Skip to content

Commit 343afb2

Browse files
authored
docs: add SECURITY.md (#26)
* docs: add SECURITY.md pointing at private vulnerability reporting gh-attach handles GitHub authentication cookies on the local machine and uploads file contents under the signed-in user's identity via the Git Data API. A bug in the wrong place could expose credentials or let an attacker write content under someone else's auth, so the project needs a documented private reporting path before that becomes a problem. Private Vulnerability Reporting is already enabled on the repository (confirmed via `gh api /repos/.../private-vulnerability-reporting` returning `enabled: true`), so the policy points reporters at `/security/advisories/new` as the primary channel. No separate email backup — GitHub's private advisory workflow is the single canonical path and avoids the "email bitrot" problem of stale inbox addresses in security policies. ## Contents - **Supported versions**: latest tagged release only. Pragmatic for a pre-1.0 project with frequent releases; contributors are expected to `gh extension upgrade` before filing a report. - **Reporting flow**: explicit "no public issues" warning, link to the private advisory form, and a checklist of useful info to include (version, platform, repro, affected code paths, proposed fix, credit preference). - **Response expectations**: realistic small-team numbers — 5 days to acknowledge, 10 days to triage, severity-dependent fix window, 30–90 day coordinated-disclosure window. - **Scope**: explicit list of in-scope areas that map to real attack surface in this codebase: - cookie extraction + jar handling - the 3-step upload token chain - file-handling paths (--name validation, stdin temp files, filepath.Base assumptions, symlink handling, path traversal in both upload and get) - ref handling (gh.ValidateKey, get's tree walking) - git remote URL parsing (potential for argument injection in the downstream gh CLI calls) - output rendering (markdown injection, JSON contract) - **Out of scope**: upstream `gh`, `kooky`, Go stdlib, GitHub itself, and intended-behavior uploads by authenticated users. Pointed at upstream repos for the report. - **Disclosure**: coordinated disclosure with reporter credit by default (anonymity on request). Intentionally narrow — this is a ~1500-LOC CLI, not an enterprise framework, and a 100-line policy is plenty. No CVE numbering, no bug bounty, no PGP key — those add process without adding safety for a project this size. * docs: fix SECURITY.md to describe gh-attach's actual auth + upload flow Address PR #26 review: the original SECURITY.md listed an attack surface that doesn't exist in this project. I conflated gh-attach with the other gh-image project (drogers0/gh-image), which DOES use kooky for browser cookie extraction and the 3-step uploadToken/asset_upload_authenticity_token/S3 browser protocol. gh-attach's actual mechanism is different: 1. `gh auth token` (via execCommand) → OAuth token from the gh CLI 2. JSON POST to api.github.com/.../git/blobs|trees|commits|refs with `Authorization: token <OAUTH>` header 3. No browser cookies, no kooky dependency, no S3 presigned POST, no asset_upload_authenticity_token chain Verified against the actual source before rewriting: - ghAuthToken exec path: internal/gh/resolver.go:65-66 uses execCommand("gh", "auth", "token") - Authorization header: 8 call sites across gitdata.go and comment.go, all using "token <OAUTH>" - 4-step upload (blob → tree → commit → ref): gitdata.go:171,195,212,222/230 - 4-step download (ref → commit → tree → blob): gitdata.go:532,546,562 with docstring at 496-499 - go.mod has zero external dependencies — no kooky, no cookie handling code exists at all ## Corrections - Intro paragraph: "handles GitHub authentication cookies on the local machine" → describes the gh auth token exec path instead. - Scope / Authentication handling: rewritten to cover the real attack surface (token resolution, Authorization header handling, token leakage into logs/errors/JSON output). - Scope / new "gh CLI delegation" bullet: enumerates the three actual execCommand call sites and flags `gh pr view --repo <repo>` as the only one where user-influenced input reaches argv. - Scope / new "Git Data API flow" bullet: describes the real 4-step upload sequence and the matching 4-step download sequence in GetAttachments, plus DeleteRef and ListRefs. - Scope / File handling: added specific mentions of expandFiles symlink handling and the get pre-flight conflict check. - Scope / Ref handling: made "commit/tree walking" explicitly belong to `gh attach get`. - Scope / Output rendering: pointed at FormatSection and EmbedURL by name instead of describing them abstractly. - Out of scope: removed the kooky line entirely (not a dependency); added a clarifying note on gh CLI token storage so reporters know local-storage bugs belong in cli/cli, not here. No other sections touched.
1 parent 7b45fec commit 343afb2

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

SECURITY.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Security Policy
2+
3+
`gh-attach` reads the signed-in user's OAuth token from the [`gh` CLI](https://cli.github.com/)
4+
(via `gh auth token`) and uses it to push file contents under that user's
5+
identity via GitHub's Git Data API. A security bug in this tool could leak
6+
the token, let an attacker write content under someone else's identity, or
7+
escape out of the intended filesystem boundaries on upload or download, so
8+
please report issues privately so they can be fixed before public disclosure.
9+
10+
## Supported versions
11+
12+
Only the **latest tagged release** receives security fixes. The project is
13+
pre-1.0 and releases often — please upgrade before reporting:
14+
15+
```bash
16+
gh extension upgrade gh-attach
17+
```
18+
19+
If you can only reproduce the issue on an older version, mention that in the
20+
report, but the fix will ship on the latest release line.
21+
22+
## Reporting a vulnerability
23+
24+
**Do not open a public issue for security problems.** Public issues are
25+
indexable and broadcast the vulnerability before a fix is available.
26+
27+
Use GitHub's Private Vulnerability Reporting:
28+
29+
👉 **[Report a vulnerability](https://github.com/enthus-appdev/gh-attach/security/advisories/new)**
30+
31+
Private Vulnerability Reporting is enabled on this repository. The report is
32+
visible only to you and the maintainers; GitHub handles the advisory workflow
33+
and credit tracking. Please include as much of the following as you can:
34+
35+
- A description of the issue and its impact
36+
- Reproduction steps, including the installed version (`gh extension list`
37+
shows the gh-attach version) and your platform
38+
- Any proof-of-concept code, scripts, or sample output
39+
- Affected code paths or commits, if you've found them
40+
- A proposed fix if you have one
41+
- Your GitHub handle if you'd like public credit after the fix ships
42+
43+
## Response expectations
44+
45+
This is a small-team open-source project. Realistic targets:
46+
47+
| Event | Timeline |
48+
|---|---|
49+
| Initial acknowledgment | within **5 business days** of your report |
50+
| Triage and severity assessment | within **10 business days** |
51+
| Fix development | depends on severity and complexity |
52+
| Coordinated disclosure | typically **30–90 days** after a fix ships, sooner if actively exploited |
53+
54+
If you have not heard back within the acknowledgment window, please nudge via
55+
the security advisory thread.
56+
57+
## Scope
58+
59+
### In scope
60+
61+
Anything in the `gh-attach` binary or its upload/download flow. High-value
62+
areas to probe:
63+
64+
- **Authentication handling** — the `gh auth token` exec path in
65+
`internal/gh/resolver.go` that resolves the user's OAuth token, how that
66+
token is passed to the HTTP client (`Authorization: token ...` on every
67+
request in `internal/gh/gitdata.go` and `internal/gh/comment.go`), and
68+
whether the token can leak into error messages, log output, or the
69+
`--json` result on stderr/stdout.
70+
- **`gh` CLI delegation** — the three subprocess call sites that
71+
`gh-attach` goes through (all in `internal/gh/resolver.go`):
72+
`git remote get-url origin` (static args), `gh auth token` (static
73+
args), and `gh pr view --json number --repo <repo>` where `<repo>`
74+
is the string passed to `--repo` or parsed from the git remote. The
75+
third one is the only path where user-influenced input reaches argv,
76+
so it's the candidate worth probing for argument-injection edge
77+
cases.
78+
- **Git Data API flow** — the 4-step upload sequence (blob → tree →
79+
commit → ref create or fast-forward) in `internal/gh/gitdata.go`, the
80+
matching 4-step download sequence (ref → commit → tree → blob) in
81+
`GetAttachments`, and the ref create/delete endpoints in
82+
`DeleteRef`/`ListRefs`.
83+
- **File handling**`--name` basename validation, stdin materialization
84+
to temp files, path traversal in both the upload and `get` paths,
85+
`filepath.Base` assumptions on arbitrary input, symlink handling in
86+
`expandFiles`, and the pre-flight conflict check + force-overwrite
87+
behavior of `gh attach get`.
88+
- **Ref handling**`refs/uploads/*` namespace construction, ref name
89+
validation (`gh.ValidateKey`), and the commit/tree walking performed by
90+
`gh attach get`.
91+
- **Git remote parsing** — the SSH and HTTPS URL parsers in
92+
`internal/gh/repo.go`, including any input that could lead to command
93+
or argument injection in the `gh` CLI calls that follow, or to
94+
targeting the wrong repository.
95+
- **Output rendering** — markdown injection via filename fields in
96+
`FormatSection`, URL encoding in embed URLs (`EmbedURL`), and the
97+
`--json` output contract for `upload`/`list`/`get` results.
98+
99+
### Out of scope
100+
101+
Please report the following upstream rather than here — they are not
102+
`gh-attach` vulnerabilities:
103+
104+
- Issues in the [`gh` CLI](https://github.com/cli/cli) itself, including
105+
how it stores and retrieves OAuth tokens on the local machine
106+
- Issues in the Go standard library, toolchain, or `net/http` defaults
107+
- Issues in GitHub's own API, storage infrastructure, or rate limits
108+
- An authenticated user uploading content to their own repositories —
109+
that is the intended behavior of the tool
110+
111+
## Disclosure policy
112+
113+
We practice coordinated disclosure:
114+
115+
1. You report the vulnerability privately via the link above.
116+
2. We acknowledge, triage, and develop a fix.
117+
3. We release a patched version on a new tag.
118+
4. After a mutually agreed delay, we publish the security advisory, credit
119+
the reporter (unless anonymity is requested), and link to the fix commit
120+
and release.
121+
122+
Reporters are credited in the advisory and in the release notes for the fix
123+
unless they prefer to remain anonymous.

0 commit comments

Comments
 (0)