chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:12:00 +08:00
commit 3de48288cb
2986 changed files with 1131193 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
# Security alert triage
How Dependabot and CodeQL (code-scanning) alerts are managed for this repo.
## Pipeline
| Layer | Mechanism | What it does |
|---|---|---|
| Detection — deps | Dependabot alerts (on) | Flags vulnerable dependencies. |
| Detection — code | CodeQL default setup (on) | Flags code-level findings. |
| Detection — secrets | Secret scanning + push protection (on) | Blocks committed secrets. |
| Detection — diff | `security-scan.yml` | Per-PR static scan (secrets/exfil/sensitive-path/workflow-misuse/semgrep/OSV). |
| **Fixing — deps** | **Dependabot security updates** + `dependabot.yml` | Auto-opens grouped fix PRs for vulnerable deps. |
| **Triage** | **`security-triage.yml`** (this) | Daily AI triage: dismiss high-confidence false positives, escalate serious findings privately. |
Dependency *fixing* is Dependabot's job; this workflow does not edit code. Code
findings are never auto-fixed — only triaged.
## How the triage cron decides
The cron (`.github/workflows/security-triage.yml`) follows the same
injection-resistant model as `issue-triage.yml`: trusted steps fetch alerts and
apply mutations; the LLM (`.github/triage/security/`) runs with **no tools, no
shell, no token** and only emits validated JSON.
Per alert the model returns one of:
- **false_positive** — pattern not exploitable here (must name why).
- **wont_fix** — real but negligible (test-only fixture / dev-only tooling).
- **serious** — real and exploitable in production / on untrusted input.
- **monitor** — uncertain; left for a human.
Mutations are tightly gated:
- **Auto-dismiss** happens only at **confidence ≥ 0.9**, and is allow-listed
on each side:
- **CodeQL** — only for an allow-listed set of rule ids (see
`AUTO_DISMISS_RULES` in the workflow). `py/path-injection` and
`actions/untrusted-checkout` are **not** auto-dismissable.
- **Dependabot** — only **low/medium** severity advisories. A **high or
critical** dependency advisory is never auto-dismissed on the model's word
alone; it always waits for a human.
- **serious** findings are collected into a **private** GitHub Security
Advisory draft. They are never posted to public issues.
- **Mutations are OFF by default.** APPLY mode requires either the repo
variable `SECURITY_TRIAGE_APPLY == 'true'` (enables scheduled enforcement) or
a manual dispatch with `dry_run` unchecked. Merging the workflow alone never
triggers a live run — review a few dry-run summaries first.
## Tokens
- CodeQL dismissals use the job `GITHUB_TOKEN` (`security-events: write`).
- Dependabot dismissals and advisory creation need a repo/org secret
**`SECURITY_TRIAGE_TOKEN`** (fine-grained PAT with *Dependabot alerts:
write* + *Security advisories: write*) — `GITHUB_TOKEN` cannot do either.
Without it the cron still classifies and reports; it just can't mutate
Dependabot alerts or open advisories.
## Verified false positives (current backlog)
These were checked by reading the code during the initial audit and are safe to
dismiss as false positives:
- `py/clear-text-logging-sensitive-data` @ `omnigent/inner/claude_sdk_executor.py`
— the `logger.info` logs `model / gateway / base_url / tool-count`, no secret.
- `py/weak-sensitive-data-hashing` @ `omnigent/model_catalog.py:225` — SHA256 is
used to build a non-secret 16-char **cache fingerprint**, not to store a
password. The secret is deliberately never persisted.
Accepted-risk (review, then dismiss with justification — not silently):
- `actions/untrusted-checkout` (critical) @ `oss-regen-on-comment.yml` — the
`issue_comment` workflow checks out PR head, but with `persist-credentials:
false`, no token on disk during `uv lock`, an App token minted only after the
lock and used only at the push step, behind an `authorize` gate. Untrusted
code runs without secrets in scope.
Needs per-case review (do **not** bulk-dismiss): the 52 `py/path-injection`
findings in `spec/parser.py`, `tools/builtins/upload_file.py`, `spec/tar_utils.py`,
etc. — most are trusted-input, but the extraction paths deserve a look.
Serious (fix, don't dismiss): `starlette` and `cryptography` advisories (server
runtime); the `undici` cluster in `web`.
+63
View File
@@ -0,0 +1,63 @@
# Custom semgrep rules for the contributor Security Scan (pass 1).
# Run LOCALLY (semgrep --config this-file) so the scan needs no network to the
# semgrep registry. These target code-execution / exfiltration shapes that an
# untrusted PR might smuggle in; registry packs (p/ci, p/secrets) can be added
# later as an additive, network-permitting step.
rules:
- id: exec-on-decoded-payload
languages: [python]
severity: ERROR
message: >
Executing a decoded/deobfuscated payload (base64/hex/zlib -> eval/exec).
This is the canonical way to hide a backdoor from review.
patterns:
- pattern-either:
- pattern: eval(...)
- pattern: exec(...)
- pattern-either:
- pattern: eval(base64.$F(...))
- pattern: exec(base64.$F(...))
- pattern: eval(bytes.fromhex(...))
- pattern: exec(bytes.fromhex(...))
- pattern: eval(codecs.decode(...))
- pattern: exec(codecs.decode(...))
- pattern: eval(zlib.decompress(...))
- pattern: exec(zlib.decompress(...))
- pattern: eval($X.decode(...))
- pattern: exec($X.decode(...))
- id: python-shell-pipe-to-interpreter
languages: [python]
severity: ERROR
message: >
A subprocess/os.system call pipes a downloaded script straight into a
shell/interpreter (curl|wget ... | sh/bash/python). Runs arbitrary
remote code.
patterns:
- pattern-either:
- pattern: os.system($CMD)
- pattern: os.popen($CMD)
- pattern: subprocess.$F($CMD, ...)
- pattern: subprocess.$F($CMD)
- metavariable-regex:
metavariable: $CMD
regex: (?i).*(curl|wget)\b.*\|\s*(sudo\s+)?(sh|bash|zsh|python[0-9.]*|node|ruby|perl)\b.*
- id: shell-pipe-to-interpreter
languages: [bash]
severity: ERROR
message: >
Piping a downloaded script straight into a shell/interpreter. Runs
arbitrary remote code in CI.
patterns:
- pattern-regex: (?i)(curl|wget)\b[^\n|]*\|\s*(sudo\s+)?(sh|bash|zsh|python[0-9.]*|node|ruby|perl)\b
- id: dynamic-import-from-network
languages: [python]
severity: WARNING
message: >
Dynamic import / module loading at runtime. Verify the source is trusted
and not attacker-controlled.
pattern-either:
- pattern: importlib.import_module($X)
- pattern: __import__($X)