torusguard 1.0.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.torusguard/.manifest.json +196 -78
- package/.torusguard/references/csharp-security.md +41 -0
- package/.torusguard/references/go-security.md +41 -0
- package/.torusguard/references/java-security.md +40 -0
- package/.torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/references/rust-security.md +40 -0
- package/.torusguard/rules/README.md +93 -62
- package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/.torusguard/rules/custom/.gitkeep +1 -0
- package/.torusguard/rules/custom/README.md +30 -0
- package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/.torusguard/runs/report-latest.html +370 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
- package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
- package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
- package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
- package/.torusguard/runs/run-20260908-115240-audit/summary.md +5 -0
- package/.torusguard/schemas/golden-recipe.schema.json +75 -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__/memory_engine.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +332 -0
- package/.torusguard/scripts/audit_runner.py +550 -0
- package/.torusguard/scripts/diff_guard.py +183 -8
- package/.torusguard/scripts/finding_scorer.py +91 -5
- package/.torusguard/scripts/harden_runner.py +353 -0
- package/.torusguard/scripts/html_reporter.py +643 -0
- package/.torusguard/scripts/manifest_builder.py +7 -5
- package/.torusguard/scripts/memory_engine.py +525 -99
- package/.torusguard/scripts/monorepo_detector.py +123 -10
- package/.torusguard/scripts/recheck_runner.py +221 -0
- package/.torusguard/scripts/recipes_runner.py +130 -0
- package/.torusguard/scripts/rules_sync.py +321 -0
- package/.torusguard/scripts/run_manager.py +17 -5
- package/.torusguard/scripts/stack_detect.py +458 -26
- package/.torusguard/skills/torusguard/SKILL.md +42 -42
- package/.torusguard/skills/torusguard/references/csharp-security.md +41 -0
- package/.torusguard/skills/torusguard/references/go-security.md +41 -0
- package/.torusguard/skills/torusguard/references/java-security.md +40 -0
- package/.torusguard/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/skills/torusguard/references/rust-security.md +40 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
- package/README.md +344 -410
- package/bin/torusguard.js +195 -21
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/bootstrap.py +149 -70
- package/skills/torusguard/payload/.manifest.json +196 -78
- package/skills/torusguard/payload/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/references/go-security.md +41 -0
- package/skills/torusguard/payload/references/java-security.md +40 -0
- package/skills/torusguard/payload/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/references/rust-security.md +40 -0
- package/skills/torusguard/payload/rules/README.md +93 -62
- package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/skills/torusguard/payload/rules/custom/.gitkeep +1 -0
- package/skills/torusguard/payload/rules/custom/README.md +30 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/skills/torusguard/payload/schemas/golden-recipe.schema.json +75 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +332 -0
- package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +183 -8
- package/skills/torusguard/payload/scripts/finding_scorer.py +91 -5
- package/skills/torusguard/payload/scripts/harden_runner.py +353 -0
- package/skills/torusguard/payload/scripts/html_reporter.py +643 -0
- package/skills/torusguard/payload/scripts/manifest_builder.py +7 -5
- package/skills/torusguard/payload/scripts/memory_engine.py +525 -99
- package/skills/torusguard/payload/scripts/monorepo_detector.py +123 -10
- package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
- package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
- package/skills/torusguard/payload/scripts/rules_sync.py +321 -0
- package/skills/torusguard/payload/scripts/run_manager.py +17 -5
- package/skills/torusguard/payload/scripts/stack_detect.py +458 -26
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +149 -70
- package/skills/torusguard/payload/skills/torusguard/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/go-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/java-security.md +40 -0
- package/skills/torusguard/payload/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/skills/torusguard/references/rust-security.md +40 -0
- package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
- package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
|
@@ -1,62 +1,93 @@
|
|
|
1
|
-
# TorusGuard
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
# TorusGuard Rule Catalog
|
|
2
|
+
|
|
3
|
+
Stable rule IDs for TorusGuard v1.3.0. Each rule has a dedicated document in this directory.
|
|
4
|
+
|
|
5
|
+
## Severity Definitions
|
|
6
|
+
|
|
7
|
+
| Severity | Meaning |
|
|
8
|
+
|----------|---------|
|
|
9
|
+
| **Critical** | Secret exposure or flaw enabling immediate compromise of sensitive systems/data |
|
|
10
|
+
| **High** | Exploitable weakness likely to expose or modify sensitive data, accounts, or privileged operations |
|
|
11
|
+
| **Medium** | Important defense gap with meaningful but contextual impact |
|
|
12
|
+
| **Low** | Hardening improvement or limited direct impact |
|
|
13
|
+
| **Info** | Best-practice observation requiring human judgment |
|
|
14
|
+
|
|
15
|
+
## Rule Index
|
|
16
|
+
|
|
17
|
+
### Secrets and Configuration
|
|
18
|
+
|
|
19
|
+
| ID | Title | Default Severity |
|
|
20
|
+
|----|-------|------------------|
|
|
21
|
+
| [TG-SEC-001](TG-SEC-001-hardcoded-secrets.md) | Hardcoded Secret | Critical |
|
|
22
|
+
| [TG-SEC-002](TG-SEC-002-public-environment-secrets.md) | Sensitive Value in Public Environment Variable | Critical |
|
|
23
|
+
| [TG-SEC-003](TG-SEC-003-tracked-env-file.md) | Tracked Environment File | High |
|
|
24
|
+
| [TG-SEC-004](TG-SEC-004-sensitive-logging.md) | Sensitive Data Logging | Medium |
|
|
25
|
+
|
|
26
|
+
### Frontend Database Exposure
|
|
27
|
+
|
|
28
|
+
| ID | Title | Default Severity |
|
|
29
|
+
|----|-------|------------------|
|
|
30
|
+
| [TG-DB-001](TG-DB-001-frontend-database-query.md) | Database Query in Frontend Source | High |
|
|
31
|
+
| [TG-DB-002](TG-DB-002-privileged-database-credential.md) | Privileged Database Credential in Browser Code | Critical |
|
|
32
|
+
| [TG-DB-003](TG-DB-003-frontend-admin-sdk.md) | Frontend Admin SDK or Privileged Client | Critical |
|
|
33
|
+
|
|
34
|
+
### Input and Injection
|
|
35
|
+
|
|
36
|
+
| ID | Title | Default Severity |
|
|
37
|
+
|----|-------|------------------|
|
|
38
|
+
| [TG-INPUT-001](TG-INPUT-001-missing-server-validation.md) | Missing Server-Side Input Validation | High |
|
|
39
|
+
| [TG-INPUT-002](TG-INPUT-002-raw-sql-concatenation.md) | Raw SQL Concatenation | Critical |
|
|
40
|
+
| [TG-INPUT-003](TG-INPUT-003-unsafe-html-or-code-execution.md) | Unsafe HTML or Dynamic Code Execution | High |
|
|
41
|
+
| [TG-INPUT-004](TG-INPUT-004-unrestricted-file-upload.md) | Unrestricted File Upload | High |
|
|
42
|
+
|
|
43
|
+
### Authentication and Authorization
|
|
44
|
+
|
|
45
|
+
| ID | Title | Default Severity |
|
|
46
|
+
|----|-------|------------------|
|
|
47
|
+
| [TG-AUTH-001](TG-AUTH-001-weak-password-storage.md) | Weak Password Storage | Critical |
|
|
48
|
+
| [TG-AUTH-002](TG-AUTH-002-client-only-authorization.md) | Client-Only Authorization | High |
|
|
49
|
+
| [TG-AUTH-003](TG-AUTH-003-missing-object-authorization.md) | Missing Object-Level Authorization (IDOR) | High |
|
|
50
|
+
| [TG-AUTH-004](TG-AUTH-004-insecure-session-cookie.md) | Insecure Session Cookie | High |
|
|
51
|
+
| [TG-AUTH-005](TG-AUTH-005-unsafe-password-reset.md) | Unsafe Password Reset or Account Recovery | High |
|
|
52
|
+
|
|
53
|
+
### Rate Limiting and Resource Abuse
|
|
54
|
+
|
|
55
|
+
| ID | Title | Default Severity |
|
|
56
|
+
|----|-------|------------------|
|
|
57
|
+
| [TG-RATE-001](TG-RATE-001-unlimited-auth-endpoint.md) | Unlimited Authentication Endpoint | High |
|
|
58
|
+
| [TG-RATE-002](TG-RATE-002-unlimited-public-write-endpoint.md) | Unlimited Public Write or Expensive Endpoint | Medium |
|
|
59
|
+
| [TG-RATE-003](TG-RATE-003-unbounded-resource-consumption.md) | Unbounded Resource Consumption | High |
|
|
60
|
+
|
|
61
|
+
### Client Exposure
|
|
62
|
+
|
|
63
|
+
| ID | Title | Default Severity |
|
|
64
|
+
|----|-------|------------------|
|
|
65
|
+
| [TG-CLIENT-001](TG-CLIENT-001-public-production-source-maps.md) | Public Production Source Maps | Medium |
|
|
66
|
+
| [TG-CLIENT-002](TG-CLIENT-002-sensitive-client-bundle-content.md) | Sensitive Client Bundle Content | High |
|
|
67
|
+
|
|
68
|
+
### Platform Hardening
|
|
69
|
+
|
|
70
|
+
| ID | Title | Default Severity |
|
|
71
|
+
|----|-------|------------------|
|
|
72
|
+
| [TG-PLATFORM-001](TG-PLATFORM-001-wildcard-cors-with-credentials.md) | Wildcard CORS With Credentials | High |
|
|
73
|
+
| [TG-PLATFORM-002](TG-PLATFORM-002-missing-security-headers.md) | Missing Security Headers | Medium |
|
|
74
|
+
| [TG-PLATFORM-003](TG-PLATFORM-003-production-stack-trace-exposure.md) | Production Stack Trace or Internal Error Exposure | Medium |
|
|
75
|
+
| [TG-PLATFORM-004](TG-PLATFORM-004-missing-request-size-limits.md) | Missing Request Size Limits | Medium |
|
|
76
|
+
|
|
77
|
+
## Area Mapping for `/TorusGuard check`
|
|
78
|
+
|
|
79
|
+
| Area | Rules |
|
|
80
|
+
|------|-------|
|
|
81
|
+
| `secrets` | TG-SEC-001 … TG-SEC-004 |
|
|
82
|
+
| `database` | TG-DB-001 … TG-DB-003 |
|
|
83
|
+
| `input` | TG-INPUT-001 … TG-INPUT-004 |
|
|
84
|
+
| `auth` | TG-AUTH-001 … TG-AUTH-005 |
|
|
85
|
+
| `rate-limit` | TG-RATE-001 … TG-RATE-003 |
|
|
86
|
+
| `client` | TG-CLIENT-001 … TG-CLIENT-002 |
|
|
87
|
+
| `platform` | TG-PLATFORM-001 … TG-PLATFORM-004 |
|
|
88
|
+
|
|
89
|
+
## Related Documentation
|
|
90
|
+
|
|
91
|
+
- Reference modules: `skills/TorusGuard/references/`
|
|
92
|
+
- Framework guides: `guides/`
|
|
93
|
+
- Example mappings: `examples/vulnerable-react-express/vulnerabilities.md`, `examples/hardened-react-express/fixes.md`
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# TG-AUTH-001: Weak Password Storage
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
Critical
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- User registration and login systems
|
|
8
|
+
- Password reset and credential update flows
|
|
9
|
+
- Legacy account import/migration jobs
|
|
10
|
+
- Identity providers that store local credentials
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Weak password storage enables catastrophic compromise when databases leak through attacks, backups, logs, or insider misuse.
|
|
14
|
+
Plaintext, reversible encryption, or fast unsalted hashes let attackers recover passwords quickly and reuse them across services.
|
|
15
|
+
Secure, adaptive hashing with per-password salt and optional pepper drastically reduces offline cracking feasibility.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Passwords stored as plaintext or encoded forms such as Base64.
|
|
19
|
+
- Use of outdated fast hashes (`MD5`, `SHA1`, bare `SHA256`) for password storage.
|
|
20
|
+
- Same hash value for identical passwords due to missing random salt.
|
|
21
|
+
- Manual cryptography routines instead of vetted password hashing libraries.
|
|
22
|
+
- Logging of raw passwords or hash inputs during authentication workflows.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
import crypto from "crypto";
|
|
27
|
+
|
|
28
|
+
app.post("/api/register", async (req, res) => {
|
|
29
|
+
const email = req.body.email;
|
|
30
|
+
const password = req.body.password;
|
|
31
|
+
|
|
32
|
+
// Fast hash with no salt and no work factor
|
|
33
|
+
const passwordHash = crypto.createHash("sha256").update(password).digest("hex");
|
|
34
|
+
|
|
35
|
+
await db.user.create({
|
|
36
|
+
data: { email, password_hash: passwordHash }
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
res.json({ ok: true });
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Safe Example
|
|
44
|
+
```js
|
|
45
|
+
import argon2 from "argon2";
|
|
46
|
+
|
|
47
|
+
app.post("/api/register", async (req, res) => {
|
|
48
|
+
const email = String(req.body.email || "");
|
|
49
|
+
const password = String(req.body.password || "");
|
|
50
|
+
|
|
51
|
+
if (password.length < 12) {
|
|
52
|
+
return res.status(400).json({ ok: false, error: "Password too short" });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const hash = await argon2.hash(password, {
|
|
56
|
+
type: argon2.argon2id,
|
|
57
|
+
memoryCost: 19456,
|
|
58
|
+
timeCost: 2,
|
|
59
|
+
parallelism: 1
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await db.user.create({
|
|
63
|
+
data: { email, password_hash: hash }
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
res.json({ ok: true });
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
app.post("/api/login", async (req, res) => {
|
|
70
|
+
const user = await db.user.findUnique({ where: { email: req.body.email } });
|
|
71
|
+
if (!user) return res.status(401).json({ ok: false });
|
|
72
|
+
|
|
73
|
+
const valid = await argon2.verify(user.password_hash, String(req.body.password || ""));
|
|
74
|
+
if (!valid) return res.status(401).json({ ok: false });
|
|
75
|
+
|
|
76
|
+
res.json({ ok: true });
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Remediation
|
|
81
|
+
1. Replace insecure password storage with Argon2id, bcrypt, or scrypt using recommended cost factors.
|
|
82
|
+
2. Ensure each password hash includes a unique random salt (handled by modern libraries).
|
|
83
|
+
3. Add optional application-level pepper stored in a secret manager, not in the database.
|
|
84
|
+
4. Remove password values from logs, traces, analytics events, and error telemetry.
|
|
85
|
+
5. Migrate existing hashes using rehash-on-login or controlled reset campaigns.
|
|
86
|
+
6. Periodically tune work factors based on current hardware and latency targets.
|
|
87
|
+
|
|
88
|
+
## Verification
|
|
89
|
+
- Inspect stored credential records and confirm they use adaptive hash formats.
|
|
90
|
+
- Verify identical passwords across test accounts produce different hash outputs.
|
|
91
|
+
- Benchmark login flow to ensure configured cost factors are actually applied.
|
|
92
|
+
- Attempt cracking tests on sample exported hashes to validate resistance assumptions.
|
|
93
|
+
- Review codebase for direct use of fast hash APIs in authentication modules.
|
|
94
|
+
|
|
95
|
+
## False Positives and Exceptions
|
|
96
|
+
- One-way hashes for non-password tokens may look similar but are separate controls.
|
|
97
|
+
- Temporary test fixtures can include static hashes only if isolated from production data paths.
|
|
98
|
+
- External identity providers reduce local password handling scope but do not exempt backup credential paths.
|
|
99
|
+
|
|
100
|
+
## Related Rules
|
|
101
|
+
- [TG-AUTH-005](./TG-AUTH-005-unsafe-password-reset.md)
|
|
102
|
+
- [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
|
|
103
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# TG-AUTH-002: Client-Only Authorization
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Single-page applications with protected routes
|
|
8
|
+
- Mobile apps that hide privileged UI actions
|
|
9
|
+
- APIs serving both user and admin clients
|
|
10
|
+
- Feature-flagged operations with role constraints
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Authorization enforced only in frontend code is not security control, because attackers can bypass the UI and call backend APIs directly.
|
|
14
|
+
If server endpoints trust client-supplied role flags or hidden form fields, privilege escalation becomes trivial.
|
|
15
|
+
Robust authorization must be verified on every sensitive backend action regardless of UI behavior.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Admin checks present in frontend components but absent in backend handlers.
|
|
19
|
+
- API routes that trust `role`, `isAdmin`, or similar flags from request body/query.
|
|
20
|
+
- Hidden buttons/menus used as the only barrier to privileged operations.
|
|
21
|
+
- Use of local storage role values for security decisions.
|
|
22
|
+
- Missing middleware or policy checks around destructive and high-impact endpoints.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
// Frontend blocks non-admin users from seeing delete button
|
|
27
|
+
if (currentUser.role === "admin") {
|
|
28
|
+
showDeleteUserButton();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Backend route does not verify authenticated role
|
|
32
|
+
app.post("/api/admin/delete-user", async (req, res) => {
|
|
33
|
+
const targetUserId = req.body.userId;
|
|
34
|
+
await db.user.delete({ where: { id: targetUserId } });
|
|
35
|
+
res.json({ ok: true });
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```js
|
|
41
|
+
function requireRole(...allowedRoles) {
|
|
42
|
+
return (req, res, next) => {
|
|
43
|
+
const role = req.auth?.role;
|
|
44
|
+
if (!allowedRoles.includes(role)) {
|
|
45
|
+
return res.status(403).json({ ok: false, error: "Forbidden" });
|
|
46
|
+
}
|
|
47
|
+
next();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
app.post("/api/admin/delete-user", requireAuth, requireRole("admin"), async (req, res) => {
|
|
52
|
+
const targetUserId = String(req.body.userId || "");
|
|
53
|
+
if (!/^[a-f0-9-]{36}$/.test(targetUserId)) {
|
|
54
|
+
return res.status(400).json({ ok: false, error: "Invalid user id" });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await db.user.delete({ where: { id: targetUserId } });
|
|
58
|
+
res.json({ ok: true });
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Remediation
|
|
63
|
+
1. Enforce authorization checks on the server for every protected action and resource.
|
|
64
|
+
2. Derive roles/permissions from authenticated server-side identity, not request payload flags.
|
|
65
|
+
3. Implement centralized policy middleware to reduce inconsistent endpoint protection.
|
|
66
|
+
4. Keep frontend role checks for UX only, never as the sole security mechanism.
|
|
67
|
+
5. Add audit logging for privileged operations including actor, target, and outcome.
|
|
68
|
+
6. Write regression tests that call endpoints directly without using the UI.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
- Call privileged endpoints with a non-admin token and verify consistent `403` responses.
|
|
72
|
+
- Remove/hide frontend restrictions in browser devtools and confirm backend still blocks access.
|
|
73
|
+
- Attempt sending forged `isAdmin: true` fields and verify they are ignored.
|
|
74
|
+
- Inspect route registrations to ensure protected middleware is applied universally.
|
|
75
|
+
- Review audit logs for denied authorization attempts.
|
|
76
|
+
|
|
77
|
+
## False Positives and Exceptions
|
|
78
|
+
- Public metadata endpoints may intentionally skip authorization if they contain no sensitive operations or data.
|
|
79
|
+
- Early prototypes often rely on frontend checks; production deployment must not.
|
|
80
|
+
- Internal admin APIs still require authorization controls unless isolated by strong network identity boundaries.
|
|
81
|
+
|
|
82
|
+
## Related Rules
|
|
83
|
+
- [TG-AUTH-003](./TG-AUTH-003-missing-object-authorization.md)
|
|
84
|
+
- [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
|
|
85
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# TG-AUTH-003: Missing Object-Level Authorization (IDOR)
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- APIs that fetch or modify records by ID
|
|
8
|
+
- File and document retrieval endpoints
|
|
9
|
+
- Multi-tenant systems with organization-scoped data
|
|
10
|
+
- Billing, messaging, and profile management resources
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
IDOR occurs when applications expose object identifiers but fail to verify that the requester is allowed to access that specific object.
|
|
14
|
+
Attackers can enumerate or guess IDs to read, modify, or delete other users' resources without needing elevated roles.
|
|
15
|
+
This creates severe confidentiality and integrity breaches, especially in multi-tenant products.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Endpoints reading `:id` or query IDs without ownership or tenant checks.
|
|
19
|
+
- `findUnique`/`getById` calls that do not include current user or tenant constraints.
|
|
20
|
+
- Access to files/records based solely on untrusted identifier parameters.
|
|
21
|
+
- Sequential numeric IDs exposed in URLs with missing authorization guards.
|
|
22
|
+
- Update/delete operations that authenticate user identity but skip object-level policy.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
app.get("/api/invoices/:invoiceId", requireAuth, async (req, res) => {
|
|
27
|
+
const invoiceId = req.params.invoiceId;
|
|
28
|
+
|
|
29
|
+
// Authenticated, but no check that invoice belongs to this user/tenant
|
|
30
|
+
const invoice = await db.invoice.findUnique({
|
|
31
|
+
where: { id: invoiceId }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!invoice) return res.status(404).json({ ok: false });
|
|
35
|
+
res.json({ ok: true, invoice });
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```js
|
|
41
|
+
app.get("/api/invoices/:invoiceId", requireAuth, async (req, res) => {
|
|
42
|
+
const invoiceId = String(req.params.invoiceId || "");
|
|
43
|
+
const userId = req.auth.userId;
|
|
44
|
+
const tenantId = req.auth.tenantId;
|
|
45
|
+
|
|
46
|
+
const invoice = await db.invoice.findFirst({
|
|
47
|
+
where: {
|
|
48
|
+
id: invoiceId,
|
|
49
|
+
tenant_id: tenantId,
|
|
50
|
+
customer_user_id: userId
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!invoice) {
|
|
55
|
+
return res.status(404).json({ ok: false, error: "Not found" });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
res.json({ ok: true, invoice });
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Remediation
|
|
63
|
+
1. Apply object-level authorization checks on every read, update, and delete path.
|
|
64
|
+
2. Scope data queries by authenticated user, tenant, account, or policy context.
|
|
65
|
+
3. Centralize authorization policies so object checks are consistent across endpoints.
|
|
66
|
+
4. Avoid exposing predictable identifiers when not required; consider opaque IDs.
|
|
67
|
+
5. Log access denials and anomalous ID probing attempts for detection.
|
|
68
|
+
6. Add tests that attempt cross-user and cross-tenant access with valid credentials.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
- Authenticate as User A and request User B resources by changing IDs.
|
|
72
|
+
- Confirm unauthorized object access returns `404` or `403` consistently without data leakage.
|
|
73
|
+
- Test update and delete endpoints, not only read endpoints.
|
|
74
|
+
- Validate background jobs and export endpoints enforce tenant/object constraints too.
|
|
75
|
+
- Inspect ORM/database queries for required ownership predicates.
|
|
76
|
+
|
|
77
|
+
## False Positives and Exceptions
|
|
78
|
+
- Public resources intentionally shared across tenants should be explicitly labeled and policy-reviewed.
|
|
79
|
+
- Some administrative roles can access cross-tenant objects, but this must be explicit and auditable.
|
|
80
|
+
- Random UUID usage alone does not remove need for object authorization.
|
|
81
|
+
|
|
82
|
+
## Related Rules
|
|
83
|
+
- [TG-AUTH-002](./TG-AUTH-002-client-only-authorization.md)
|
|
84
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|
|
85
|
+
- [TG-INPUT-002](./TG-INPUT-002-raw-sql-concatenation.md)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# TG-AUTH-004: Insecure Session Cookie Configuration
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- Web applications using cookie-based sessions
|
|
8
|
+
- Authentication gateways and reverse proxies
|
|
9
|
+
- Legacy apps migrating from token storage in local storage
|
|
10
|
+
- SSO callback handlers setting auth cookies
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Session cookies that lack secure attributes can be stolen, replayed, or manipulated by attackers.
|
|
14
|
+
Missing `HttpOnly` enables JavaScript access during XSS, missing `Secure` exposes cookies over unencrypted transport, and weak `SameSite` settings increase CSRF risk.
|
|
15
|
+
Improper domain/path/lifetime settings also expand token exposure across subdomains and long time windows.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Cookies set without `HttpOnly`, `Secure`, or explicit `SameSite`.
|
|
19
|
+
- Session identifiers in URL parameters or local storage instead of hardened cookies.
|
|
20
|
+
- Excessive cookie lifetime for sensitive sessions.
|
|
21
|
+
- Broad cookie domain scopes (`.example.com`) without necessity.
|
|
22
|
+
- Session rotation missing after login, privilege change, or password reset.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
app.post("/api/login", async (req, res) => {
|
|
27
|
+
const sessionId = await createSession(req.body.email, req.body.password);
|
|
28
|
+
if (!sessionId) return res.status(401).json({ ok: false });
|
|
29
|
+
|
|
30
|
+
// Missing critical security attributes
|
|
31
|
+
res.cookie("sid", sessionId, {
|
|
32
|
+
sameSite: "none"
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
res.json({ ok: true });
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Safe Example
|
|
40
|
+
```js
|
|
41
|
+
app.post("/api/login", async (req, res) => {
|
|
42
|
+
const user = await verifyCredentials(req.body.email, req.body.password);
|
|
43
|
+
if (!user) return res.status(401).json({ ok: false });
|
|
44
|
+
|
|
45
|
+
const sessionId = await createSession(user.id);
|
|
46
|
+
res.cookie("sid", sessionId, {
|
|
47
|
+
httpOnly: true,
|
|
48
|
+
secure: true,
|
|
49
|
+
sameSite: "lax",
|
|
50
|
+
path: "/",
|
|
51
|
+
maxAge: 1000 * 60 * 30 // 30 minutes
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
res.json({ ok: true });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
app.post("/api/password/reset/complete", requireAuth, async (req, res) => {
|
|
58
|
+
await invalidateAllSessions(req.auth.userId);
|
|
59
|
+
const rotated = await createSession(req.auth.userId);
|
|
60
|
+
|
|
61
|
+
res.cookie("sid", rotated, {
|
|
62
|
+
httpOnly: true,
|
|
63
|
+
secure: true,
|
|
64
|
+
sameSite: "strict",
|
|
65
|
+
path: "/",
|
|
66
|
+
maxAge: 1000 * 60 * 15
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
res.json({ ok: true });
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Remediation
|
|
74
|
+
1. Set `HttpOnly`, `Secure`, and explicit `SameSite` on all session/auth cookies.
|
|
75
|
+
2. Use HTTPS everywhere; reject insecure origins and mixed-content session transport.
|
|
76
|
+
3. Minimize cookie scope with narrow domain/path and reasonable expiration.
|
|
77
|
+
4. Rotate session IDs on authentication, privilege transitions, and credential recovery.
|
|
78
|
+
5. Invalidate old sessions on logout, password changes, and suspicious activity.
|
|
79
|
+
6. Add CSRF protections compatible with cookie strategy for state-changing requests.
|
|
80
|
+
|
|
81
|
+
## Verification
|
|
82
|
+
- Inspect `Set-Cookie` headers in browser/network tools for required attributes.
|
|
83
|
+
- Attempt JavaScript cookie reads and confirm auth cookies are inaccessible.
|
|
84
|
+
- Test login over HTTP in non-production environments and ensure secure policy behavior.
|
|
85
|
+
- Validate old session IDs stop working after rotation events.
|
|
86
|
+
- Confirm cross-site POST attempts are blocked by SameSite and CSRF controls.
|
|
87
|
+
|
|
88
|
+
## False Positives and Exceptions
|
|
89
|
+
- `SameSite=None` can be valid for specific cross-site SSO flows, but requires `Secure` and additional CSRF controls.
|
|
90
|
+
- Development environments on localhost may need adjusted secure handling; document separation from production settings.
|
|
91
|
+
- Stateless bearer tokens in headers are out of scope for this rule but require equivalent protections.
|
|
92
|
+
|
|
93
|
+
## Related Rules
|
|
94
|
+
- [TG-AUTH-002](./TG-AUTH-002-client-only-authorization.md)
|
|
95
|
+
- [TG-AUTH-005](./TG-AUTH-005-unsafe-password-reset.md)
|
|
96
|
+
- [TG-INPUT-003](./TG-INPUT-003-unsafe-html-or-code-execution.md)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# TG-AUTH-005: Unsafe Password Reset Flow
|
|
2
|
+
|
|
3
|
+
## Severity
|
|
4
|
+
High
|
|
5
|
+
|
|
6
|
+
## Applies To
|
|
7
|
+
- "Forgot password" and account recovery endpoints
|
|
8
|
+
- Email/SMS reset token issuance and verification
|
|
9
|
+
- Self-service credential recovery in web and mobile apps
|
|
10
|
+
- Administrative reset tooling for user accounts
|
|
11
|
+
|
|
12
|
+
## Why It Matters
|
|
13
|
+
Password reset is a high-value account takeover target because it bypasses existing credentials.
|
|
14
|
+
Weak reset token generation, leakage through URLs/logs, missing expiry, and lack of rate limiting can let attackers hijack accounts at scale.
|
|
15
|
+
Unsafe reset completion logic can also leave existing sessions active, preserving attacker access.
|
|
16
|
+
|
|
17
|
+
## What TorusGuard Looks For
|
|
18
|
+
- Predictable reset tokens or short numeric codes without brute-force protection.
|
|
19
|
+
- Reset tokens stored in plaintext and compared directly.
|
|
20
|
+
- Missing token expiry, single-use enforcement, or account binding checks.
|
|
21
|
+
- User enumeration through distinct responses for existing vs non-existing emails.
|
|
22
|
+
- Failure to invalidate active sessions after successful password reset.
|
|
23
|
+
|
|
24
|
+
## Unsafe Example
|
|
25
|
+
```js
|
|
26
|
+
app.post("/api/password/forgot", async (req, res) => {
|
|
27
|
+
const user = await db.user.findUnique({ where: { email: req.body.email } });
|
|
28
|
+
if (!user) return res.status(404).json({ ok: false, error: "No account found" });
|
|
29
|
+
|
|
30
|
+
const token = Math.floor(Math.random() * 1000000).toString();
|
|
31
|
+
await db.password_reset.create({
|
|
32
|
+
data: { user_id: user.id, token, expires_at: null, used: false }
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await sendMail(user.email, `Reset link: https://app.example/reset?token=${token}`);
|
|
36
|
+
res.json({ ok: true });
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Safe Example
|
|
41
|
+
```js
|
|
42
|
+
import crypto from "crypto";
|
|
43
|
+
|
|
44
|
+
app.post("/api/password/forgot", async (req, res) => {
|
|
45
|
+
const email = String(req.body.email || "").toLowerCase();
|
|
46
|
+
const user = await db.user.findUnique({ where: { email } });
|
|
47
|
+
|
|
48
|
+
// Always return generic response to prevent user enumeration
|
|
49
|
+
if (user) {
|
|
50
|
+
const rawToken = crypto.randomBytes(32).toString("hex");
|
|
51
|
+
const tokenHash = crypto.createHash("sha256").update(rawToken).digest("hex");
|
|
52
|
+
const expiresAt = new Date(Date.now() + 15 * 60 * 1000);
|
|
53
|
+
|
|
54
|
+
await db.password_reset.create({
|
|
55
|
+
data: { user_id: user.id, token_hash: tokenHash, expires_at: expiresAt, used: false }
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await sendMail(user.email, `Reset link: https://app.example/reset?token=${rawToken}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
res.json({ ok: true, message: "If an account exists, a reset email has been sent." });
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
app.post("/api/password/reset", async (req, res) => {
|
|
65
|
+
const rawToken = String(req.body.token || "");
|
|
66
|
+
const newPassword = String(req.body.newPassword || "");
|
|
67
|
+
const tokenHash = crypto.createHash("sha256").update(rawToken).digest("hex");
|
|
68
|
+
|
|
69
|
+
const record = await db.password_reset.findFirst({
|
|
70
|
+
where: { token_hash: tokenHash, used: false, expires_at: { gt: new Date() } }
|
|
71
|
+
});
|
|
72
|
+
if (!record) return res.status(400).json({ ok: false, error: "Invalid or expired token" });
|
|
73
|
+
|
|
74
|
+
await setUserPassword(record.user_id, newPassword);
|
|
75
|
+
await db.password_reset.update({ where: { id: record.id }, data: { used: true } });
|
|
76
|
+
await invalidateAllSessions(record.user_id);
|
|
77
|
+
res.json({ ok: true });
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Remediation
|
|
82
|
+
1. Generate cryptographically strong, high-entropy reset tokens and store only token hashes.
|
|
83
|
+
2. Enforce short token lifetime, one-time use, and strict account binding.
|
|
84
|
+
3. Apply rate limits and anomaly detection on reset request and token verification endpoints.
|
|
85
|
+
4. Return generic responses for reset initiation to prevent account enumeration.
|
|
86
|
+
5. Invalidate active sessions and recovery artifacts after successful password reset.
|
|
87
|
+
6. Require strong new passwords and optionally step-up verification for risky reset attempts.
|
|
88
|
+
|
|
89
|
+
## Verification
|
|
90
|
+
- Request reset for known and unknown emails; verify indistinguishable responses.
|
|
91
|
+
- Attempt brute-force token guesses and confirm lockout/rate-limit behavior.
|
|
92
|
+
- Reuse a consumed token and confirm it fails.
|
|
93
|
+
- Use an expired token and verify rejection path.
|
|
94
|
+
- Confirm all existing sessions are invalidated after reset completion.
|
|
95
|
+
|
|
96
|
+
## False Positives and Exceptions
|
|
97
|
+
- Enterprise SSO environments may delegate password reset externally; local reset flows should be disabled or strongly gated.
|
|
98
|
+
- Short OTP codes can be acceptable when combined with strict attempt limits, device binding, and very short expiry.
|
|
99
|
+
- Manual support resets need controlled operator workflows and audit trails.
|
|
100
|
+
|
|
101
|
+
## Related Rules
|
|
102
|
+
- [TG-AUTH-001](./TG-AUTH-001-weak-password-storage.md)
|
|
103
|
+
- [TG-AUTH-004](./TG-AUTH-004-insecure-session-cookie.md)
|
|
104
|
+
- [TG-INPUT-001](./TG-INPUT-001-missing-server-validation.md)
|