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.
Files changed (378) hide show
  1. package/.torusguard/.manifest.json +113 -9
  2. package/.torusguard/rules/README.md +93 -62
  3. package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
  4. package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
  5. package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
  6. package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
  7. package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
  8. package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
  9. package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  10. package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
  11. package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
  12. package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
  13. package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  14. package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
  15. package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  16. package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  17. package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  18. package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  19. package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  20. package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  21. package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
  22. package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  23. package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  24. package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  25. package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  26. package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  27. package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
  28. package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
  29. package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
  30. package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
  31. package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
  32. package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
  33. package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
  34. package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
  35. package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
  36. package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
  37. package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  38. package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
  39. package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
  40. package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
  41. package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  42. package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
  43. package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  44. package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  45. package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  46. package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  47. package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  48. package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  49. package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
  50. package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  51. package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  52. package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  53. package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  54. package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  55. package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
  56. package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
  57. package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
  58. package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
  59. package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
  60. package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
  61. package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
  62. package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
  63. package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
  64. package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
  65. package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
  66. package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
  67. package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
  68. package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
  69. package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
  70. package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
  71. package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
  72. package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
  73. package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
  74. package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
  75. package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
  76. package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
  77. package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
  78. package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
  79. package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
  80. package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
  81. package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
  82. package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
  83. package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
  84. package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
  85. package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
  86. package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
  87. package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
  88. package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
  89. package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
  90. package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
  91. package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
  92. package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
  93. package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
  94. package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
  95. package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
  96. package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
  97. package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
  98. package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
  99. package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
  100. package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
  101. package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
  102. package/.torusguard/runs/report-latest.html +62 -20
  103. package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
  104. package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
  105. package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
  106. package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
  107. package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
  108. package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
  109. package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
  110. package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
  111. package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
  112. package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
  113. package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
  114. package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
  115. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
  116. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
  117. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
  118. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
  119. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
  120. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
  121. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
  122. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
  123. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
  124. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
  125. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
  126. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
  127. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
  128. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
  129. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
  130. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
  131. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
  132. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
  133. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
  134. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
  135. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
  136. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
  137. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
  138. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
  139. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
  140. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
  141. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
  142. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
  143. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
  144. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
  145. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
  146. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
  147. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
  148. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
  149. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
  150. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
  151. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
  152. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
  153. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
  154. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
  155. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
  156. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
  157. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
  158. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
  159. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
  160. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
  161. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
  162. package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
  163. package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
  164. package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
  165. package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
  166. package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
  167. package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
  168. package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
  169. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
  170. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
  171. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
  172. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
  173. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
  174. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
  175. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
  176. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
  177. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
  178. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
  179. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
  180. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
  181. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
  182. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
  183. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
  184. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
  185. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
  186. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
  187. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
  188. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
  189. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
  190. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
  191. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
  192. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
  193. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
  194. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
  195. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
  196. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
  197. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
  198. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
  199. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
  200. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
  201. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
  202. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
  203. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
  204. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
  205. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
  206. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
  207. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
  208. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
  209. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
  210. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
  211. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
  212. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
  213. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
  214. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
  215. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
  216. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
  217. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
  218. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
  219. package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
  220. package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
  221. package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
  222. package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
  223. package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
  224. package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
  225. package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
  226. package/.torusguard/runs/run-20260908-115240-audit/summary.md +5 -0
  227. package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
  228. package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
  229. package/.torusguard/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
  230. package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
  231. package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
  232. package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
  233. package/.torusguard/scripts/apply_runner.py +339 -0
  234. package/.torusguard/scripts/audit_runner.py +550 -0
  235. package/.torusguard/scripts/diff_guard.py +52 -4
  236. package/.torusguard/scripts/finding_scorer.py +58 -0
  237. package/.torusguard/scripts/harden_runner.py +375 -0
  238. package/.torusguard/scripts/html_reporter.py +25 -10
  239. package/.torusguard/scripts/manifest_builder.py +2 -0
  240. package/.torusguard/scripts/memory_engine.py +4 -0
  241. package/.torusguard/scripts/recheck_runner.py +221 -0
  242. package/.torusguard/scripts/recipes_runner.py +130 -0
  243. package/.torusguard/scripts/run_manager.py +17 -5
  244. package/.torusguard/skills/torusguard/SKILL.md +42 -42
  245. package/.torusguard/skills/torusguard/bootstrap.py +149 -70
  246. package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
  247. package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
  248. package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
  249. package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
  250. package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
  251. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
  252. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
  253. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
  254. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
  255. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
  256. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
  257. package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
  258. package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
  259. package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
  260. package/README.md +70 -33
  261. package/bin/torusguard.js +92 -22
  262. package/package.json +1 -1
  263. package/skills/torusguard/SKILL.md +42 -42
  264. package/skills/torusguard/bootstrap.py +147 -68
  265. package/skills/torusguard/payload/.manifest.json +113 -9
  266. package/skills/torusguard/payload/rules/README.md +93 -62
  267. package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
  268. package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
  269. package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
  270. package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
  271. package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
  272. package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
  273. package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  274. package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
  275. package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
  276. package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
  277. package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  278. package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
  279. package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  280. package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  281. package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  282. package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  283. package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  284. package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  285. package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
  286. package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  287. package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  288. package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  289. package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  290. package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  291. package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
  292. package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
  293. package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
  294. package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
  295. package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
  296. package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
  297. package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
  298. package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
  299. package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
  300. package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
  301. package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
  302. package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
  303. package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
  304. package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
  305. package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
  306. package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
  307. package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
  308. package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
  309. package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
  310. package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
  311. package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
  312. package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
  313. package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
  314. package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
  315. package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
  316. package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
  317. package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
  318. package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
  319. package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
  320. package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
  321. package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
  322. package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
  323. package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
  324. package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
  325. package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
  326. package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
  327. package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
  328. package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
  329. package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
  330. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
  331. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
  332. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
  333. package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
  334. package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
  335. package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
  336. package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
  337. package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
  338. package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
  339. package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
  340. package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
  341. package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
  342. package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
  343. package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
  344. package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
  345. package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
  346. package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
  347. package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
  348. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
  349. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
  350. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
  351. package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
  352. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
  353. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
  354. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
  355. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
  356. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
  357. package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
  358. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
  359. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
  360. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
  361. package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
  362. package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
  363. package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
  364. package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
  365. package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
  366. package/skills/torusguard/payload/scripts/apply_runner.py +339 -0
  367. package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
  368. package/skills/torusguard/payload/scripts/diff_guard.py +52 -4
  369. package/skills/torusguard/payload/scripts/finding_scorer.py +58 -0
  370. package/skills/torusguard/payload/scripts/harden_runner.py +375 -0
  371. package/skills/torusguard/payload/scripts/html_reporter.py +25 -10
  372. package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
  373. package/skills/torusguard/payload/scripts/memory_engine.py +4 -0
  374. package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
  375. package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
  376. package/skills/torusguard/payload/scripts/run_manager.py +17 -5
  377. package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
  378. 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.reconfigure(encoding="utf-8", errors="replace")
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.reconfigure(encoding="utf-8", errors="replace")
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}v0.9.5{RESET} {CYAN}│{RESET}
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(f""" {CYAN}┌─ {BOLD}Step 1/3{RESET} {CYAN}──────────────────────── {WHITE}Unpacking Governance Assets{RESET} {CYAN}──────┐{RESET}
75
- {CYAN}│{RESET} {CYAN}│{RESET}
76
- {CYAN}│{RESET} {GREEN}✔{RESET} Canonical security rules {DIM}71 rules across 11 families{RESET} {CYAN}│{RESET}
77
- {CYAN}│{RESET} {GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET} {CYAN}│{RESET}
78
- {CYAN}│{RESET} {GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET} {CYAN}│{RESET}
79
- {CYAN}│{RESET} {GREEN}✔{RESET} Workflow templates {DIM}11 slash commands{RESET} {CYAN}│{RESET}
80
- {CYAN}│{RESET} {GREEN}✔{RESET} Framework reference guides {DIM}10 security guides{RESET} {CYAN}│{RESET}
81
- {CYAN}│{RESET} {CYAN}│{RESET}
82
- {CYAN}│{RESET} {BOLD}{WHITE}{file_count} files unpacked{RESET} {CYAN}│{RESET}
83
- {CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
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
- label = f"Auto-aligned stack: {fw} ({lang})"
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
- status_line = f" {CYAN}│{RESET} {DIM}ℹ Stack auto-detected on first /torusguard-audit run{RESET} {CYAN}│{RESET}"
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
- lines = ""
186
+ print(card_border_top("Step 3/3 ─── AI IDE Command Registration"))
187
+ print(card_line(""))
120
188
  for r in registered_ides:
121
- lines += f" {CYAN}│{RESET} {GREEN}✔{RESET} {r:<67} {CYAN}│{RESET}\n"
122
-
123
- print(f""" {CYAN}┌─ {BOLD}Step 3/3{RESET} {CYAN}─────────────────── {WHITE}AI IDE Command Registration{RESET} {CYAN}─────────┐{RESET}
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(f""" {GREEN}╔═══════════════════════════════════════════════════════════════════════╗{RESET}
133
- {GREEN}║{RESET} {GREEN}║{RESET}
134
- {GREEN}║{RESET} {GREEN}{BOLD}✅ WORKSPACE INITIALIZED SUCCESSFULLY{RESET} {GREEN}║{RESET}
135
- {GREEN}║{RESET} {GREEN}║{RESET}
136
- {GREEN}╠═══════════════════════════════════════════════════════════════════════╣{RESET}
137
- {GREEN}║{RESET} {GREEN}║{RESET}
138
- {GREEN}║{RESET} {BOLD}Next Steps:{RESET} {GREEN}║{RESET}
139
- {GREEN}║{RESET} {GREEN}║{RESET}
140
- {GREEN}║{RESET} {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard-audit{RESET} or {WHITE}/torusguard{RESET} {GREEN}║{RESET}
141
- {GREEN}║{RESET} {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET} {GREEN}║{RESET}
142
- {GREEN}║{RESET} {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET} {GREEN}║{RESET}
143
- {GREEN}║{RESET} {GREEN}║{RESET}
144
- {GREEN}║{RESET} {DIM}Docs{RESET} {CYAN}https://github.com/githubmofo/TorusGuard{RESET} {GREEN}║{RESET}
145
- {GREEN}║{RESET} {DIM}NPM{RESET} {CYAN}https://npmjs.com/package/torusguard{RESET} {GREEN}║{RESET}
146
- {GREEN}║{RESET} {GREEN}║{RESET}
147
- {GREEN}╚═══════════════════════════════════════════════════════════════════════╝{RESET}
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.0.0')}{RESET}
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 .agents/workflows are created
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 11 individual slash commands
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}`));