| Titel | yoanbernabeu grepai 0.35.0 Improper Isolation |
|---|
| Beschreibung | ## Vulnerability Title
Cross-project Qdrant vector index overwrite via non-namespaced chunk IDs
## Affected Component
`indexer/chunker.go` and `store/qdrant.go`
Repository: https://github.com/yoanbernabeu/grepai
## Summary
When multiple grepai projects are configured to use the same Qdrant collection, chunks from different projects can overwrite each other if they have the same relative file path and chunk index.
The chunker generates chunk IDs from only `filePath` and `chunkIndex` (e.g., `README.md_0`). The Qdrant backend derives the point UUID from this chunk ID and writes points with Qdrant upsert semantics. As a result, a second project containing a file with the same name (like `README.md`) can overwrite the first project's chunk in the shared collection. This is a security-relevant index integrity issue when a shared Qdrant collection is used for projects that are not mutually trusted, causing cross-project vector index poisoning and incorrect search/readback results.
## Technical Details
Both projects generate the same application-level chunk ID:
`README.md_0`
Qdrant derives the same point UUID from this ID and upserts the point. The second project's chunk overwrites the first project's chunk payload and vector in the shared collection.
Relevant code in `indexer/chunker.go`:
```go
hash := sha256.Sum256([]byte(fmt.Sprintf("%s:%d:%d:%s", filePath, pos, end, chunkContent)))
contentHash := sha256.Sum256([]byte(chunkContent))
chunkID := fmt.Sprintf("%s_%d", filePath, chunkIndex)
```
Relevant code in `store/qdrant.go`:
```go
func (s *QdrantStore) getUUIDForChunk(chunkID string) uuid.UUID {
namespace := uuid.MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
return uuid.NewSHA1(namespace, []byte(chunkID))
}
pointID := s.getUUIDForChunk(chunk.ID)
_, err := s.client.Upsert(ctx, &qdrant.UpsertPoints{
CollectionName: s.collectionName,
Points: points,
})
```
## Steps to Reproduce
1. Configure two separate grepai projects to use the same Qdrant collection.
2. In project A, create `README.md` with content: `Victim private deployment runbook`
3. Index project A.
4. In project B, create `README.md` with content: `Attacker decoy repository content`
5. Index project B into the same Qdrant collection.
6. Read back `README.md` from project A's Qdrant-backed store.
Observed output (E2E verification):
```text
victim_before id="" hash="ab19d91389bc19e2" content="File: README.md\n\nVictim private deployment runbook"
victim_after id="" hash="5c57e074d9e5a7aa" content="File: README.md\n\nAttacker decoy repository content"
attacker_view id="" hash="5c57e074d9e5a7aa" content="File: README.md\n\nAttacker decoy repository content"
```
## Expected Behavior
Chunks from different projects should not overwrite each other in a shared vector store. Chunk identity in Qdrant should include a project, repository, workspace, or collection namespace that makes object identity unique across trust domains.
## Impact
This vulnerability allows attackers to overwrite and poison the vector index of other projects sharing the same Qdrant collection. It leads to data integrity loss and potential exposure of decoy/malicious content to victim projects during retrieval-augmented generation (RAG) or search operations.
## Configuration Prerequisites
Minimal affected configuration shape requires multiple projects sharing a collection:
```yaml
store:
backend: qdrant
qdrant:
endpoint: http://localhost
port: 6334
collection: shared_collection_name
```
*(Note: Normal single-project default collection naming uses a sanitized project root when `collection` is empty, which reduces exposure unless multiple projects explicitly share a configuration).* |
|---|
| Quelle | ⚠️ https://github.com/yoanbernabeu/grepai/issues/247 |
|---|
| Benutzer | Dem000 (UID 98389) |
|---|
| Einreichung | 20.05.2026 09:54 (vor 19 Tagen) |
|---|
| Moderieren | 07.06.2026 11:45 (18 days later) |
|---|
| Status | Akzeptiert |
|---|
| VulDB Eintrag | 369099 [yoanbernabeu grepai 0.35.0 Qdrant Backend indexer/chunker.go schwache Verschlüsselung] |
|---|
| Punkte | 20 |
|---|