torusguard 1.3.0 → 1.3.2
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 +113 -9
- 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/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 +62 -20
- 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/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 +339 -0
- package/.torusguard/scripts/audit_runner.py +550 -0
- package/.torusguard/scripts/diff_guard.py +52 -4
- package/.torusguard/scripts/finding_scorer.py +58 -0
- package/.torusguard/scripts/harden_runner.py +375 -0
- package/.torusguard/scripts/html_reporter.py +25 -10
- package/.torusguard/scripts/manifest_builder.py +2 -0
- package/.torusguard/scripts/memory_engine.py +4 -0
- package/.torusguard/scripts/recheck_runner.py +221 -0
- package/.torusguard/scripts/recipes_runner.py +130 -0
- package/.torusguard/scripts/run_manager.py +17 -5
- package/.torusguard/skills/torusguard/SKILL.md +42 -42
- package/.torusguard/skills/torusguard/bootstrap.py +149 -70
- 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 +70 -33
- package/bin/torusguard.js +92 -22
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/bootstrap.py +147 -68
- package/skills/torusguard/payload/.manifest.json +113 -9
- 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/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/scripts/apply_runner.py +339 -0
- package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +52 -4
- package/skills/torusguard/payload/scripts/finding_scorer.py +58 -0
- package/skills/torusguard/payload/scripts/harden_runner.py +375 -0
- package/skills/torusguard/payload/scripts/html_reporter.py +25 -10
- package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
- package/skills/torusguard/payload/scripts/memory_engine.py +4 -0
- 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/run_manager.py +17 -5
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +147 -68
|
@@ -15,12 +15,12 @@ from pathlib import Path
|
|
|
15
15
|
# Ensure UTF-8 stdout/stderr on Windows consoles
|
|
16
16
|
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
17
17
|
try:
|
|
18
|
-
sys.stdout
|
|
18
|
+
getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
|
|
19
19
|
except Exception:
|
|
20
20
|
pass
|
|
21
21
|
if sys.stderr and hasattr(sys.stderr, "reconfigure"):
|
|
22
22
|
try:
|
|
23
|
-
sys.stderr
|
|
23
|
+
getattr(sys.stderr, "reconfigure")(encoding="utf-8", errors="replace")
|
|
24
24
|
except Exception:
|
|
25
25
|
pass
|
|
26
26
|
|
|
@@ -57,12 +57,85 @@ def find_project_root(start_dir=None):
|
|
|
57
57
|
return current
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
import re
|
|
61
|
+
import unicodedata
|
|
62
|
+
|
|
63
|
+
ANSI_REGEX = re.compile(r'\033\[[0-9;]*m')
|
|
64
|
+
|
|
65
|
+
def get_visual_width(text: str) -> int:
|
|
66
|
+
"""Calculate the printable display width of a string (ANSI and emoji aware)."""
|
|
67
|
+
clean = ANSI_REGEX.sub('', text)
|
|
68
|
+
width = 0
|
|
69
|
+
for ch in clean:
|
|
70
|
+
ea = unicodedata.east_asian_width(ch)
|
|
71
|
+
if ea in ('W', 'F'):
|
|
72
|
+
width += 2
|
|
73
|
+
elif ord(ch) >= 0x1F300:
|
|
74
|
+
width += 2
|
|
75
|
+
else:
|
|
76
|
+
width += 1
|
|
77
|
+
return width
|
|
78
|
+
|
|
79
|
+
def truncate_visual(text: str, max_w: int = 67) -> str:
|
|
80
|
+
"""Truncate text visually without breaking ANSI escape codes."""
|
|
81
|
+
if get_visual_width(text) <= max_w:
|
|
82
|
+
return text
|
|
83
|
+
out, curr_w, in_ansi, ansi_buf = [], 0, False, ''
|
|
84
|
+
for ch in text:
|
|
85
|
+
if ch == '\033':
|
|
86
|
+
in_ansi = True
|
|
87
|
+
ansi_buf = ch
|
|
88
|
+
continue
|
|
89
|
+
if in_ansi:
|
|
90
|
+
ansi_buf += ch
|
|
91
|
+
if ch == 'm':
|
|
92
|
+
in_ansi = False
|
|
93
|
+
out.append(ansi_buf)
|
|
94
|
+
continue
|
|
95
|
+
ea = unicodedata.east_asian_width(ch)
|
|
96
|
+
cw = 2 if ea in ('W', 'F') or ord(ch) >= 0x1F300 else 1
|
|
97
|
+
if curr_w + cw > max_w - 3:
|
|
98
|
+
out.append('...')
|
|
99
|
+
break
|
|
100
|
+
out.append(ch)
|
|
101
|
+
curr_w += cw
|
|
102
|
+
return ''.join(out)
|
|
103
|
+
|
|
104
|
+
def card_line(content: str, max_w: int = 67, border: str = "│", border_color: str = CYAN) -> str:
|
|
105
|
+
"""Pad content so the card is exactly 75 visual columns total width."""
|
|
106
|
+
trunc = truncate_visual(content, max_w)
|
|
107
|
+
vis = get_visual_width(trunc)
|
|
108
|
+
pad = " " * max(0, max_w - vis)
|
|
109
|
+
return f" {border_color}{border}{RESET} {trunc}{pad} {border_color}{border}{RESET}"
|
|
110
|
+
|
|
111
|
+
def card_border_top(title: str = "", border_color: str = CYAN, double: bool = False) -> str:
|
|
112
|
+
left = "╔" if double else "┌"
|
|
113
|
+
right = "╗" if double else "┐"
|
|
114
|
+
h = "═" if double else "─"
|
|
115
|
+
if title:
|
|
116
|
+
vis = get_visual_width(title)
|
|
117
|
+
rem = max(0, 71 - 3 - vis - 1)
|
|
118
|
+
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
119
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
120
|
+
|
|
121
|
+
def card_border_bottom(border_color: str = CYAN, double: bool = False) -> str:
|
|
122
|
+
left = "╚" if double else "└"
|
|
123
|
+
right = "╝" if double else "┘"
|
|
124
|
+
h = "═" if double else "─"
|
|
125
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
126
|
+
|
|
127
|
+
def card_divider(border_color: str = CYAN, double: bool = False) -> str:
|
|
128
|
+
left = "╠" if double else "├"
|
|
129
|
+
right = "╣" if double else "┤"
|
|
130
|
+
h = "═" if double else "─"
|
|
131
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
132
|
+
|
|
60
133
|
def print_header():
|
|
61
134
|
"""Print the branded TorusGuard header card."""
|
|
62
135
|
print(f"""
|
|
63
136
|
{CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
|
|
64
137
|
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
65
|
-
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}
|
|
138
|
+
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}v1.3.0{RESET} {CYAN}│{RESET}
|
|
66
139
|
{CYAN}│{RESET} {DIM}Autonomous Security Engine for AI-Built Applications{RESET} {CYAN}│{RESET}
|
|
67
140
|
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
68
141
|
{CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
|
|
@@ -71,81 +144,71 @@ def print_header():
|
|
|
71
144
|
|
|
72
145
|
def print_step_1_assets(file_count):
|
|
73
146
|
"""Print the enhanced Step 1 asset unpacking card."""
|
|
74
|
-
print(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
""")
|
|
147
|
+
print(card_border_top("Step 1/3 ─── Unpacking Governance Assets"))
|
|
148
|
+
print(card_line(""))
|
|
149
|
+
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}71 rules across 11 families{RESET}"))
|
|
150
|
+
print(card_line(f"{GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET}"))
|
|
151
|
+
print(card_line(f"{GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET}"))
|
|
152
|
+
print(card_line(f"{GREEN}✔{RESET} Workflow templates {DIM}11 slash commands{RESET}"))
|
|
153
|
+
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}10 security guides{RESET}"))
|
|
154
|
+
print(card_line(""))
|
|
155
|
+
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked{RESET}"))
|
|
156
|
+
print(card_border_bottom())
|
|
85
157
|
|
|
86
158
|
|
|
87
159
|
def print_step_2_profile(detected_stack=None):
|
|
88
160
|
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
161
|
+
print(card_border_top("Step 2/3 ─── Security Profile & Coverage"))
|
|
162
|
+
print(card_line(""))
|
|
163
|
+
print(card_line(f"{BOLD}Rule Families:{RESET}"))
|
|
164
|
+
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety"))
|
|
165
|
+
print(card_line(f" {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication"))
|
|
166
|
+
print(card_line(f" {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection"))
|
|
167
|
+
print(card_line(f" {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless"))
|
|
168
|
+
print(card_line(f" {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net"))
|
|
169
|
+
print(card_line(f" {YELLOW}TG-BIZ{RESET} Business Logic"))
|
|
170
|
+
print(card_line(""))
|
|
171
|
+
print(card_line(f"{BOLD}Supported Stacks:{RESET}"))
|
|
172
|
+
print(card_line(f" {GREEN}Python{RESET} Django · FastAPI · Flask · DRF · SQLAlchemy"))
|
|
173
|
+
print(card_line(f" {GREEN}Node.js{RESET} Next.js · Express · React · Supabase · Firebase"))
|
|
174
|
+
print(card_line(""))
|
|
89
175
|
if detected_stack and detected_stack.get("framework") and detected_stack.get("framework") != "None":
|
|
90
176
|
fw = str(detected_stack.get("framework"))
|
|
91
177
|
lang = str(detected_stack.get("language", ""))
|
|
92
|
-
|
|
93
|
-
pad = " " * max(0, 66 - len(label))
|
|
94
|
-
status_line = f" {CYAN}│{RESET} {GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}{pad}{CYAN}│{RESET}"
|
|
178
|
+
print(card_line(f"{GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}"))
|
|
95
179
|
else:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
print(f""" {CYAN}┌─ {BOLD}Step 2/3{RESET} {CYAN}──────────────────── {WHITE}Security Profile & Coverage{RESET} {CYAN}────────┐{RESET}
|
|
99
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
100
|
-
{CYAN}│{RESET} {BOLD}Rule Families:{RESET} {CYAN}│{RESET}
|
|
101
|
-
{CYAN}│{RESET} {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety {CYAN}│{RESET}
|
|
102
|
-
{CYAN}│{RESET} {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication {CYAN}│{RESET}
|
|
103
|
-
{CYAN}│{RESET} {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection {CYAN}│{RESET}
|
|
104
|
-
{CYAN}│{RESET} {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless {CYAN}│{RESET}
|
|
105
|
-
{CYAN}│{RESET} {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net {CYAN}│{RESET}
|
|
106
|
-
{CYAN}│{RESET} {YELLOW}TG-BIZ{RESET} Business Logic {CYAN}│{RESET}
|
|
107
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
108
|
-
{CYAN}│{RESET} {BOLD}Supported Stacks:{RESET} {CYAN}│{RESET}
|
|
109
|
-
{CYAN}│{RESET} {GREEN}Python{RESET} Django {DIM}·{RESET} FastAPI {DIM}·{RESET} Flask {DIM}·{RESET} DRF {DIM}·{RESET} SQLAlchemy {CYAN}│{RESET}
|
|
110
|
-
{CYAN}│{RESET} {GREEN}Node.js{RESET} Next.js {DIM}·{RESET} Express {DIM}·{RESET} React {DIM}·{RESET} Supabase {DIM}·{RESET} Firebase {CYAN}│{RESET}
|
|
111
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
112
|
-
{status_line}
|
|
113
|
-
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
114
|
-
""")
|
|
180
|
+
print(card_line(f"{DIM}ℹ Stack auto-detected on first /torusguard-audit run{RESET}"))
|
|
181
|
+
print(card_border_bottom())
|
|
115
182
|
|
|
116
183
|
|
|
117
184
|
def print_step_3_bridges(registered_ides):
|
|
118
185
|
"""Print the IDE command registration card."""
|
|
119
|
-
|
|
186
|
+
print(card_border_top("Step 3/3 ─── AI IDE Command Registration"))
|
|
187
|
+
print(card_line(""))
|
|
120
188
|
for r in registered_ides:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
print(
|
|
124
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
125
|
-
{lines} {CYAN}│{RESET} {CYAN}│{RESET}
|
|
126
|
-
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
127
|
-
""")
|
|
189
|
+
print(card_line(f"{GREEN}✔{RESET} {r}"))
|
|
190
|
+
print(card_line(""))
|
|
191
|
+
print(card_border_bottom())
|
|
128
192
|
|
|
129
193
|
|
|
130
194
|
def print_success_card():
|
|
131
195
|
"""Print the final success card with next steps."""
|
|
132
|
-
print(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
""")
|
|
196
|
+
print(card_border_top("", border_color=GREEN, double=True))
|
|
197
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
198
|
+
print(card_line(f"{GREEN}{BOLD}✅ WORKSPACE INITIALIZED SUCCESSFULLY{RESET}", border="║", border_color=GREEN))
|
|
199
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
200
|
+
print(card_divider(border_color=GREEN, double=True))
|
|
201
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
202
|
+
print(card_line(f"{BOLD}Next Steps:{RESET}", border="║", border_color=GREEN))
|
|
203
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
204
|
+
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard-audit{RESET} or {WHITE}/torusguard{RESET}", border="║", border_color=GREEN))
|
|
205
|
+
print(card_line(f" {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET}", border="║", border_color=GREEN))
|
|
206
|
+
print(card_line(f" {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET}", border="║", border_color=GREEN))
|
|
207
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
208
|
+
print(card_line(f"{DIM}Docs{RESET} {CYAN}https://github.com/githubmofo/TorusGuard{RESET}", border="║", border_color=GREEN))
|
|
209
|
+
print(card_line(f"{DIM}NPM{RESET} {CYAN}https://npmjs.com/package/torusguard{RESET}", border="║", border_color=GREEN))
|
|
210
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
211
|
+
print(card_border_bottom(border_color=GREEN, double=True))
|
|
149
212
|
|
|
150
213
|
|
|
151
214
|
def print_already_initialized(target_root, cfg):
|
|
@@ -157,7 +220,7 @@ def print_already_initialized(target_root, cfg):
|
|
|
157
220
|
|
|
158
221
|
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
159
222
|
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
160
|
-
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '1.
|
|
223
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '1.3.0')}{RESET}
|
|
161
224
|
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
162
225
|
|
|
163
226
|
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
@@ -358,23 +421,39 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
358
421
|
3. Follow the phase execution steps defined in the workflow.
|
|
359
422
|
"""
|
|
360
423
|
|
|
361
|
-
# Ensure .agent/workflows and .
|
|
424
|
+
# Ensure .agents/workflows, .agents/skills, .agent/workflows, and .agent/skills are created
|
|
362
425
|
dest_workflow_dirs = []
|
|
363
|
-
if (target_root / ".agents").exists():
|
|
364
|
-
agents_wf = target_root / ".agents" / "workflows"
|
|
365
|
-
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
366
|
-
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
367
|
-
dest_workflow_dirs.append(agents_wf)
|
|
368
|
-
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
369
426
|
|
|
427
|
+
# 1. Antigravity / Gemini (.agents/)
|
|
428
|
+
agents_wf = target_root / ".agents" / "workflows"
|
|
429
|
+
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
430
|
+
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
431
|
+
dest_workflow_dirs.append(agents_wf)
|
|
432
|
+
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
433
|
+
|
|
434
|
+
# 2. Tribunal Agent Kit (.agent/)
|
|
370
435
|
agent_wf = target_root / ".agent" / "workflows"
|
|
371
436
|
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
372
437
|
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
373
438
|
dest_workflow_dirs.append(agent_wf)
|
|
374
439
|
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
375
440
|
|
|
441
|
+
# Unpack Skills into .agents/skills and .agent/skills for full IDE resolution
|
|
442
|
+
src_skills = torusguard_target / "skills"
|
|
443
|
+
if src_skills.is_dir():
|
|
444
|
+
for dest_base in [target_root / ".agents" / "skills", target_root / ".agent" / "skills"]:
|
|
445
|
+
dest_base.mkdir(parents=True, exist_ok=True)
|
|
446
|
+
for skill_dir in src_skills.iterdir():
|
|
447
|
+
if skill_dir.is_dir():
|
|
448
|
+
target_skill_dir = dest_base / skill_dir.name
|
|
449
|
+
if not target_skill_dir.exists():
|
|
450
|
+
try:
|
|
451
|
+
shutil.copytree(skill_dir, target_skill_dir)
|
|
452
|
+
except Exception:
|
|
453
|
+
pass
|
|
454
|
+
|
|
376
455
|
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
377
|
-
# unlock and register all
|
|
456
|
+
# unlock and register all individual slash commands
|
|
378
457
|
if full_commands:
|
|
379
458
|
src_wf = torusguard_target / "workflows"
|
|
380
459
|
if src_wf.is_dir():
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { clientConfig } from './config';
|
|
3
|
+
|
|
4
|
+
// TG-DB-001: SQL query construction in frontend (never do this)
|
|
5
|
+
function buildSearchQuery(email) {
|
|
6
|
+
return `SELECT id, email FROM users WHERE email LIKE '%${email}%'`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// TG-DB-003: Documented anti-pattern — Prisma must never run in browser
|
|
10
|
+
// import { PrismaClient } from '@prisma/client'; // FORBIDDEN in client
|
|
11
|
+
|
|
12
|
+
export default function App() {
|
|
13
|
+
const [email, setEmail] = useState('');
|
|
14
|
+
const [password, setPassword] = useState('');
|
|
15
|
+
const [bio, setBio] = useState('<img src=x onerror=alert(1)>');
|
|
16
|
+
const [userId, setUserId] = useState('1');
|
|
17
|
+
const [isAdmin] = useState(localStorage.getItem('role') === 'admin'); // TG-AUTH-002
|
|
18
|
+
const [message, setMessage] = useState('');
|
|
19
|
+
|
|
20
|
+
async function login(e) {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
const res = await fetch('/api/login', {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: { 'Content-Type': 'application/json' },
|
|
25
|
+
credentials: 'include',
|
|
26
|
+
body: JSON.stringify({ email, password }),
|
|
27
|
+
});
|
|
28
|
+
const data = await res.json();
|
|
29
|
+
// TG-CLIENT-002: Sensitive console logging
|
|
30
|
+
console.log('Login token:', data.token, 'config:', clientConfig);
|
|
31
|
+
setMessage(JSON.stringify(data));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function fetchUser() {
|
|
35
|
+
const res = await fetch(`/api/users/${userId}`);
|
|
36
|
+
setMessage(await res.text());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div style={{ maxWidth: 560, margin: '2rem auto', fontFamily: 'sans-serif' }}>
|
|
41
|
+
<h1>Vulnerable Demo</h1>
|
|
42
|
+
<p style={{ color: 'crimson' }}>Intentionally insecure — localhost lab only</p>
|
|
43
|
+
|
|
44
|
+
<form onSubmit={login}>
|
|
45
|
+
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
|
|
46
|
+
<input value={password} onChange={(e) => setPassword(e.target.value)} placeholder="password" type="password" />
|
|
47
|
+
<button type="submit">Login</button>
|
|
48
|
+
</form>
|
|
49
|
+
|
|
50
|
+
<p>Frontend SQL preview: {buildSearchQuery(email)}</p>
|
|
51
|
+
|
|
52
|
+
{/* TG-INPUT-003: Unsafe HTML rendering */}
|
|
53
|
+
<div dangerouslySetInnerHTML={{ __html: bio }} />
|
|
54
|
+
|
|
55
|
+
<button onClick={fetchUser}>Fetch user (IDOR demo)</button>
|
|
56
|
+
|
|
57
|
+
{/* TG-AUTH-002: Client-only admin gate */}
|
|
58
|
+
{isAdmin && <section><h2>Admin Panel</h2><p>Visible if localStorage role=admin — not real security</p></section>}
|
|
59
|
+
|
|
60
|
+
{message && <pre>{message}</pre>}
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const cors = require('cors');
|
|
3
|
+
const jwt = require('jsonwebtoken');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
const PORT = 3001;
|
|
7
|
+
|
|
8
|
+
// TG-SEC-001: Hardcoded JWT secret
|
|
9
|
+
const JWT_SECRET = 'FAKE_DEMO_JWT_SECRET_NOT_FOR_PRODUCTION';
|
|
10
|
+
|
|
11
|
+
// TG-PLATFORM-001: Wildcard CORS with credentials
|
|
12
|
+
app.use(cors({ origin: '*', credentials: true }));
|
|
13
|
+
|
|
14
|
+
// TG-PLATFORM-004: No explicit JSON body size limit
|
|
15
|
+
app.use(express.json());
|
|
16
|
+
|
|
17
|
+
const users = [
|
|
18
|
+
{ id: '1', email: 'alice@demo.local', password: 'password123', name: 'Alice' },
|
|
19
|
+
{ id: '2', email: 'bob@demo.local', password: 'secret456', name: 'Bob' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
// TG-RATE-001: No rate limit on login
|
|
23
|
+
// TG-AUTH-001: Plaintext password comparison
|
|
24
|
+
// TG-SEC-004: Logs sensitive data
|
|
25
|
+
// TG-AUTH-004: Insecure cookie (no httpOnly/Secure/SameSite)
|
|
26
|
+
app.post('/api/login', (req, res) => {
|
|
27
|
+
const { email, password } = req.body;
|
|
28
|
+
console.log('Login attempt:', { email, password }); // TG-SEC-004
|
|
29
|
+
const user = users.find((u) => u.email === email && u.password === password);
|
|
30
|
+
if (!user) return res.status(401).json({ error: 'User not found' }); // enumeration
|
|
31
|
+
const token = jwt.sign({ id: user.id }, JWT_SECRET);
|
|
32
|
+
res.cookie('token', token);
|
|
33
|
+
res.json({ message: 'ok', token, user });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// TG-AUTH-003: IDOR — no ownership check
|
|
37
|
+
app.get('/api/users/:id', (req, res) => {
|
|
38
|
+
const user = users.find((u) => u.id === req.params.id);
|
|
39
|
+
if (!user) return res.status(404).json({ error: 'Not found' });
|
|
40
|
+
res.json(user);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// TG-INPUT-002: SQL concatenation (simulated query string)
|
|
44
|
+
// TG-RATE-003: Unbounded results
|
|
45
|
+
app.get('/api/search', (req, res) => {
|
|
46
|
+
const q = req.query.q || '';
|
|
47
|
+
const fakeSql = `SELECT * FROM users WHERE email LIKE '%${q}%'`;
|
|
48
|
+
const results = users.filter((u) => u.email.includes(q));
|
|
49
|
+
res.json({ query: fakeSql, results });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// TG-INPUT-001: No validation
|
|
53
|
+
// TG-RATE-002: Unlimited contact endpoint
|
|
54
|
+
app.post('/api/contact', (req, res) => {
|
|
55
|
+
res.json({ received: req.body });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// TG-RATE-002: Unlimited AI endpoint
|
|
59
|
+
app.post('/api/ai', (req, res) => {
|
|
60
|
+
res.json({ reply: 'demo', prompt: req.body.prompt });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// TG-INPUT-004: Unrestricted upload (stub)
|
|
64
|
+
app.post('/api/upload', (req, res) => {
|
|
65
|
+
res.json({ saved: req.body.filename });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// TG-AUTH-005: Unsafe password reset
|
|
69
|
+
app.post('/api/reset', (req, res) => {
|
|
70
|
+
const { email } = req.body;
|
|
71
|
+
const user = users.find((u) => u.email === email);
|
|
72
|
+
if (!user) return res.status(404).json({ error: 'Email not registered' }); // enumeration
|
|
73
|
+
const token = `reset-${user.id}-12345`; // predictable
|
|
74
|
+
res.json({ resetToken: token });
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
app.use((err, req, res, next) => {
|
|
78
|
+
// TG-PLATFORM-003: Stack trace exposed
|
|
79
|
+
res.status(500).json({ error: err.message, stack: err.stack });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
app.listen(PORT, () => console.log(`Vulnerable demo server http://localhost:${PORT}`));
|