Skip to content

[Security][Medium] Unauthenticated annotation writes persist unlimited attacker-shaped files into the git-tracked .graphcoder store #9

Description

@docxology

Title: [Security][Medium] Unauthenticated annotation writes persist unlimited attacker-shaped files into the git-tracked .graphcoder store

Severity: Medium (CWE-400, CWE-20)
Locations: packages/server/src/routes/annotations.ts:186-207, 387-394; packages/core/src/annotations/store.ts:69-74

Summary

.graphcoder/annotations/ is git-tracked by design. POST /api/annotations writes one JSON file per call — unauthenticated, no rate limit, no quota. Only kind is length-capped (64); label/description/reasoning/members are unbounded free text. POST /api/git/pr-stack/import additionally persists commit-message-derived labels/descriptions from ANY repo the user diffs into committed files.

Evidence

routes/annotations.ts:186-207:

const annotation = createAnnotation(shape, label, members, opts)
saveAnnotation(root, annotation)

schemas (annotations.ts): label: z.string().min(1) — no max; members: z.array(z.string()).default([]) — no count cap.

Impact

An attacker page (via CORS) or a diff-view click on a malicious repo can: fill the user's disk with files; forge agent-authored review-comment content that the client renders; pre-register poisoned kind names that get committed.

Recommended fix

Add field-length/member-count caps to the schemas, rate-limit writes, and require explicit confirmation before persisting agent/imported annotations into the git-tracked store.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions