torusguard 1.3.4 → 1.3.5
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/.torusguard/.manifest.json +66 -63
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/.torusguard/rules_catalog.json +520 -0
- package/.torusguard/runs/report-latest.html +93 -7
- package/.torusguard/runs/run-20260912-214110-audit/findings.json +1256 -0
- package/.torusguard/runs/run-20260912-214110-audit/findings.md +534 -0
- package/.torusguard/runs/run-20260912-214110-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214110-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.json +992 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.md +422 -0
- package/.torusguard/runs/run-20260912-214813-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214813-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.json +530 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.md +232 -0
- package/.torusguard/runs/run-20260912-215555-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260912-215555-audit/remediation.md +102 -0
- package/.torusguard/runs/run-20260912-215555-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215731-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/minimal_patch_plan.md +22 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/patch.diff +10 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/diff_summary.md +186 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.json +497 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.md +218 -0
- package/.torusguard/runs/run-20260912-215731-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260912-215731-audit/recheck.md +76 -0
- package/.torusguard/runs/run-20260912-215731-audit/remediation.md +234 -0
- package/.torusguard/runs/run-20260912-215731-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.json +68 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.md +36 -0
- package/.torusguard/runs/run-20260912-220134-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220134-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220200-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220200-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220200-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220227-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220227-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220227-audit/summary.md +5 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/report_sync.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +383 -377
- package/.torusguard/scripts/audit_runner.py +1306 -653
- package/.torusguard/scripts/finding_scorer.py +14 -2
- package/.torusguard/scripts/harden_runner.py +628 -455
- package/.torusguard/scripts/recheck_runner.py +248 -238
- package/.torusguard/scripts/recipes_runner.py +137 -137
- package/.torusguard/scripts/report_sync.py +423 -0
- package/.torusguard/scripts/sarif_exporter.py +116 -116
- package/.torusguard/scripts/term_ui.py +162 -162
- package/.torusguard/snapshots/run-20260912-215731-audit/demo/playground/vulnerable_nextjs/actions.ts.bak +24 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/hardened-react-express/server/index.js.bak +121 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/python/fastapi-vuln/main.py.bak +20 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/vite.config.js.bak +12 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/workflows/apply.md +11 -4
- package/.torusguard/workflows/audit.md +7 -1
- package/.torusguard/workflows/authorize.md +2 -1
- package/.torusguard/workflows/exploit-check.md +2 -1
- package/.torusguard/workflows/harden.md +7 -1
- package/.torusguard/workflows/init.md +6 -1
- package/.torusguard/workflows/memory.md +2 -1
- package/.torusguard/workflows/recheck.md +7 -1
- package/.torusguard/workflows/report.md +7 -1
- package/.torusguard/workflows/status.md +6 -1
- package/.torusguard/workflows/verify.md +6 -1
- package/.torusguard/workflows/web-validate.md +2 -1
- package/README.md +470 -345
- package/bin/torusguard.js +550 -545
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +73 -72
- package/skills/torusguard/payload/.manifest.json +66 -63
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/skills/torusguard/payload/rules_catalog.json +520 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +383 -377
- package/skills/torusguard/payload/scripts/audit_runner.py +1306 -653
- package/skills/torusguard/payload/scripts/finding_scorer.py +14 -2
- package/skills/torusguard/payload/scripts/harden_runner.py +628 -455
- package/skills/torusguard/payload/scripts/recheck_runner.py +248 -238
- package/skills/torusguard/payload/scripts/recipes_runner.py +137 -137
- package/skills/torusguard/payload/scripts/report_sync.py +423 -0
- package/skills/torusguard/payload/scripts/sarif_exporter.py +116 -116
- package/skills/torusguard/payload/scripts/term_ui.py +162 -162
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +75 -72
- package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +7 -2
- package/skills/torusguard/payload/workflows/apply.md +11 -4
- package/skills/torusguard/payload/workflows/audit.md +7 -1
- package/skills/torusguard/payload/workflows/authorize.md +2 -1
- package/skills/torusguard/payload/workflows/exploit-check.md +2 -1
- package/skills/torusguard/payload/workflows/harden.md +7 -1
- package/skills/torusguard/payload/workflows/init.md +6 -1
- package/skills/torusguard/payload/workflows/memory.md +2 -1
- package/skills/torusguard/payload/workflows/recheck.md +7 -1
- package/skills/torusguard/payload/workflows/report.md +7 -1
- package/skills/torusguard/payload/workflows/status.md +6 -1
- package/skills/torusguard/payload/workflows/verify.md +6 -1
- package/skills/torusguard/payload/workflows/web-validate.md +2 -1
- package/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard-web-validate/SKILL.md +7 -2
|
@@ -1,37 +1,42 @@
|
|
|
1
|
-
# TG-SEC-005: Secret in Git History
|
|
1
|
+
# TG-SEC-005: Secret or Private Key in Git History
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Committing private API keys, credentials, or private certificates into git history persists them permanently across all cloned repositories, even if deleted in subsequent commits.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Git Repositories, Public and Private Remotes
|
|
8
|
+
- All Languages & Frameworks
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Deleting a secret file in a follow-up commit (`git rm .env`) does NOT remove it from git history. Attackers clone public repositories and run scanners (`git log -p`) to extract historical secrets within seconds.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Git commit objects or patch diffs containing private keys, AWS access keys, or JWT secret strings.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```bash
|
|
18
|
+
# UNSAFE: Adding .env with live credentials directly to git tracking
|
|
19
|
+
git add .env
|
|
20
|
+
git commit -m "Add production database credentials"
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
24
|
+
```bash
|
|
25
|
+
# SAFE: Keeping .env in .gitignore; using .env.example with placeholder tokens
|
|
26
|
+
echo ".env" >> .gitignore
|
|
27
|
+
git add .gitignore .env.example
|
|
28
|
+
git commit -m "Add environment configuration baseline"
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
31
|
+
## Ponytail Remediation Budget
|
|
32
|
+
- Additions: <= 2 lines
|
|
33
|
+
- Deletions: <= 2 lines
|
|
32
34
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
+
## Remediation
|
|
36
|
+
1. Immediately rotate any secret that was committed to git history.
|
|
37
|
+
2. Use tools like `git-filter-repo` or BFG Repo-Cleaner to purge the commit blob from repository history.
|
|
38
|
+
3. Add `.env` and `*.pem` to `.gitignore`.
|
|
35
39
|
|
|
36
40
|
## Related Rules
|
|
37
|
-
- TG-
|
|
41
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
42
|
+
- `TG-SEC-003`: Unencrypted Secret in Tracked Config File
|
|
@@ -1,37 +1,54 @@
|
|
|
1
|
-
# TG-SEC-006: Secret in Build Artifact
|
|
1
|
+
# TG-SEC-006: Secret in Build Artifact or Container Image
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Copying `.env` files, build-time secrets, or SSH keys into Docker build layers persists secrets in image layers, allowing anyone with pull access to extract credentials via `docker history` or container inspection.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Dockerfiles, Container Builds, Serverless Bundle Artifacts
|
|
8
|
+
- Docker, Containerd, Podman, Webpack, Vite
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Docker image layers are cached and stored individually. Running `COPY .env .` followed by `RUN rm .env` still retains the `.env` file in the preceding layer blob, allowing trivial credential recovery.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Dockerfile instructions containing `COPY .env` or `ARG SECRET_KEY` without BuildKit secret mount protection.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```dockerfile
|
|
18
|
+
# UNSAFE: Copying local .env into container layer
|
|
19
|
+
FROM node:20-alpine
|
|
20
|
+
WORKDIR /app
|
|
21
|
+
COPY package*.json ./
|
|
22
|
+
RUN npm ci
|
|
23
|
+
COPY .env .
|
|
24
|
+
COPY . .
|
|
25
|
+
RUN npm run build
|
|
18
26
|
```
|
|
19
27
|
|
|
20
28
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
29
|
+
```dockerfile
|
|
30
|
+
# SAFE: Using BuildKit secret mounts or multi-stage build without persisting secrets
|
|
31
|
+
# syntax=docker/dockerfile:1.4
|
|
32
|
+
FROM node:20-alpine AS builder
|
|
33
|
+
WORKDIR /app
|
|
34
|
+
COPY package*.json ./
|
|
35
|
+
RUN npm ci
|
|
36
|
+
COPY . .
|
|
37
|
+
RUN --mount=type=secret,id=build_secrets npm run build
|
|
38
|
+
|
|
39
|
+
FROM node:20-alpine
|
|
40
|
+
WORKDIR /app
|
|
41
|
+
COPY --from=builder /app/dist ./dist
|
|
23
42
|
```
|
|
24
43
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
44
|
+
## Ponytail Remediation Budget
|
|
45
|
+
- Additions: <= 5 lines
|
|
46
|
+
- Deletions: <= 2 lines
|
|
32
47
|
|
|
33
|
-
##
|
|
34
|
-
|
|
48
|
+
## Remediation
|
|
49
|
+
1. Use Docker BuildKit secret mounts (`--mount=type=secret`) for credentials needed during build.
|
|
50
|
+
2. Use multi-stage Docker builds to ensure final runtime images only contain compiled frontend assets.
|
|
35
51
|
|
|
36
52
|
## Related Rules
|
|
37
|
-
- TG-
|
|
53
|
+
- `TG-SUPPLY-006`: Container Build Secret Persistence
|
|
54
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md
CHANGED
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
# TG-SEC-007: Secret in Test or Example Fixture
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Medium. Committing real production or staging credentials into test fixtures, mocks, or example configuration files leaks secrets under the assumption that test directories are unmonitored.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Test Suites, Mock Fixtures, Example Configs
|
|
8
|
+
- All Languages & Frameworks
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Developers often copy live payload captures from production to create integration tests or seed fixtures. If these fixtures contain real API keys or customer JWT tokens, they are exposed in source control.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- High-entropy tokens, Stripe live keys (`sk_live_`), or valid JWT signatures present in `tests/`, `fixtures/`, or `examples/` directories.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Real active production API key used in test fixture
|
|
19
|
+
const mockAuth = {
|
|
20
|
+
apiKey: "sk_live_51M0...REAL_STRIPE_LIVE_KEY_12345"
|
|
21
|
+
};
|
|
18
22
|
```
|
|
19
23
|
|
|
20
24
|
## Safe Example
|
|
21
25
|
```javascript
|
|
22
|
-
//
|
|
26
|
+
// SAFE: Explicit synthetic mock sentinel string
|
|
27
|
+
const mockAuth = {
|
|
28
|
+
apiKey: "sk_test_fake_mock_token_for_unit_tests_only"
|
|
29
|
+
};
|
|
23
30
|
```
|
|
24
31
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
32
|
+
## Ponytail Remediation Budget
|
|
33
|
+
- Additions: <= 2 lines
|
|
34
|
+
- Deletions: <= 2 lines
|
|
32
35
|
|
|
33
|
-
##
|
|
34
|
-
|
|
36
|
+
## Remediation
|
|
37
|
+
1. Replace all real credentials in test directories with synthetic, inert mock sentinels (`test_token_dummy`).
|
|
38
|
+
2. Rotate any credentials that were copied from production to test files.
|
|
35
39
|
|
|
36
40
|
## Related Rules
|
|
37
|
-
- TG-
|
|
41
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
42
|
+
- `TG-SEC-004`: Sensitive Information in Logs
|
package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md
CHANGED
|
@@ -1,37 +1,64 @@
|
|
|
1
1
|
# TG-SSRF-002: Missing Internal Network Protection
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Allowing server-side HTTP clients to dispatch requests to internal network interfaces (127.0.0.1, private RFC 1918 subnets, or cloud metadata services like 169.254.169.254) allows external attackers to extract cloud credentials and interact with internal microservices.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Webhook dispatchers, URL preview fetchers, PDF generators, image proxies
|
|
8
|
+
- Node.js (fetch, axios), Python (requests, httpx, urllib), Go (net/http), Java
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
If a server accepts a destination URL from a user (e.g. `/api/fetch-avatar?url=...`) without blocking private network spaces, an attacker can supply `http://169.254.169.254/latest/meta-data/iam/security-credentials/` to steal AWS IAM role tokens, or `http://127.0.0.1:6379` to inject Redis commands.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Server-side request calls dispatching requests to unvalidated URLs that could resolve to loopback (`127.0.0.0/8`), link-local (`169.254.0.0/16`), or private IP ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`).
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```python
|
|
18
|
+
# UNSAFE: Outbound fetch without private IP filtering
|
|
19
|
+
import requests
|
|
20
|
+
from fastapi import FastAPI
|
|
21
|
+
|
|
22
|
+
app = FastAPI()
|
|
23
|
+
|
|
24
|
+
@app.get("/fetch")
|
|
25
|
+
def fetch_url(url: str):
|
|
26
|
+
return requests.get(url).text # Attacker passes http://169.254.169.254/...
|
|
18
27
|
```
|
|
19
28
|
|
|
20
29
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
```python
|
|
31
|
+
# SAFE: Resolving IP and validating against private subnet ranges before fetching
|
|
32
|
+
import socket
|
|
33
|
+
import ipaddress
|
|
34
|
+
import requests
|
|
35
|
+
from fastapi import FastAPI, HTTPException
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
1. Step one
|
|
27
|
-
2. Step two
|
|
37
|
+
app = FastAPI()
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
def is_safe_url(url: str) -> bool:
|
|
40
|
+
from urllib.parse import urlparse
|
|
41
|
+
hostname = urlparse(url).hostname
|
|
42
|
+
if not hostname: return False
|
|
43
|
+
ip = ipaddress.ip_address(socket.gethostbyname(hostname))
|
|
44
|
+
return not (ip.is_private or ip.is_loopback or ip.is_link_local)
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
@app.get("/fetch")
|
|
47
|
+
def fetch_url(url: str):
|
|
48
|
+
if not is_safe_url(url):
|
|
49
|
+
raise HTTPException(status_code=400, detail="Invalid destination IP")
|
|
50
|
+
return requests.get(url, timeout=5.0).text
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Ponytail Remediation Budget
|
|
54
|
+
- Additions: <= 14 lines
|
|
55
|
+
- Deletions: <= 2 lines
|
|
56
|
+
|
|
57
|
+
## Remediation
|
|
58
|
+
1. Parse the destination hostname and resolve DNS.
|
|
59
|
+
2. Assert that resolved IP addresses are neither loopback (`127.0.0.0/8`), link-local (`169.254.0.0/16`), nor RFC 1918 private subnets.
|
|
60
|
+
3. Pin DNS resolution to prevent time-of-check to time-of-use (TOCTOU) DNS rebinding attacks.
|
|
35
61
|
|
|
36
62
|
## Related Rules
|
|
37
|
-
- TG-
|
|
63
|
+
- `TG-SSRF-001`: User-Controlled Server-Side URL Fetch
|
|
64
|
+
- `TG-SSRF-004`: Unbounded Outbound Request
|
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
# TG-SSRF-003: Unsafe Redirect Following
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
High by
|
|
4
|
+
High. Configuring server-side HTTP clients to automatically follow redirects allows attackers to bypass initial URL allowlists by supplying a public URL that redirects (301/302) to an internal loopback or cloud metadata service.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- HTTP Clients (Axios, Requests, Fetch, urllib, cURL)
|
|
8
|
+
- Node.js, Python, Go, Java
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
An application might validate that `https://example.com/image.png` is safe. However, if `example.com` returns a redirect header `Location: http://169.254.169.254/latest/meta-data/` and the client follows redirects automatically, the internal metadata service is fetched.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- HTTP client configurations with `maxRedirects > 0`, `follow_redirects=True`, or `allow_redirects=True` on user-controlled fetches.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
17
|
```javascript
|
|
17
|
-
//
|
|
18
|
+
// UNSAFE: Axios configured with default automatic redirect following
|
|
19
|
+
const response = await axios.get(userSuppliedUrl, { maxRedirects: 5 });
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
## Safe Example
|
|
21
23
|
```javascript
|
|
22
|
-
//
|
|
24
|
+
// SAFE: Disabling automatic redirect following or revalidating redirect target
|
|
25
|
+
const response = await axios.get(userSuppliedUrl, {
|
|
26
|
+
maxRedirects: 0,
|
|
27
|
+
validateStatus: status => status >= 200 && status < 300
|
|
28
|
+
});
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
31
|
+
## Ponytail Remediation Budget
|
|
32
|
+
- Additions: <= 4 lines
|
|
33
|
+
- Deletions: <= 2 lines
|
|
32
34
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
+
## Remediation
|
|
36
|
+
1. Disable automatic HTTP redirect following (`maxRedirects: 0` or `allow_redirects=False`).
|
|
37
|
+
2. If redirects must be supported, intercept `Location` headers and re-run IP safety checks before dispatching secondary requests.
|
|
35
38
|
|
|
36
39
|
## Related Rules
|
|
37
|
-
- TG-
|
|
40
|
+
- `TG-SSRF-001`: User-Controlled Server-Side URL Fetch
|
|
41
|
+
- `TG-SSRF-002`: Missing Internal Network Protection
|
|
@@ -1,37 +1,46 @@
|
|
|
1
|
-
# TG-SSRF-004: Unbounded Outbound Request
|
|
1
|
+
# TG-SSRF-004: Unbounded Outbound Request Without Timeout
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Dispatching server-side HTTP requests without strict socket and read timeouts allows malicious endpoints or slowloris servers to hang server worker threads indefinitely, leading to resource exhaustion and DoS.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- Outbound HTTP Clients (Python `requests`, Node `axios`, Go `http.Client`)
|
|
8
|
+
- Python, Node.js, Go, Java
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
In Python `requests`, the default timeout is `None` (it waits forever). If an attacker provides a URL pointing to a server that accepts the connection and trickles 1 byte every 10 minutes, your server worker threads become permanently exhausted.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- Outbound HTTP calls (`requests.get`, `requests.post`, `axios.get`, `fetch`) lacking explicit `timeout` parameters.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```python
|
|
18
|
+
# UNSAFE: Python requests call without timeout hangs indefinitely
|
|
19
|
+
import requests
|
|
20
|
+
|
|
21
|
+
def fetch_avatar(url: str):
|
|
22
|
+
response = requests.get(url) # Can hang indefinitely
|
|
23
|
+
return response.content
|
|
18
24
|
```
|
|
19
25
|
|
|
20
26
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
```python
|
|
28
|
+
# SAFE: Explicit timeout prevents hanging worker threads
|
|
29
|
+
import requests
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
def fetch_avatar(url: str):
|
|
32
|
+
response = requests.get(url, timeout=5.0) # 5-second socket timeout
|
|
33
|
+
return response.content
|
|
34
|
+
```
|
|
28
35
|
|
|
29
|
-
##
|
|
30
|
-
-
|
|
31
|
-
-
|
|
36
|
+
## Ponytail Remediation Budget
|
|
37
|
+
- Additions: <= 2 lines
|
|
38
|
+
- Deletions: <= 1 line
|
|
32
39
|
|
|
33
|
-
##
|
|
34
|
-
|
|
40
|
+
## Remediation
|
|
41
|
+
1. Always specify an explicit `timeout` on all network calls (typically 3.0 to 10.0 seconds).
|
|
42
|
+
2. Configure custom client sessions with default timeouts applied globally.
|
|
35
43
|
|
|
36
44
|
## Related Rules
|
|
37
|
-
- TG-
|
|
45
|
+
- `TG-SSRF-001`: User-Controlled Server-Side URL Fetch
|
|
46
|
+
- `TG-RATE-003`: Unbounded Resource Consumption
|
|
@@ -1,37 +1,44 @@
|
|
|
1
1
|
# TG-SUPPLY-001: Missing or Ignored Dependency Lockfile
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
High
|
|
4
|
+
High. Omitting or `.gitignore`-ing dependency lockfiles (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `Poetry.lock`, `Cargo.lock`, `go.sum`) allows non-deterministic builds and exposes installations to malicious sub-dependency updates.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- npm, pnpm, yarn, pip, poetry, cargo, go
|
|
8
|
+
- All polyglot projects
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Without a committed lockfile, running `npm install` or `pip install` resolves the latest compatible semantic version (`^1.0.0`). If a third-party dependency author account is compromised and publishes a malicious patch version, your CI/CD pipeline installs it automatically.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- `.gitignore` files containing `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml`.
|
|
15
|
+
- Repositories with manifest files (`package.json`) lacking corresponding lockfiles.
|
|
14
16
|
|
|
15
17
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
+
```gitignore
|
|
19
|
+
# UNSAFE: Ignoring dependency lockfiles in version control
|
|
20
|
+
node_modules/
|
|
21
|
+
package-lock.json
|
|
22
|
+
yarn.lock
|
|
18
23
|
```
|
|
19
24
|
|
|
20
25
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
26
|
+
```gitignore
|
|
27
|
+
# SAFE: Tracking lockfiles in version control; ignoring only node_modules
|
|
28
|
+
node_modules/
|
|
29
|
+
dist/
|
|
30
|
+
build/
|
|
23
31
|
```
|
|
24
32
|
|
|
25
|
-
## Remediation
|
|
26
|
-
1
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
33
|
+
## Ponytail Remediation Budget
|
|
34
|
+
- Additions: <= 1 line
|
|
35
|
+
- Deletions: <= 2 lines
|
|
32
36
|
|
|
33
|
-
##
|
|
34
|
-
|
|
37
|
+
## Remediation
|
|
38
|
+
1. Remove lockfile references from `.gitignore`.
|
|
39
|
+
2. Run `npm install` to generate `package-lock.json` and commit it to git.
|
|
40
|
+
3. In CI/CD pipelines, use `npm ci` or `pnpm install --frozen-lockfile` instead of `npm install`.
|
|
35
41
|
|
|
36
42
|
## Related Rules
|
|
37
|
-
- TG-
|
|
43
|
+
- `TG-SUPPLY-002`: Vulnerable Dependency Review Missing
|
|
44
|
+
- `TG-SUPPLY-004`: Unpinned CI Action
|
package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md
CHANGED
|
@@ -1,37 +1,47 @@
|
|
|
1
|
-
# TG-SUPPLY-003: Unsafe CI/CD Secret Exposure
|
|
1
|
+
# TG-SUPPLY-003: Unsafe CI/CD Secret Exposure in Workflow Logs
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Echoing or printing pipeline secrets in CI/CD step commands (`echo ${{ secrets.API_KEY }}`) or passing secrets directly in command line arguments persists plaintext credentials in build logs.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- GitHub Actions, GitLab CI, CircleCI, Bitbucket Pipelines
|
|
8
|
+
- YAML Workflows
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
CI/CD logs are often accessible to broad team members, external contributors, or public viewers on open-source repositories. Even when CI providers attempt log masking, modified or base64-encoded strings bypass masking and remain permanently visible in build logs.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- CI steps running `echo` or `print` on `${{ secrets.* }}` or `$SECRET_*`.
|
|
15
|
+
- Passing secrets as command-line arguments instead of masked environment variables.
|
|
14
16
|
|
|
15
17
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
+
```yaml
|
|
19
|
+
# UNSAFE: Echoing secrets directly into execution step logs
|
|
20
|
+
- name: Deploy to Cloud
|
|
21
|
+
run: |
|
|
22
|
+
echo "Using token ${{ secrets.DEPLOY_TOKEN }}"
|
|
23
|
+
deploy-tool --token ${{ secrets.DEPLOY_TOKEN }}
|
|
18
24
|
```
|
|
19
25
|
|
|
20
26
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
27
|
+
```yaml
|
|
28
|
+
# SAFE: Injecting secrets strictly via environment variables without logging
|
|
29
|
+
- name: Deploy to Cloud
|
|
30
|
+
env:
|
|
31
|
+
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
|
|
32
|
+
run: |
|
|
33
|
+
deploy-tool
|
|
23
34
|
```
|
|
24
35
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
36
|
+
## Ponytail Remediation Budget
|
|
37
|
+
- Additions: <= 5 lines
|
|
38
|
+
- Deletions: <= 3 lines
|
|
32
39
|
|
|
33
|
-
##
|
|
34
|
-
|
|
40
|
+
## Remediation
|
|
41
|
+
1. Never print or echo secret variables in workflow step commands.
|
|
42
|
+
2. Pass secrets into steps strictly via the `env:` block.
|
|
43
|
+
3. Avoid command-line arguments for secrets; configure tools to read credentials from environment variables or secure files.
|
|
35
44
|
|
|
36
45
|
## Related Rules
|
|
37
|
-
- TG-
|
|
46
|
+
- `TG-SEC-001`: Hardcoded Secret or API Key in Tracked Source
|
|
47
|
+
- `TG-SUPPLY-004`: Unpinned CI Action
|
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
# TG-SUPPLY-004: Unpinned CI Action
|
|
2
2
|
|
|
3
3
|
## Severity
|
|
4
|
-
|
|
4
|
+
Critical. Referencing third-party GitHub Actions using mutable branch or version tags (e.g. `uses: actions/checkout@v4`) allows attackers who compromise the action's repository to push malicious code that runs with your workflow's permissions.
|
|
5
5
|
|
|
6
6
|
## Applies To
|
|
7
|
-
-
|
|
7
|
+
- GitHub Actions Workflows (`.github/workflows/*.yml`)
|
|
8
|
+
- CI/CD Configurations
|
|
8
9
|
|
|
9
10
|
## Why It Matters
|
|
10
|
-
|
|
11
|
+
Git tags in third-party repositories are mutable pointers. An attacker who compromises a popular action maintainer's account can force-push a malicious commit to `@v3` or `@v4`, granting them immediate execution inside your CI environment with access to your repository secrets.
|
|
11
12
|
|
|
12
13
|
## What TorusGuard Looks For
|
|
13
|
-
-
|
|
14
|
+
- GitHub Actions `uses:` declarations referencing version tags (`@v4`, `@main`) instead of 40-character immutable commit SHA hashes.
|
|
14
15
|
|
|
15
16
|
## Unsafe Example
|
|
16
|
-
```
|
|
17
|
-
|
|
17
|
+
```yaml
|
|
18
|
+
# UNSAFE: Mutable tag vulnerable to tag spoofing
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: some-vendor/setup-tool@v1
|
|
18
22
|
```
|
|
19
23
|
|
|
20
24
|
## Safe Example
|
|
21
|
-
```
|
|
22
|
-
|
|
25
|
+
```yaml
|
|
26
|
+
# SAFE: Immutable commit SHA pinning with version comment
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
29
|
+
- uses: some-vendor/setup-tool@c2e8c2f1f8b172a5a54db5e6b12a818c1b2c3d4e # v1.2.0
|
|
23
30
|
```
|
|
24
31
|
|
|
25
|
-
## Remediation
|
|
26
|
-
|
|
27
|
-
2
|
|
28
|
-
|
|
29
|
-
## Verification
|
|
30
|
-
- Test case 1
|
|
31
|
-
- Test case 2
|
|
32
|
+
## Ponytail Remediation Budget
|
|
33
|
+
- Additions: <= 2 lines
|
|
34
|
+
- Deletions: <= 2 lines
|
|
32
35
|
|
|
33
|
-
##
|
|
34
|
-
|
|
36
|
+
## Remediation
|
|
37
|
+
1. Pin all external GitHub Actions to full 40-character commit SHAs.
|
|
38
|
+
2. Use tools like Dependabot or Renovate to automate SHA updates with release verification.
|
|
35
39
|
|
|
36
40
|
## Related Rules
|
|
37
|
-
- TG-
|
|
41
|
+
- `TG-SUPPLY-003`: Unsafe CI/CD Secret Exposure
|
|
42
|
+
- `TG-SUPPLY-005`: Unsafe Dependency Install Script
|