@sentry/warden 0.22.0 → 0.24.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.
- package/.oxlintrc.json +169 -0
- package/CHANGELOG.md +427 -0
- package/README.md +4 -1
- package/dist/cli/args.d.ts +6 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +175 -207
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +16 -5
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/build.d.ts +13 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +384 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +13 -5
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/runs.d.ts.map +1 -1
- package/dist/cli/commands/runs.js +12 -6
- package/dist/cli/commands/runs.js.map +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/sync.js +4 -1
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js +8 -1
- package/dist/cli/context.js.map +1 -1
- package/dist/cli/files.d.ts.map +1 -1
- package/dist/cli/files.js +27 -9
- package/dist/cli/files.js.map +1 -1
- package/dist/cli/help.d.ts +4 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +448 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/index.js +2 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/input.d.ts +12 -0
- package/dist/cli/input.d.ts.map +1 -1
- package/dist/cli/input.js +60 -0
- package/dist/cli/input.js.map +1 -1
- package/dist/cli/main.d.ts +41 -2
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +294 -75
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output/box.js +1 -1
- package/dist/cli/output/formatters.d.ts +10 -2
- package/dist/cli/output/formatters.d.ts.map +1 -1
- package/dist/cli/output/formatters.js +32 -9
- package/dist/cli/output/formatters.js.map +1 -1
- package/dist/cli/output/index.d.ts +1 -1
- package/dist/cli/output/index.d.ts.map +1 -1
- package/dist/cli/output/index.js +1 -1
- package/dist/cli/output/index.js.map +1 -1
- package/dist/cli/output/ink-runner.d.ts +3 -1
- package/dist/cli/output/ink-runner.d.ts.map +1 -1
- package/dist/cli/output/ink-runner.js +64 -28
- package/dist/cli/output/ink-runner.js.map +1 -1
- package/dist/cli/output/jsonl.d.ts +37 -0
- package/dist/cli/output/jsonl.d.ts.map +1 -1
- package/dist/cli/output/jsonl.js +6 -0
- package/dist/cli/output/jsonl.js.map +1 -1
- package/dist/cli/output/live-status.d.ts +48 -0
- package/dist/cli/output/live-status.d.ts.map +1 -0
- package/dist/cli/output/live-status.js +173 -0
- package/dist/cli/output/live-status.js.map +1 -0
- package/dist/cli/output/reporter.d.ts +4 -0
- package/dist/cli/output/reporter.d.ts.map +1 -1
- package/dist/cli/output/reporter.js +20 -3
- package/dist/cli/output/reporter.js.map +1 -1
- package/dist/cli/output/tasks.d.ts +8 -5
- package/dist/cli/output/tasks.d.ts.map +1 -1
- package/dist/cli/output/tasks.js +113 -71
- package/dist/cli/output/tasks.js.map +1 -1
- package/dist/cli/signals.d.ts +15 -0
- package/dist/cli/signals.d.ts.map +1 -0
- package/dist/cli/signals.js +26 -0
- package/dist/cli/signals.js.map +1 -0
- package/dist/config/loader.d.ts +48 -7
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +228 -32
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +55 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +34 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/diff/context.d.ts +9 -2
- package/dist/diff/context.d.ts.map +1 -1
- package/dist/diff/context.js +65 -17
- package/dist/diff/context.js.map +1 -1
- package/dist/evals/runner.d.ts.map +1 -1
- package/dist/evals/runner.js +16 -0
- package/dist/evals/runner.js.map +1 -1
- package/dist/event/context.d.ts.map +1 -1
- package/dist/event/context.js +1 -0
- package/dist/event/context.js.map +1 -1
- package/dist/event/schedule-context.d.ts.map +1 -1
- package/dist/event/schedule-context.js +1 -0
- package/dist/event/schedule-context.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/output/dedup.d.ts +8 -11
- package/dist/output/dedup.d.ts.map +1 -1
- package/dist/output/dedup.js +39 -37
- package/dist/output/dedup.js.map +1 -1
- package/dist/output/github-checks.d.ts +1 -0
- package/dist/output/github-checks.d.ts.map +1 -1
- package/dist/output/github-checks.js +9 -7
- package/dist/output/github-checks.js.map +1 -1
- package/dist/sdk/analyze.d.ts.map +1 -1
- package/dist/sdk/analyze.js +147 -277
- package/dist/sdk/analyze.js.map +1 -1
- package/dist/sdk/circuit-breaker.d.ts +26 -0
- package/dist/sdk/circuit-breaker.d.ts.map +1 -0
- package/dist/sdk/circuit-breaker.js +53 -0
- package/dist/sdk/circuit-breaker.js.map +1 -0
- package/dist/sdk/errors.d.ts +5 -0
- package/dist/sdk/errors.d.ts.map +1 -1
- package/dist/sdk/errors.js +27 -0
- package/dist/sdk/errors.js.map +1 -1
- package/dist/sdk/extract.d.ts +18 -9
- package/dist/sdk/extract.d.ts.map +1 -1
- package/dist/sdk/extract.js +95 -87
- package/dist/sdk/extract.js.map +1 -1
- package/dist/sdk/fix-quality.d.ts +5 -0
- package/dist/sdk/fix-quality.d.ts.map +1 -1
- package/dist/sdk/fix-quality.js +42 -23
- package/dist/sdk/fix-quality.js.map +1 -1
- package/dist/sdk/haiku.d.ts +6 -0
- package/dist/sdk/haiku.d.ts.map +1 -1
- package/dist/sdk/haiku.js +75 -49
- package/dist/sdk/haiku.js.map +1 -1
- package/dist/sdk/json-output.d.ts +31 -0
- package/dist/sdk/json-output.d.ts.map +1 -0
- package/dist/sdk/json-output.js +98 -0
- package/dist/sdk/json-output.js.map +1 -0
- package/dist/sdk/model-pricing.json +56 -16
- package/dist/sdk/post-process.d.ts +29 -0
- package/dist/sdk/post-process.d.ts.map +1 -0
- package/dist/sdk/post-process.js +65 -0
- package/dist/sdk/post-process.js.map +1 -0
- package/dist/sdk/prepare.d.ts.map +1 -1
- package/dist/sdk/prepare.js +4 -1
- package/dist/sdk/prepare.js.map +1 -1
- package/dist/sdk/pricing.d.ts +18 -0
- package/dist/sdk/pricing.d.ts.map +1 -1
- package/dist/sdk/pricing.js +108 -3
- package/dist/sdk/pricing.js.map +1 -1
- package/dist/sdk/prompt-sections.d.ts +56 -0
- package/dist/sdk/prompt-sections.d.ts.map +1 -0
- package/dist/sdk/prompt-sections.js +118 -0
- package/dist/sdk/prompt-sections.js.map +1 -0
- package/dist/sdk/prompt.d.ts +2 -17
- package/dist/sdk/prompt.d.ts.map +1 -1
- package/dist/sdk/prompt.js +15 -37
- package/dist/sdk/prompt.js.map +1 -1
- package/dist/sdk/report-files.d.ts +15 -0
- package/dist/sdk/report-files.d.ts.map +1 -0
- package/dist/sdk/report-files.js +20 -0
- package/dist/sdk/report-files.js.map +1 -0
- package/dist/sdk/runner.d.ts +9 -1
- package/dist/sdk/runner.d.ts.map +1 -1
- package/dist/sdk/runner.js +6 -0
- package/dist/sdk/runner.js.map +1 -1
- package/dist/sdk/runtimes/claude.d.ts +3 -0
- package/dist/sdk/runtimes/claude.d.ts.map +1 -0
- package/dist/sdk/runtimes/claude.js +376 -0
- package/dist/sdk/runtimes/claude.js.map +1 -0
- package/dist/sdk/runtimes/index.d.ts +12 -0
- package/dist/sdk/runtimes/index.d.ts.map +1 -0
- package/dist/sdk/runtimes/index.js +22 -0
- package/dist/sdk/runtimes/index.js.map +1 -0
- package/dist/sdk/runtimes/types.d.ts +116 -0
- package/dist/sdk/runtimes/types.d.ts.map +1 -0
- package/dist/sdk/runtimes/types.js +17 -0
- package/dist/sdk/runtimes/types.js.map +1 -0
- package/dist/sdk/types.d.ts +23 -2
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/sdk/types.js.map +1 -1
- package/dist/sdk/usage.d.ts +21 -6
- package/dist/sdk/usage.d.ts.map +1 -1
- package/dist/sdk/usage.js +36 -23
- package/dist/sdk/usage.js.map +1 -1
- package/dist/sdk/verify.d.ts +25 -0
- package/dist/sdk/verify.d.ts.map +1 -0
- package/dist/sdk/verify.js +226 -0
- package/dist/sdk/verify.js.map +1 -0
- package/dist/skill-builder/agentic.d.ts +33 -0
- package/dist/skill-builder/agentic.d.ts.map +1 -0
- package/dist/skill-builder/agentic.js +240 -0
- package/dist/skill-builder/agentic.js.map +1 -0
- package/dist/skill-builder/authoring-provider.d.ts +5 -0
- package/dist/skill-builder/authoring-provider.d.ts.map +1 -0
- package/dist/skill-builder/authoring-provider.js +70 -0
- package/dist/skill-builder/authoring-provider.js.map +1 -0
- package/dist/skill-builder/definition.d.ts +46 -0
- package/dist/skill-builder/definition.d.ts.map +1 -0
- package/dist/skill-builder/definition.js +171 -0
- package/dist/skill-builder/definition.js.map +1 -0
- package/dist/skill-builder/outline-contract.d.ts +113 -0
- package/dist/skill-builder/outline-contract.d.ts.map +1 -0
- package/dist/skill-builder/outline-contract.js +73 -0
- package/dist/skill-builder/outline-contract.js.map +1 -0
- package/dist/skill-builder/outline-state.d.ts +158 -0
- package/dist/skill-builder/outline-state.d.ts.map +1 -0
- package/dist/skill-builder/outline-state.js +87 -0
- package/dist/skill-builder/outline-state.js.map +1 -0
- package/dist/skill-builder/outline.d.ts +36 -0
- package/dist/skill-builder/outline.d.ts.map +1 -0
- package/dist/skill-builder/outline.js +345 -0
- package/dist/skill-builder/outline.js.map +1 -0
- package/dist/skill-builder/skill-contract.d.ts +97 -0
- package/dist/skill-builder/skill-contract.d.ts.map +1 -0
- package/dist/skill-builder/skill-contract.js +58 -0
- package/dist/skill-builder/skill-contract.js.map +1 -0
- package/dist/skill-builder/skill-prompts.d.ts +61 -0
- package/dist/skill-builder/skill-prompts.d.ts.map +1 -0
- package/dist/skill-builder/skill-prompts.js +285 -0
- package/dist/skill-builder/skill-prompts.js.map +1 -0
- package/dist/skill-builder/skill.d.ts +23 -0
- package/dist/skill-builder/skill.d.ts.map +1 -0
- package/dist/skill-builder/skill.js +563 -0
- package/dist/skill-builder/skill.js.map +1 -0
- package/dist/skills/index.d.ts +2 -2
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +20 -6
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +88 -141
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/remote.d.ts +11 -7
- package/dist/skills/remote.d.ts.map +1 -1
- package/dist/skills/remote.js +62 -162
- package/dist/skills/remote.js.map +1 -1
- package/dist/triggers/matcher.d.ts.map +1 -1
- package/dist/triggers/matcher.js +28 -15
- package/dist/triggers/matcher.js.map +1 -1
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/path.d.ts +17 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +36 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +8 -8
- package/policies/README.md +22 -0
- package/policies/code-comments.md +20 -0
- package/policies/policy-template.md +14 -0
- package/skills/warden/SPEC.md +112 -0
- package/skills/warden/references/cli-reference.md +2 -2
- package/skills/warden/references/config-schema.md +29 -13
- package/skills/warden/references/configuration.md +20 -8
- package/skills/warden/references/creating-skills.md +3 -0
- package/skills/warden-sweep/SPEC.md +126 -0
- package/src/builtin-skills/security-review/SKILL.md +81 -0
- package/src/builtin-skills/security-review/SPEC.md +77 -0
- package/src/builtin-skills/security-review/references/github-workflows.md +186 -0
- package/src/builtin-skills/security-review/references/javascript-typescript.md +69 -0
- package/src/builtin-skills/security-review/references/python.md +70 -0
- package/src/internal-skills/skill-writer/EVAL.md +124 -0
- package/src/internal-skills/skill-writer/SKILL.md +159 -0
- package/src/internal-skills/skill-writer/SOURCES.md +94 -0
- package/src/internal-skills/skill-writer/SPEC.md +153 -0
- package/src/internal-skills/skill-writer/references/artifact-layouts/argument-driven-skill-layout.md +32 -0
- package/src/internal-skills/skill-writer/references/artifact-layouts/asset-template-skill-layout.md +30 -0
- package/src/internal-skills/skill-writer/references/artifact-layouts/inline-skill-layout.md +28 -0
- package/src/internal-skills/skill-writer/references/artifact-layouts/reference-backed-skill-layout.md +35 -0
- package/src/internal-skills/skill-writer/references/artifact-layouts/script-backed-skill-layout.md +31 -0
- package/src/internal-skills/skill-writer/references/authoring-path.md +91 -0
- package/src/internal-skills/skill-writer/references/claude-code/argument-substitutions.md +20 -0
- package/src/internal-skills/skill-writer/references/claude-code/dynamic-context.md +16 -0
- package/src/internal-skills/skill-writer/references/claude-code/frontmatter-and-invocation.md +33 -0
- package/src/internal-skills/skill-writer/references/claude-code/hook-backed-skills.md +28 -0
- package/src/internal-skills/skill-writer/references/claude-code/subagent-fork-skills.md +22 -0
- package/src/internal-skills/skill-writer/references/description-optimization.md +28 -0
- package/src/internal-skills/skill-writer/references/design-principles.md +74 -0
- package/src/internal-skills/skill-writer/references/evaluation-path.md +73 -0
- package/src/internal-skills/skill-writer/references/examples/documentation-skill.md +70 -0
- package/src/internal-skills/skill-writer/references/examples/evaluator-loop-skill.md +38 -0
- package/src/internal-skills/skill-writer/references/examples/hook-backed-skill.md +39 -0
- package/src/internal-skills/skill-writer/references/examples/router-skill.md +41 -0
- package/src/internal-skills/skill-writer/references/examples/security-review-skill.md +69 -0
- package/src/internal-skills/skill-writer/references/examples/subagent-fork-skill.md +39 -0
- package/src/internal-skills/skill-writer/references/examples/workflow-process-skill.md +65 -0
- package/src/internal-skills/skill-writer/references/execution-shapes.md +68 -0
- package/src/internal-skills/skill-writer/references/iteration-evidence.md +82 -0
- package/src/internal-skills/skill-writer/references/iteration-path.md +40 -0
- package/src/internal-skills/skill-writer/references/mode-selection.md +67 -0
- package/src/internal-skills/skill-writer/references/output-contracts.md +68 -0
- package/src/internal-skills/skill-writer/references/reference-architecture.md +71 -0
- package/src/internal-skills/skill-writer/references/registration-validation.md +67 -0
- package/src/internal-skills/skill-writer/references/source-discovery.md +60 -0
- package/src/internal-skills/skill-writer/references/spec-template.md +118 -0
- package/src/internal-skills/skill-writer/references/structure-troubleshooting.md +111 -0
- package/src/internal-skills/skill-writer/references/synthesis-path.md +119 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/evaluator-loops.md +25 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/orchestrator-workers.md +25 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/parallel-workflows.md +21 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/plan-validate-execute.md +26 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/prompt-chaining.md +24 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/routing-workflows.md +28 -0
- package/src/internal-skills/skill-writer/references/workflow-mechanics/validation-loops.md +26 -0
- package/src/internal-skills/skill-writer/scripts/quick_validate.py +158 -0
- package/src/internal-skills/skill-writer/scripts/quick_validate_test.py +79 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Warden Sweep Skill Specification
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
The `warden-sweep` skill runs a full-repository Warden scan, verifies findings through deeper code tracing, and creates draft PRs for validated issues.
|
|
6
|
+
|
|
7
|
+
It exists for batch remediation work where a normal targeted Warden run is too narrow. The workflow is intentionally conservative: scan broadly, verify before patching, deduplicate against existing PRs, and record every decision in sweep artifacts.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
In scope:
|
|
12
|
+
|
|
13
|
+
- Scanning a repository file-by-file with Warden.
|
|
14
|
+
- Extracting and normalizing Warden findings.
|
|
15
|
+
- Verifying findings before any code changes are attempted.
|
|
16
|
+
- Creating a tracking issue for the sweep.
|
|
17
|
+
- Creating one draft PR per validated issue that passes patch triage.
|
|
18
|
+
- Organizing reports, security findings, PR links, and resumable sweep state.
|
|
19
|
+
|
|
20
|
+
Out of scope:
|
|
21
|
+
|
|
22
|
+
- Replacing human review of generated PRs.
|
|
23
|
+
- Applying fixes directly to the user's current branch.
|
|
24
|
+
- Patching low-confidence or unverified findings.
|
|
25
|
+
- Running generic codebase review without Warden scan artifacts.
|
|
26
|
+
- Managing CI iteration after PR creation.
|
|
27
|
+
|
|
28
|
+
## Users And Trigger Context
|
|
29
|
+
|
|
30
|
+
- Primary users: maintainers asking an agent to perform broad Warden-backed repository cleanup.
|
|
31
|
+
- Common user requests: "sweep the repo", "scan everything", "find all bugs", "full codebase review", "batch code analysis", "run Warden across the whole repository".
|
|
32
|
+
- Should not trigger for: normal pre-commit Warden runs, single-file checks, generic code review, or PR feedback iteration.
|
|
33
|
+
|
|
34
|
+
## Runtime Contract
|
|
35
|
+
|
|
36
|
+
- Required first actions:
|
|
37
|
+
- Confirm the repository has the required tools: `warden`, `gh`, `git`, `jq`, and `uv`.
|
|
38
|
+
- Run `scripts/scan.py` from the repository root using the host skill-root path.
|
|
39
|
+
- Preserve the returned `runId` and `sweepDir`.
|
|
40
|
+
- Resume existing sweep artifacts instead of duplicating work when a sweep directory is provided.
|
|
41
|
+
- Required outputs:
|
|
42
|
+
- Phase summaries after scan, verification, issue creation, patching, and organization.
|
|
43
|
+
- Final pointer to the generated summary report.
|
|
44
|
+
- Explicit counts for scanned files, timeouts/errors, verified/rejected findings, created/existing/failed PRs, and security findings.
|
|
45
|
+
- Non-negotiable constraints:
|
|
46
|
+
- Verify findings before patching.
|
|
47
|
+
- Patch findings sequentially to avoid worktree and branch cross-contamination.
|
|
48
|
+
- Create draft PRs, not direct commits to the default branch.
|
|
49
|
+
- Record errors in sweep data and continue to the next finding when possible.
|
|
50
|
+
- Clean up worktrees after patch attempts.
|
|
51
|
+
- Expected bundled files loaded at runtime:
|
|
52
|
+
- `references/script-interfaces.md`
|
|
53
|
+
- `references/scan-phase.md`
|
|
54
|
+
- `references/verify-phase.md`
|
|
55
|
+
- `references/issue-phase.md`
|
|
56
|
+
- `references/patch-phase.md`
|
|
57
|
+
- `references/organize-phase.md`
|
|
58
|
+
- `references/resume-and-artifacts.md`
|
|
59
|
+
- `references/verify-prompt.md`
|
|
60
|
+
- `references/patch-prompt.md`
|
|
61
|
+
- `scripts/*.py`
|
|
62
|
+
|
|
63
|
+
## Source And Evidence Model
|
|
64
|
+
|
|
65
|
+
Authoritative sources:
|
|
66
|
+
|
|
67
|
+
- `skills/warden-sweep/SKILL.md` and bundled references.
|
|
68
|
+
- `skills/warden-sweep/scripts/*.py`.
|
|
69
|
+
- Warden JSONL output schema and renderer code in `src/cli/output/`.
|
|
70
|
+
- GitHub CLI behavior for PRs, issues, labels, and repo metadata.
|
|
71
|
+
|
|
72
|
+
Useful improvement sources:
|
|
73
|
+
|
|
74
|
+
- positive examples: completed sweeps with verified findings, clean draft PRs, and accurate final reports
|
|
75
|
+
- negative examples: duplicate PRs, false positive patches, failed worktree cleanup, incorrect artifact state, or patch contamination across findings
|
|
76
|
+
- commit logs/changelogs: changes to Warden output, script behavior, or sweep artifact schema
|
|
77
|
+
- issue or PR feedback: reviewer complaints about generated PR quality, false positives, or sweep noise
|
|
78
|
+
- eval results: dry-run prompts for scan resume, verification, patch triage, and final organization
|
|
79
|
+
|
|
80
|
+
Data that must not be stored:
|
|
81
|
+
|
|
82
|
+
- secrets, credentials, or tokens
|
|
83
|
+
- private customer data
|
|
84
|
+
- raw issue/PR content unrelated to the sweep finding
|
|
85
|
+
- unredacted sensitive code excerpts beyond what is needed in local sweep artifacts
|
|
86
|
+
|
|
87
|
+
## Reference Architecture
|
|
88
|
+
|
|
89
|
+
- `SKILL.md` contains the phase overview, routing table, universal constraints, and completion contract.
|
|
90
|
+
- `SOURCES.md` contains source inventory, coverage, decisions, gaps, and changelog.
|
|
91
|
+
- `references/` contains focused phase runbooks, prompt templates, script interfaces, and artifact layout.
|
|
92
|
+
- `references/evidence/` is unused until durable examples are needed.
|
|
93
|
+
- `scripts/` contains repeatable automation for scan, extraction, issue creation, PR indexing, reviewer selection, report generation, and organization.
|
|
94
|
+
- `assets/` is unused.
|
|
95
|
+
|
|
96
|
+
## Evaluation
|
|
97
|
+
|
|
98
|
+
- Lightweight validation:
|
|
99
|
+
- Run the skill validator against `skills/warden-sweep`.
|
|
100
|
+
- Confirm every script mentioned in `SKILL.md` and references exists.
|
|
101
|
+
- Confirm every phase reference has one clear lookup purpose.
|
|
102
|
+
- Deeper evaluation:
|
|
103
|
+
- Run a dry sweep in a small fixture repository when script or artifact behavior changes.
|
|
104
|
+
- Exercise resume paths for scan, verify, issue, patch, and organize phases.
|
|
105
|
+
- Holdout examples:
|
|
106
|
+
- Store redacted false positive and duplicate-PR examples in `references/evidence/` if these failures recur.
|
|
107
|
+
- Acceptance gates:
|
|
108
|
+
- Findings are verified before patching.
|
|
109
|
+
- Patch phase creates isolated branches and draft PRs.
|
|
110
|
+
- Existing overlapping PRs are detected before creating new PRs.
|
|
111
|
+
- Final artifacts are resumable and summarize errors separately from successful work.
|
|
112
|
+
|
|
113
|
+
## Known Limitations
|
|
114
|
+
|
|
115
|
+
- The workflow depends on external CLIs and repository permissions.
|
|
116
|
+
- Verification and patching quality depends on the host agent's ability to inspect code deeply.
|
|
117
|
+
- The skill uses host-agent delegation when available; hosts without parallel delegation can run the same verification steps serially.
|
|
118
|
+
- Broad scans can be expensive and noisy if repository Warden configuration is too broad.
|
|
119
|
+
|
|
120
|
+
## Maintenance Notes
|
|
121
|
+
|
|
122
|
+
- Update `SKILL.md` when phase order, universal constraints, or routing changes.
|
|
123
|
+
- Update `SOURCES.md` when source inventory, decisions, coverage, or known gaps change.
|
|
124
|
+
- Update phase references when script arguments, output shapes, artifact schema, or error handling changes.
|
|
125
|
+
- Update prompt templates when verification or patch quality failures recur.
|
|
126
|
+
- Update `references/evidence/` when preserving redacted examples will improve future iterations.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-review
|
|
3
|
+
description: Finds exploitable application security vulnerabilities in code changes. Use for Warden security scans, appsec review, OWASP-style checks, authentication or authorization bugs, injection, XSS, SSRF, path traversal, secrets, unsafe crypto, webhook verification, open redirects, or sensitive data exposure.
|
|
4
|
+
allowed-tools: Read Grep Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a senior application security reviewer finding real, exploitable vulnerabilities in code changes for Warden's broad default security skill.
|
|
8
|
+
Keep the review simple and high-signal: trace source, boundary, sink, mitigation, and impact before reporting.
|
|
9
|
+
|
|
10
|
+
## References
|
|
11
|
+
|
|
12
|
+
Load only matching references:
|
|
13
|
+
|
|
14
|
+
| Reference | Read When |
|
|
15
|
+
|-----------|-----------|
|
|
16
|
+
| `references/javascript-typescript.md` | Reviewing JavaScript, TypeScript, Node, React, Next.js, or browser code |
|
|
17
|
+
| `references/python.md` | Reviewing Python, Django, Flask, FastAPI, Celery, or Python service code |
|
|
18
|
+
| `references/github-workflows.md` | Reviewing GitHub Actions workflows, local actions, reusable workflows, or workflow-loaded scripts/config |
|
|
19
|
+
|
|
20
|
+
## Finding Requirements
|
|
21
|
+
|
|
22
|
+
- Report a finding only when you can show attacker-controlled input, the vulnerable sink or missing guard, the security boundary, and concrete impact.
|
|
23
|
+
- Identify attacker-controlled input: request bodies, query strings, path params, cookies, headers, uploads, webhooks, OAuth callbacks, third-party callbacks, user-written database values, and caller-controlled service inputs.
|
|
24
|
+
- Identify the security boundary: login state, session, tenant, org, team, account, project, role, webhook signature, internal network, filesystem root, cache namespace, or paid quota.
|
|
25
|
+
- Follow imports, wrappers, middleware, validators, serializers, auth helpers, route definitions, shared utilities, sibling handlers, and framework conventions before reporting.
|
|
26
|
+
- Verify mitigations in the effective path. Parameterized queries, exact allowlists, safe URL fetchers, escaping, signature checks, handler-level auth, ownership checks, realpath containment, and quota controls can close the path.
|
|
27
|
+
- Treat pattern matches as leads. A dangerous API is not a vulnerability unless untrusted data can reach it without an effective mitigation.
|
|
28
|
+
- Prefer no finding over speculative hardening advice.
|
|
29
|
+
|
|
30
|
+
## Investigation Process
|
|
31
|
+
|
|
32
|
+
1. Read the changed hunk and target file enough to understand the effective execution path.
|
|
33
|
+
2. Confirm the code is production-reachable. Return no findings for generated, vendored, test-only, fixture, example, migration, or build-output code unless it is actually shipped or invoked.
|
|
34
|
+
3. Find security entry points: routes, server actions, RPC handlers, webhooks, service handlers, background jobs, serializers, clients, file operations, and network operations.
|
|
35
|
+
4. Trace suspicious values from source to sink or missing guard.
|
|
36
|
+
5. Read imported guards, validators, auth wrappers, schemas, middleware, shared utilities, and sibling handlers when they decide exploitability.
|
|
37
|
+
6. Check whether mitigations block the real path, not just a nearby path.
|
|
38
|
+
7. Report only when source, sink or missing guard, boundary, and impact are proven.
|
|
39
|
+
|
|
40
|
+
## What To Report
|
|
41
|
+
|
|
42
|
+
| Category | Report When |
|
|
43
|
+
|----------|-------------|
|
|
44
|
+
| Authentication | Login, session, token, OAuth, SSO, reset, webhook, or service identity checks can be bypassed, spoofed, replayed, or confused. |
|
|
45
|
+
| Authorization | Tenant, org, team, account, project, role, owner, or resource checks are missing, inverted, stale, or performed on the wrong actor. |
|
|
46
|
+
| Injection and RCE | User input reaches SQL/NoSQL, shell, template, eval, deserialization, expression, or dynamic import sinks without parameterization or allowlisting. |
|
|
47
|
+
| XSS and unsafe HTML | User-controlled data reaches HTML, DOM, script, Markdown HTML, unsafe URLs, or framework escape hatches without context-correct escaping or sanitization. |
|
|
48
|
+
| SSRF and redirects | User-controlled URLs, hosts, redirects, callbacks, proxies, or fetchers can reach internal services, metadata endpoints, or trusted redirect flows. |
|
|
49
|
+
| Filesystem and uploads | User-controlled paths, archive entries, object keys, filenames, or uploads can escape an intended root, overwrite sensitive files, or become executable. |
|
|
50
|
+
| Secrets and data exposure | Real credentials, tokens, private keys, signed URLs, auth headers, cookies, PII, stack traces, or internal fields are exposed to untrusted users, clients, or logs. |
|
|
51
|
+
| Crypto and randomness | Weak hashes, predictable random values, static IVs, ECB mode, timing-unsafe compares, unsigned tokens, or custom crypto protect security-sensitive data. |
|
|
52
|
+
| Abuse controls | Sensitive or expensive operations such as login, MFA, invites, exports, password reset, billing, email, SMS, or paid API calls lack meaningful rate, quota, replay, or idempotency controls. |
|
|
53
|
+
| CI and workflows | Workflow changes let untrusted or caller-controlled code, text, artifacts, caches, or actions reach privileged execution, secrets, write tokens, releases, packages, deployments, or sensitive runners. |
|
|
54
|
+
|
|
55
|
+
## Severity
|
|
56
|
+
|
|
57
|
+
| Level | Use For |
|
|
58
|
+
|-------|---------|
|
|
59
|
+
| high | Broad auth bypass, privilege escalation, cross-tenant sensitive data access, RCE, SQL/NoSQL injection over sensitive data, SSRF to internal services or cloud metadata, unsafe deserialization, production credential exposure, privileged CI execution, or destructive unauthorized actions. |
|
|
60
|
+
| medium | XSS with script execution, bounded path traversal, sensitive information disclosure, webhook side effects without verification, open redirects in auth/token flows, weak token validation, meaningful abuse of expensive or sensitive operations, or limited unauthorized data mutation. |
|
|
61
|
+
| low | Concrete defense-in-depth flaw with a plausible exploit path and limited impact. Do not use low for vague best-practice advice. |
|
|
62
|
+
|
|
63
|
+
- Tie-breaker: choose the lower severity when impact depends on unproven preconditions.
|
|
64
|
+
|
|
65
|
+
## What Not To Report
|
|
66
|
+
|
|
67
|
+
- Code fully mitigated by a verified guard in the effective path.
|
|
68
|
+
- Sinks fed only by constants, trusted server-side values, test data, migrations, generated code, vendored code, examples, or build output.
|
|
69
|
+
- Generic dependency CVEs unless the changed code makes the vulnerable behavior reachable.
|
|
70
|
+
- Style, lint, maintainability, performance, missing comments, or generic best-practice recommendations.
|
|
71
|
+
- Public endpoints that intentionally expose non-sensitive data and have no sensitive side effect.
|
|
72
|
+
- Workflow style, actionlint issues, broad permissions, or mutable action refs without a traced path to execution, credential exposure, trusted artifacts, or privileged side effects.
|
|
73
|
+
- Secret-looking placeholders such as `example`, `test`, `dummy`, documented fake keys, or values confined to tests.
|
|
74
|
+
- Framework defaults that already escape, parameterize, validate, or authorize unless the code uses an unsafe escape hatch.
|
|
75
|
+
|
|
76
|
+
## Finding Format
|
|
77
|
+
|
|
78
|
+
- Title: name the vulnerability and impact.
|
|
79
|
+
- Description: include source, sink or missing guard, boundary crossed, and attacker-visible consequence.
|
|
80
|
+
- `verification`: list checked files, functions, guards, or sibling paths.
|
|
81
|
+
- `suggestedFix`: include only when the fix is complete for the analyzed file.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Security Review Skill Specification
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
The `security-review` skill is Warden's broad default application security scanner. It gives teams a usable first-pass security review without importing benchmark prompts or requiring language-specific setup.
|
|
6
|
+
|
|
7
|
+
It should catch common exploitable vulnerabilities in changed production code while avoiding noisy hardening advice.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
In scope:
|
|
12
|
+
|
|
13
|
+
- Authentication, authorization, tenant isolation, identity, and service-boundary bugs.
|
|
14
|
+
- Injection, RCE, unsafe deserialization, XSS, SSRF, path traversal, unsafe redirects, webhook verification, secrets exposure, weak crypto, sensitive data exposure, and meaningful abuse-control gaps.
|
|
15
|
+
- General guidance that applies across web services and application code.
|
|
16
|
+
- Focused notes for JavaScript/TypeScript, Python, and GitHub Actions workflows.
|
|
17
|
+
|
|
18
|
+
Out of scope:
|
|
19
|
+
|
|
20
|
+
- Full dependency CVE triage without reachable changed code.
|
|
21
|
+
- Compliance checklists, infrastructure-only policy review, or exhaustive cloud IAM audits.
|
|
22
|
+
- Style, maintainability, performance, or non-security correctness bugs.
|
|
23
|
+
- Benchmark-specific prompt compatibility.
|
|
24
|
+
- Large language-specific catalogs in `SKILL.md`.
|
|
25
|
+
|
|
26
|
+
## Users And Trigger Context
|
|
27
|
+
|
|
28
|
+
- Primary users: coding agents and Warden runs reviewing pull requests or local changes.
|
|
29
|
+
- Should trigger for: "security review", "scan for vulnerabilities", "appsec review", "OWASP check", "auth bypass", "XSS", "SQL injection", "SSRF", "path traversal", "secret exposure", or equivalent security-focused review requests.
|
|
30
|
+
- Should not trigger for: generic code review, prompt-writing help, Warden CLI usage, or broad architecture review with no security focus.
|
|
31
|
+
|
|
32
|
+
## Runtime Contract
|
|
33
|
+
|
|
34
|
+
- Required first actions:
|
|
35
|
+
- Identify whether changed files are production code or test/generated/vendor/example code.
|
|
36
|
+
- Read the target file and any guards, helpers, middleware, validators, serializers, or sibling handlers needed to prove the path.
|
|
37
|
+
- Load only the matching language reference when it materially improves the review.
|
|
38
|
+
- Required finding evidence:
|
|
39
|
+
- attacker-controlled source
|
|
40
|
+
- vulnerable sink or missing guard
|
|
41
|
+
- crossed security boundary
|
|
42
|
+
- concrete attacker-visible impact
|
|
43
|
+
- verification details naming checked files/functions
|
|
44
|
+
- Required outputs:
|
|
45
|
+
- Warden findings only for high-confidence vulnerabilities.
|
|
46
|
+
- Empty findings when exploitability is not proven.
|
|
47
|
+
- Non-negotiable constraints:
|
|
48
|
+
- Do not report pattern-only suspicions.
|
|
49
|
+
- Do not lower the bar to create coverage.
|
|
50
|
+
- Do not add language-specific examples to `SKILL.md`; route them to `references/`.
|
|
51
|
+
|
|
52
|
+
## Reference Architecture
|
|
53
|
+
|
|
54
|
+
- `SKILL.md` contains the broad review contract, category table, severity rubric, exclusions, and reference routing.
|
|
55
|
+
- `references/javascript-typescript.md` contains JS/TS/Node/React/Next-specific examples and false-positive controls.
|
|
56
|
+
- `references/python.md` contains Python/Django/Flask/FastAPI-specific examples and false-positive controls.
|
|
57
|
+
- `references/github-workflows.md` contains GitHub Actions workflow examples and false-positive controls.
|
|
58
|
+
- `scripts/`, `assets/`, and `references/evidence/` are unused until repeated evidence warrants them.
|
|
59
|
+
|
|
60
|
+
## Evaluation
|
|
61
|
+
|
|
62
|
+
- Lightweight validation:
|
|
63
|
+
- Run the skill validator against `src/builtin-skills/security-review`.
|
|
64
|
+
- Verify every reference is directly routed from `SKILL.md`.
|
|
65
|
+
- Run init command tests that install bundled skills.
|
|
66
|
+
- Deeper evaluation:
|
|
67
|
+
- Add eval cases for SQL injection, XSS, SSRF, authz bypass, secrets, and safe counterexamples.
|
|
68
|
+
- Compare false positives against sanitized real Warden runs.
|
|
69
|
+
- Acceptance gates:
|
|
70
|
+
- `SKILL.md` stays concise enough to scan.
|
|
71
|
+
- Language-specific examples stay in references.
|
|
72
|
+
- Findings require exploitability evidence, not keyword matches.
|
|
73
|
+
|
|
74
|
+
## Maintenance Notes
|
|
75
|
+
|
|
76
|
+
- Add a new language reference only when recurring findings need language-specific calibration.
|
|
77
|
+
- Keep examples minimal and transformed; do not store proprietary code.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# GitHub Workflow Security Notes
|
|
2
|
+
|
|
3
|
+
Use this when reviewing GitHub Actions workflows, local actions, reusable workflows, or scripts/config loaded by workflows. This reference adapts the dedicated workflow-security prior art for the broad `security-review` skill; keep findings exploit-oriented, not style-oriented.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Review Map](#review-map)
|
|
8
|
+
- [Reportable Patterns](#reportable-patterns)
|
|
9
|
+
- [False-Positive Controls](#false-positive-controls)
|
|
10
|
+
- [Verification Checklist](#verification-checklist)
|
|
11
|
+
- [Minimal Examples](#minimal-examples)
|
|
12
|
+
|
|
13
|
+
## Review Map
|
|
14
|
+
|
|
15
|
+
Start with the effective execution graph:
|
|
16
|
+
|
|
17
|
+
1. Identify the trigger: `pull_request`, `pull_request_target`, `workflow_run`, `workflow_dispatch`, `workflow_call`, `issue_comment`, `discussion`, `label`, `push`, `release`, or `schedule`.
|
|
18
|
+
2. Mark who controls each input: fork PR code, PR title/body, branch names, changed filenames, comments, labels, discussion text, manual inputs, reusable-workflow inputs, artifacts, caches, local actions, and checked-out refs.
|
|
19
|
+
3. Follow every boundary: `uses: ./.github/actions/...`, `uses: ./.github/workflows/...`, composite action steps, repo-local scripts, Makefiles, package commands, artifacts, caches, and downloaded tools.
|
|
20
|
+
4. Mark privileges at the point of execution: `secrets.*`, PATs, deploy keys, registry tokens, `id-token: write`, `GITHUB_TOKEN` write scopes, release/package/deploy authority, and self-hosted runners.
|
|
21
|
+
5. Report only when untrusted or caller-controlled code/data reaches privileged execution, credentials, trusted artifacts, releases/packages/deployments, or sensitive runners.
|
|
22
|
+
|
|
23
|
+
In-scope files include `.github/workflows/*.yml`, `.github/workflows/*.yaml`, `.github/actions/**/action.yml`, `.github/actions/**/action.yaml`, repository-root `action.yml`/`action.yaml`, and any scripts/config files loaded by those workflows.
|
|
24
|
+
|
|
25
|
+
## Reportable Patterns
|
|
26
|
+
|
|
27
|
+
| Pattern | Report When | Safer Shape |
|
|
28
|
+
|---------|-------------|-------------|
|
|
29
|
+
| Privileged PR checkout | `pull_request_target`, privileged `workflow_run`, or similar trusted context checks out, imports, builds, tests, or executes PR-controlled refs while trusted tokens/secrets are available | Use `pull_request` for untrusted code, or keep `pull_request_target` metadata-only |
|
|
30
|
+
| Expression injection | Attacker/caller-controlled `${{ }}` reaches `run:`, composite shell steps, `bash -c`, `node -e`, `python -c`, `actions/github-script`, `actions/script`, or workflow command files | Move values to `env:`, read native variables, quote/validate, and avoid interpreter strings |
|
|
31
|
+
| Manual or reusable input RCE | Free-form `workflow_dispatch` or `workflow_call` input reaches release, deploy, publish, signing, PR creation, OIDC, PAT, or secret-bearing commands | Use finite input types, allowlists, argv APIs, and least privilege |
|
|
32
|
+
| Comment/chatops abuse | `issue_comment`, discussion, label, or slash-command workflows execute privileged commands without a trusted actor gate, or use comment text as shell/script input | Verify owner/member/collaborator/team permission and parse arguments as data |
|
|
33
|
+
| Approval TOCTOU | Maintainer approval occurs, then the workflow re-resolves `pull_request.head.sha`, `head_ref`, or PR refs at run time before privileged checkout/execution | Pin the exact SHA approved by the maintainer, or require re-approval after every push |
|
|
34
|
+
| Reusable/local action trust crossing | Caller grants secrets/write scopes while a callee or local composite action executes caller-controlled inputs or PR-controlled files | Pass narrow secrets, define callee permissions, validate inputs, keep local actions on trusted code |
|
|
35
|
+
| Artifact/cache trust crossing | Privileged `workflow_run`, release, or deploy job executes or trusts artifacts/caches produced by untrusted PR jobs | Treat artifacts/caches as untrusted data; validate, sign, or partition trust scopes |
|
|
36
|
+
| Artifact credential leak | `upload-artifact` uploads the workspace/root, `.git/`, home credential files, Docker/npm config, or similar after credentials were written | Upload only build outputs; set `persist-credentials: false`; exclude credential paths |
|
|
37
|
+
| Self-hosted runner exposure | PR-reachable or comment-triggered jobs run untrusted code on persistent, internal, signing, deploy, or otherwise sensitive self-hosted runners | Keep untrusted code on GitHub-hosted runners or require a strong approval gate |
|
|
38
|
+
| Mutable action supply chain | Third-party `uses: owner/action@tag`, branch, partial SHA, or mutable reusable workflow runs in a job with secrets, OIDC, write token, release, deploy, package, or signing power | Pin third-party actions and reusable workflows to a 40-character commit SHA |
|
|
39
|
+
| AI agent config poisoning | Privileged workflows run coding/review agents on PR-controlled checkouts or instruction files such as `AGENTS.md`, `CLAUDE.md`, or Copilot instructions | Run agents in unprivileged PR context, protect instruction files, and avoid write/secrets in poisoned contexts |
|
|
40
|
+
|
|
41
|
+
### Expression Injection Sources
|
|
42
|
+
|
|
43
|
+
Treat these as untrusted when the trigger is externally reachable, manually triggerable, or callable:
|
|
44
|
+
|
|
45
|
+
- PR title/body, issue title/body, comment body, review body, discussion title/body, label names, branch names, commit messages, changed filenames, and changed-file lists.
|
|
46
|
+
- `inputs.*` and `github.event.inputs.*` from `workflow_dispatch`.
|
|
47
|
+
- `inputs.*` from `workflow_call`, including values passed through visible caller workflows.
|
|
48
|
+
- Action outputs or env vars derived from the values above.
|
|
49
|
+
|
|
50
|
+
Usually not injectable by themselves: PR numbers, numeric IDs, full commit SHAs, booleans, base-repository constants, and hardcoded shell-safe `choice` inputs. Re-check them if later code reinterprets the value as shell, JavaScript, Python, package-manager flags, or another code-like language.
|
|
51
|
+
|
|
52
|
+
Dangerous sinks include:
|
|
53
|
+
|
|
54
|
+
- `run: echo "${{ github.event.pull_request.title }}"`
|
|
55
|
+
- `actions/github-script` or `actions/script` `script:` bodies containing `${{ github.event.* }}` or `${{ inputs.* }}`
|
|
56
|
+
- `echo "key=${{ github.event.comment.body }}" >> $GITHUB_OUTPUT`, `$GITHUB_ENV`, `$GITHUB_STEP_SUMMARY`, or `$GITHUB_PATH`
|
|
57
|
+
- `npx semver -i ${{ inputs.bump }} "$CURRENT"`, `gh pr create --fill ${{ inputs.pr_options }}`, `docker build -t ${{ inputs.tag }}`, `git checkout ${{ inputs.ref }}`
|
|
58
|
+
- Composite action shell steps that interpolate `${{ inputs.* }}` from an externally reachable caller
|
|
59
|
+
|
|
60
|
+
### Privileged PR Context
|
|
61
|
+
|
|
62
|
+
High-signal indicators:
|
|
63
|
+
|
|
64
|
+
- `on: pull_request_target` plus `actions/checkout` with `ref: ${{ github.event.pull_request.head.sha }}`, `github.head_ref`, `github.event.pull_request.head.ref`, `repository: ${{ github.event.pull_request.head.repo.full_name }}`, `refs/pull/...`, or custom `git fetch` of PR refs.
|
|
65
|
+
- Build/test/package commands after PR checkout: `npm install`, `pnpm install`, `npm test`, `pip install`, `tox`, `pytest`, `make`, `cargo`, `go test`, `bundle`, `gradle`, `mvn`.
|
|
66
|
+
- Local actions, scripts, Makefiles, package lifecycle hooks, or config files loaded from the PR checkout.
|
|
67
|
+
- `persist-credentials` omitted or true before untrusted code runs.
|
|
68
|
+
- Write scopes, secrets, OIDC, package publishing, release creation, deployments, or agent write access available in the same job.
|
|
69
|
+
|
|
70
|
+
Do not report `pull_request_target` that only labels, comments, or reads metadata without checking out or loading PR-controlled files.
|
|
71
|
+
|
|
72
|
+
### Reusable Workflows, Artifacts, Caches, And Credentials
|
|
73
|
+
|
|
74
|
+
Trace cross-file flows before reporting:
|
|
75
|
+
|
|
76
|
+
- `workflow_call` callers that pass secrets/write permissions into a callee that executes caller-controlled inputs.
|
|
77
|
+
- Reusable workflows that reference `secrets.X` without declaring `X` under `on.workflow_call.secrets`, other than `GITHUB_TOKEN`; this hides the secret surface and pressures callers into `secrets: inherit`.
|
|
78
|
+
- Reusable workflows without top-level or job-level `permissions:` when the callee needs a narrower scope than callers commonly grant.
|
|
79
|
+
- `workflow_run` jobs that download artifacts from untrusted PR workflows and execute scripts, import code, publish packages, or make trusted comments without validation.
|
|
80
|
+
- Caches shared from untrusted PR jobs into privileged jobs, including eviction-and-replace poisoning of expected cache keys.
|
|
81
|
+
- `actions/upload-artifact` whose `path:` includes `.`, `./`, `${{ github.workspace }}`, `.git/`, `~/.docker/config.json`, `~/.npmrc`, `~/.gitconfig`, `~/.aws/credentials`, or other credential-bearing paths after checkout/login/setup steps.
|
|
82
|
+
- `id-token: write` where untrusted refs can satisfy visible cloud OIDC trust policies.
|
|
83
|
+
|
|
84
|
+
Permissions and secrets are amplifiers. Tie them to the untrusted execution or leak path.
|
|
85
|
+
|
|
86
|
+
### Mutable Action References
|
|
87
|
+
|
|
88
|
+
Report mutable third-party actions only when job privilege makes compromise security-relevant. CVE-2025-30066 (`tj-actions/changed-files`) and related 2025 supply-chain incidents showed that tag rewrites can leak secrets at scale.
|
|
89
|
+
|
|
90
|
+
Severity guide:
|
|
91
|
+
|
|
92
|
+
| Shape | Severity |
|
|
93
|
+
|-------|----------|
|
|
94
|
+
| Mutable third-party ref in package publishing, release signing, protected-branch push, production deploy, or token-minting job | high |
|
|
95
|
+
| Mutable third-party ref with secrets, OIDC, or non-trivial write-scoped `GITHUB_TOKEN` | medium |
|
|
96
|
+
| Pinned action that downloads and executes mutable remote scripts in a privileged job | medium, or high when the downloaded payload runs inside the privileged step |
|
|
97
|
+
| Mutable third-party ref in public read-only CI with no secrets and no write scopes | no finding unless adjacent to another traced workflow risk |
|
|
98
|
+
|
|
99
|
+
First-party `actions/*` and `github/*` actions on version tags are not findings by themselves. Same-repo or vendored actions are not third-party supply-chain findings, but can still be unsafe if they are loaded from PR-controlled checkouts.
|
|
100
|
+
|
|
101
|
+
## False-Positive Controls
|
|
102
|
+
|
|
103
|
+
- Broad `permissions:` alone is not a vulnerability. Report it only as part of untrusted execution, credential exposure, artifact trust, or privileged side effect.
|
|
104
|
+
- Plain `pull_request` normally has restricted token and no base secrets for forks. Trace downstream artifacts/caches before escalating.
|
|
105
|
+
- `${{ }}` in `if:`, ordinary `with:`, or `env:` is not a sink unless the receiving action or a later shell/script interprets it as code. `actions/github-script` `with: script:` is a code sink.
|
|
106
|
+
- `env:` is only safe when the later shell/script uses native variables with quoting or validation. `echo '${{ env.BODY }}'` is still expression expansion.
|
|
107
|
+
- Hardcoded `choice`, `boolean`, `number`, and `environment` workflow inputs are usually safe when used only in `if:`, ordinary `with:`, or safely quoted `env:` contexts.
|
|
108
|
+
- Comment/body parsing is not a bug unless it triggers meaningful execution or privileged state change.
|
|
109
|
+
- `CONTRIBUTOR` is not equivalent to `MEMBER`, `OWNER`, or `COLLABORATOR` for chatops authorization.
|
|
110
|
+
- `persist-credentials: false` reduces `.git/config` token theft, but does not protect unrelated secrets, PATs, OIDC, or registry credentials.
|
|
111
|
+
- Do not invent external action internals. If source is unavailable, report the unresolved trust assumption as medium confidence at most.
|
|
112
|
+
|
|
113
|
+
## Verification Checklist
|
|
114
|
+
|
|
115
|
+
Before reporting:
|
|
116
|
+
|
|
117
|
+
1. Confirm the trigger can be reached by the attacker or lower-privileged caller you name.
|
|
118
|
+
2. Identify the exact attacker-controlled or caller-controlled value.
|
|
119
|
+
3. Identify the sink: shell/script execution, local action, package lifecycle hook, artifact/cache trust, credential-bearing upload, mutable action, or sensitive runner.
|
|
120
|
+
4. Follow local actions, reusable workflows, scripts, package commands, and workflow-produced artifacts/caches.
|
|
121
|
+
5. Confirm secrets, token scopes, OIDC, deploy/release/package authority, or runner sensitivity at the sink.
|
|
122
|
+
6. Check actor gates, branch/fork guards, finite input types, SHA pinning, `persist-credentials: false`, artifact path narrowing, and cloud trust-policy constraints.
|
|
123
|
+
7. Anchor the finding to the changed workflow line, and name the crossed boundary plus concrete impact.
|
|
124
|
+
|
|
125
|
+
## Minimal Examples
|
|
126
|
+
|
|
127
|
+
**Report: privileged PR checkout**
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
on: pull_request_target
|
|
131
|
+
permissions: write-all
|
|
132
|
+
jobs:
|
|
133
|
+
test:
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
steps:
|
|
136
|
+
- uses: actions/checkout@v4
|
|
137
|
+
with:
|
|
138
|
+
ref: ${{ github.event.pull_request.head.sha }}
|
|
139
|
+
- run: pnpm install
|
|
140
|
+
- run: pnpm test
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Risk: fork code controls package scripts while the job has trusted-repository permissions.
|
|
144
|
+
|
|
145
|
+
**Report: github-script injection**
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
on: issues
|
|
149
|
+
jobs:
|
|
150
|
+
comment:
|
|
151
|
+
steps:
|
|
152
|
+
- uses: actions/github-script@v7
|
|
153
|
+
with:
|
|
154
|
+
script: |
|
|
155
|
+
github.rest.issues.createComment({
|
|
156
|
+
body: `hello ${{ github.event.issue.title }}`
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Risk: the issue title is expanded into JavaScript before `actions/github-script` runs.
|
|
161
|
+
|
|
162
|
+
**Report: workspace artifact leak**
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
steps:
|
|
166
|
+
- uses: actions/checkout@v4
|
|
167
|
+
- uses: actions/upload-artifact@v4
|
|
168
|
+
with:
|
|
169
|
+
path: .
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Risk: `.git/config` can contain persisted checkout credentials, and public-repo artifacts can expose them.
|
|
173
|
+
|
|
174
|
+
**Do not report: metadata-only target workflow**
|
|
175
|
+
|
|
176
|
+
```yaml
|
|
177
|
+
on: pull_request_target
|
|
178
|
+
permissions:
|
|
179
|
+
pull-requests: write
|
|
180
|
+
jobs:
|
|
181
|
+
label:
|
|
182
|
+
steps:
|
|
183
|
+
- run: gh pr edit "$PR" --add-label needs-review
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
No PR-controlled code or text reaches execution. Broad token scope alone is not enough.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# JavaScript And TypeScript Security Notes
|
|
2
|
+
|
|
3
|
+
Use this when reviewing JavaScript, TypeScript, Node, React, Next.js, or browser code. These examples refine the core skill; they do not add new reporting scope.
|
|
4
|
+
|
|
5
|
+
## Server-Side Entry Points
|
|
6
|
+
|
|
7
|
+
- Next.js route handlers, Server Actions, API routes, tRPC/RPC handlers, Express/Fastify/Koa routes, webhook handlers, queue consumers, and CLI/service functions can be security boundaries.
|
|
8
|
+
- Treat Server Actions as callable server entry points. UI visibility, hidden form fields, and client components are not authorization.
|
|
9
|
+
- Next.js `middleware.ts` is not enough proof of authorization for sensitive mutations. Verify handler-level auth and resource-level authorization.
|
|
10
|
+
- For service handlers, do not trust caller-controlled headers such as `x-user-id`, `x-org-id`, `x-forwarded-*`, or internal-only flags unless a trusted gateway verifies them.
|
|
11
|
+
|
|
12
|
+
## High-Signal Patterns
|
|
13
|
+
|
|
14
|
+
| Pattern | Vulnerable | Safer |
|
|
15
|
+
|---------|------------|-------|
|
|
16
|
+
| Server Action authz | `"use server"` mutation trusts `userId`, `teamId`, `role`, hidden fields, or form args | Load session in the action, scope by server-side tenant, enforce permission |
|
|
17
|
+
| SQL injection | `prisma.$queryRawUnsafe(\`...${id}\`)`, string-built SQL, concatenated `where` clauses | Tagged templates, query parameters, ORM filters scoped to the authenticated tenant |
|
|
18
|
+
| Command injection | `exec("git " + branch)`, `spawn(cmd, args, {shell: true})` with user input | `execFile`/`spawn` with fixed binary, fixed argument positions, and strict allowlists |
|
|
19
|
+
| XSS | `innerHTML`, `dangerouslySetInnerHTML`, `unsafeHTML`, unsafe Markdown HTML, inline script JSON with user data | Text rendering, vetted sanitizer, escaping `<` in inline JSON, no dangerous URL schemes |
|
|
20
|
+
| SSRF | `fetch(req.query.url)`, image/preview/proxy fetchers using user URLs, redirect-following after first-hop validation | Exact host allowlist, private-IP blocking, DNS rebinding defenses, redirect revalidation or manual redirects |
|
|
21
|
+
| Open redirect | `redirect(searchParams.get("next"))`, prefix/substring URL checks in login or OAuth flows | Relative-path allowlist or exact origin/path allowlist after URL normalization |
|
|
22
|
+
| Path traversal | `path.join(root, userPath)` without realpath containment, archive extraction by entry name | Normalize and resolve real paths, verify containment, generate server-side filenames |
|
|
23
|
+
| Webhook forgery | State-changing webhook parses JSON before verifying signature or skips timestamp/replay checks | Verify raw body signature, timestamp freshness, replay/idempotency, and provider secret before side effects |
|
|
24
|
+
| Secrets exposure | Secrets in client components, `NEXT_PUBLIC_*`, serialized props, logs, or error responses | Server-only reads, redacted logs, safe error messages, no hardcoded production fallback |
|
|
25
|
+
|
|
26
|
+
## False-Positive Controls
|
|
27
|
+
|
|
28
|
+
- React text interpolation escapes by default. Report only escape hatches or dangerous URL/script contexts.
|
|
29
|
+
- Prisma/Drizzle/Knex query builders can parameterize values. Verify the specific API before reporting SQL injection.
|
|
30
|
+
- `crypto.randomUUID()` and `crypto.getRandomValues()` are suitable for security randomness; `Math.random()` is not.
|
|
31
|
+
- `jsonwebtoken.verify` can be safe when algorithms, issuer/audience, expiry, and key selection are pinned appropriately.
|
|
32
|
+
- DOMPurify or equivalent sanitizers can mitigate HTML injection when configured for the target context.
|
|
33
|
+
|
|
34
|
+
## Minimal Examples
|
|
35
|
+
|
|
36
|
+
**Report: cross-tenant lookup**
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const invoice = await db.invoice.findUnique({ where: { id: params.invoiceId } });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Require: server-derived tenant scope such as `accountId: session.accountId`, plus permission checks.
|
|
43
|
+
|
|
44
|
+
**Report: Server Action trusts caller fields**
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
"use server";
|
|
48
|
+
export async function setRole(userId: string, role: string) {
|
|
49
|
+
await db.user.update({ where: { id: userId }, data: { role } });
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Require: load session in the action and prove caller can mutate that tenant user.
|
|
54
|
+
|
|
55
|
+
**Report: inline JSON script breakout**
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<script dangerouslySetInnerHTML={{ __html: `window.__DATA__=${JSON.stringify(data)}` }} />
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Risk: `</script>` breakout. Require: escape `<` or `</script` before embedding.
|
|
62
|
+
|
|
63
|
+
**Do not report: parameterized query**
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
await db.$queryRaw`SELECT * FROM invoices WHERE id = ${invoiceId} AND account_id = ${accountId}`;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This is not SQL injection if the tagged template parameterizes values and `accountId` is trusted from the authenticated session.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Python Security Notes
|
|
2
|
+
|
|
3
|
+
Use this when reviewing Python, Django, Flask, FastAPI, Celery, or Python service code. These examples refine the core skill; they do not add new reporting scope.
|
|
4
|
+
|
|
5
|
+
## Server-Side Entry Points
|
|
6
|
+
|
|
7
|
+
- Django views, DRF viewsets, Flask/FastAPI routes, GraphQL resolvers, webhook handlers, Celery tasks, management commands, and service-layer functions can cross trust boundaries.
|
|
8
|
+
- For background jobs and tasks, verify the caller, queue, payload signing, tenant context, and idempotency before assuming input is trusted.
|
|
9
|
+
- Decorators can prove authentication only if they wrap the effective handler. Still verify object-level authorization.
|
|
10
|
+
- DRF/FastAPI auth dependencies prove identity, not ownership of route params or body IDs.
|
|
11
|
+
|
|
12
|
+
## High-Signal Patterns
|
|
13
|
+
|
|
14
|
+
| Pattern | Vulnerable | Safer |
|
|
15
|
+
|---------|------------|-------|
|
|
16
|
+
| SQL injection | `cursor.execute(f"...{request.GET['q']}...")`, string-built raw SQL | Parameterized queries, ORM filters, strict enum allowlists for identifiers |
|
|
17
|
+
| Command injection | `os.system`, `subprocess.run(..., shell=True)`, shell strings with request data | `subprocess.run([fixed_binary, fixed_arg])`, strict allowlists, no shell |
|
|
18
|
+
| Path traversal | `open(base / request.args["name"])`, `send_file(user_path)`, unsafe archive extraction | `Path.resolve()` containment checks, generated filenames, safe storage APIs |
|
|
19
|
+
| SSRF | `requests.get(request.GET["url"])`, preview/proxy fetchers, redirect-following after first-hop validation | Exact host allowlist, block private/link-local IPs, disable or revalidate redirects |
|
|
20
|
+
| Open redirect | `redirect(request.GET["next"])`, login/callback redirects with weak host checks | Relative-path allowlist or framework helper with exact allowed hosts |
|
|
21
|
+
| Unsafe deserialization | `pickle.loads`, `yaml.load` without `SafeLoader`, model/job loaders on uploaded data | JSON or typed schemas, `yaml.safe_load`, signed trusted artifacts only |
|
|
22
|
+
| XSS | Jinja/Django `|safe`, `Markup`, disabled autoescape, raw HTML from user content | Autoescaping, vetted sanitizer, context-correct escaping |
|
|
23
|
+
| Authz bypass | `Model.objects.get(id=request.GET["id"])` on tenant data | Scope by authenticated user/org/account and enforce permissions before returning or mutating |
|
|
24
|
+
| Task trust confusion | Celery task mutates `invoice_id`, `user_id`, or `account_id` queued from a request without rechecking scope | Pass server-derived actor/tenant context and re-check before mutation |
|
|
25
|
+
| Secrets exposure | Logging tokens, cookies, auth headers, signed URLs, stack traces, or env secrets | Redacted logging, generic errors, server-only secret access |
|
|
26
|
+
|
|
27
|
+
## False-Positive Controls
|
|
28
|
+
|
|
29
|
+
- Django and SQLAlchemy ORM filters usually parameterize values. Raw SQL and string-built identifiers need closer review.
|
|
30
|
+
- Django and Jinja autoescape ordinary template interpolation by default. Report only unsafe filters, raw HTML, or disabled autoescape.
|
|
31
|
+
- `secrets` and `os.urandom` are suitable for security randomness; `random` is not.
|
|
32
|
+
- `yaml.safe_load` is the safe default for untrusted YAML; `yaml.load` may still be safe only when an explicit safe loader is used.
|
|
33
|
+
- `Path.resolve()` containment checks can mitigate traversal when they compare the resolved child against the resolved allowed root.
|
|
34
|
+
|
|
35
|
+
## Minimal Examples
|
|
36
|
+
|
|
37
|
+
**Report: object-level authorization bypass**
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
invoice = Invoice.objects.get(id=request.GET["invoice_id"])
|
|
41
|
+
return JsonResponse({"total": invoice.total, "email": invoice.customer.email})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Require: authenticated account/org scope and permission before returning sensitive data.
|
|
45
|
+
|
|
46
|
+
**Report: task loses tenant context**
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
@shared_task
|
|
50
|
+
def approve_invoice(invoice_id: str):
|
|
51
|
+
Invoice.objects.filter(id=invoice_id).update(status="approved")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Require: reload trusted actor/tenant context and enforce permission.
|
|
55
|
+
|
|
56
|
+
**Report: unsafe uploaded state**
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
state = pickle.loads(base64.b64decode(request.POST["state"]))
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Risk: unsafe deserialization. Require: trusted, signature-verified artifact before deserialization.
|
|
63
|
+
|
|
64
|
+
**Do not report: scoped ORM query**
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
invoice = Invoice.objects.get(id=invoice_id, account_id=request.user.account_id)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This is not an authorization bypass if `request.user.account_id` is trusted and the caller is authenticated for that account.
|