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
@@ -0,0 +1,82 @@
1
+ # TG-WS-001: Unauthenticated WebSocket Handshake
2
+
3
+ ## Severity
4
+ High. Accepting WebSocket upgrade handshakes without validating authentication cookies or Bearer tokens allows unauthenticated clients to establish persistent sockets and consume server resources.
5
+
6
+ ## Applies To
7
+ - `ws`, `Socket.io`, `fastapi.WebSocket`, `channels` (Django), `aiohttp`
8
+
9
+ ## Why It Matters
10
+ HTTP WebSocket upgrades (`Upgrade: websocket`) begin as standard HTTP requests. If authentication is omitted during the initial HTTP upgrade:
11
+ 1. Attackers can flood the server with unbounded persistent open TCP connections, exhausting socket file descriptors.
12
+ 2. If authorization is deferred to post-connect messages, unauthenticated clients can linger in memory indefinitely.
13
+ 3. Cross-site WebSocket hijacking (CSWSH) can occur if the `Origin` header is trusted blindly.
14
+
15
+ ## What TorusGuard Looks For
16
+ 1. WebSocket servers accepting the upgrade connection before validating session cookies, headers, or query tokens.
17
+ 2. Missing `Origin` header validation during handshake.
18
+ 3. Runtime probe: Attempting a WebSocket handshake without an `Authorization` header or session cookie; flagging if the connection status returns `101 Switching Protocols` instead of `401 Unauthorized`.
19
+
20
+ ## Unsafe Example
21
+ ```typescript
22
+ // UNSAFE: Accepting WebSocket upgrade without verifying session
23
+ import { WebSocketServer } from "ws";
24
+
25
+ const wss = new WebSocketServer({ port: 8080 });
26
+
27
+ wss.on("connection", (ws, req) => {
28
+ // Handshake already succeeded without verifying authentication!
29
+ ws.send("Welcome to real-time events");
30
+ });
31
+ ```
32
+
33
+ ## Safe Example
34
+ ```typescript
35
+ // SAFE: Validating authentication and origin during the HTTP upgrade
36
+ import http from "http";
37
+ import { WebSocketServer } from "ws";
38
+ import { verifyJwtToken } from "./auth";
39
+
40
+ const server = http.createServer();
41
+ const wss = new WebSocketServer({ noServer: true });
42
+
43
+ server.on("upgrade", (req, socket, head) => {
44
+ // 1. Verify Origin header
45
+ const origin = req.headers.origin;
46
+ if (origin !== "https://app.example.com") {
47
+ socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
48
+ socket.destroy();
49
+ return;
50
+ }
51
+
52
+ // 2. Authenticate token before completing WebSocket handshake
53
+ const token = req.headers["sec-websocket-protocol"] || req.headers.cookie;
54
+ const user = verifyJwtToken(token);
55
+ if (!user) {
56
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
57
+ socket.destroy();
58
+ return;
59
+ }
60
+
61
+ // 3. Complete upgrade only when authenticated
62
+ wss.handleUpgrade(req, socket, head, (ws) => {
63
+ wss.emit("connection", ws, req, user);
64
+ });
65
+ });
66
+ ```
67
+
68
+ ## Bounded Runtime Probe Protocol
69
+ When probing WebSocket endpoints under `/torusguard web-validate`:
70
+ 1. Dispatch an HTTP GET request with `Upgrade: websocket` and `Connection: Upgrade` headers **without authentication credentials**.
71
+ 2. Assert that the server returns `HTTP 401` or `HTTP 403` and terminates the socket.
72
+ 3. If the server returns `HTTP 101 Switching Protocols`, log a high-confidence finding for unauthenticated handshake.
73
+
74
+ ## Remediation
75
+ 1. **Authenticate on HTTP Upgrade:** Reject unauthenticated connections with standard HTTP 401/403 status codes before calling `handleUpgrade`.
76
+ 2. **Enforce Strict Origin Checking:** Validate that `req.headers.origin` matches your trusted application domain.
77
+ 3. **Set Connection Timeouts:** Automatically disconnect sockets that fail message-level handshakes within 10 seconds.
78
+
79
+ ## Related Rules
80
+ - `TG-WS-002`: Missing Channel-Level Authorization
81
+ - `TG-AUTH-004`: Insecure Session Cookie
82
+ - `TG-RATE-003`: Unbounded Resource Consumption
@@ -0,0 +1,37 @@
1
+ # TG-WS-002: Missing Channel-Level Authorization
2
+
3
+ ## Severity
4
+ High by default. Raise to Critical when applicable.
5
+
6
+ ## Applies To
7
+ - Relevant endpoints and services
8
+
9
+ ## Why It Matters
10
+ Explaining the risk of this vulnerability.
11
+
12
+ ## What TorusGuard Looks For
13
+ - Specific code patterns or configurations
14
+
15
+ ## Unsafe Example
16
+ ```javascript
17
+ // Unsafe code example
18
+ ```
19
+
20
+ ## Safe Example
21
+ ```javascript
22
+ // Safe code example
23
+ ```
24
+
25
+ ## Remediation
26
+ 1. Step one
27
+ 2. Step two
28
+
29
+ ## Verification
30
+ - Test case 1
31
+ - Test case 2
32
+
33
+ ## False Positives and Exceptions
34
+ An exception requires documented review.
35
+
36
+ ## Related Rules
37
+ - TG-OTHER-001
@@ -0,0 +1,37 @@
1
+ # TG-WS-003: Unvalidated WebSocket Message
2
+
3
+ ## Severity
4
+ High by default. Raise to Critical when applicable.
5
+
6
+ ## Applies To
7
+ - Relevant endpoints and services
8
+
9
+ ## Why It Matters
10
+ Explaining the risk of this vulnerability.
11
+
12
+ ## What TorusGuard Looks For
13
+ - Specific code patterns or configurations
14
+
15
+ ## Unsafe Example
16
+ ```javascript
17
+ // Unsafe code example
18
+ ```
19
+
20
+ ## Safe Example
21
+ ```javascript
22
+ // Safe code example
23
+ ```
24
+
25
+ ## Remediation
26
+ 1. Step one
27
+ 2. Step two
28
+
29
+ ## Verification
30
+ - Test case 1
31
+ - Test case 2
32
+
33
+ ## False Positives and Exceptions
34
+ An exception requires documented review.
35
+
36
+ ## Related Rules
37
+ - TG-OTHER-001
@@ -0,0 +1,37 @@
1
+ # TG-WS-004: Unbounded WebSocket Connections
2
+
3
+ ## Severity
4
+ High by default. Raise to Critical when applicable.
5
+
6
+ ## Applies To
7
+ - Relevant endpoints and services
8
+
9
+ ## Why It Matters
10
+ Explaining the risk of this vulnerability.
11
+
12
+ ## What TorusGuard Looks For
13
+ - Specific code patterns or configurations
14
+
15
+ ## Unsafe Example
16
+ ```javascript
17
+ // Unsafe code example
18
+ ```
19
+
20
+ ## Safe Example
21
+ ```javascript
22
+ // Safe code example
23
+ ```
24
+
25
+ ## Remediation
26
+ 1. Step one
27
+ 2. Step two
28
+
29
+ ## Verification
30
+ - Test case 1
31
+ - Test case 2
32
+
33
+ ## False Positives and Exceptions
34
+ An exception requires documented review.
35
+
36
+ ## Related Rules
37
+ - TG-OTHER-001
@@ -0,0 +1,339 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ TorusGuard Governed Patch Application & Snapshot Engine (v1.3.0)
4
+ Interactive Human Gate authorization, pre-apply .bak rollback snapshots,
5
+ atomic patch application, and Golden Fix Recipe distillation into persistent memory.
6
+
7
+ Pure Python 3.10+ standard library (zero external dependencies).
8
+ """
9
+
10
+ import sys
11
+ import os
12
+ import re
13
+ import json
14
+ import shutil
15
+ import hashlib
16
+ import argparse
17
+ import datetime
18
+ import unicodedata
19
+ from pathlib import Path
20
+ from typing import Dict, List, Any, Optional, Tuple
21
+
22
+ # Windows console UTF-8 support
23
+ if sys.stdout and hasattr(sys.stdout, "reconfigure"):
24
+ try:
25
+ getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
26
+ except Exception:
27
+ pass
28
+
29
+ # ─── Timezone Configuration: Indian Standard Time (IST, UTC+05:30) ───────────
30
+ IST = datetime.timezone(datetime.timedelta(hours=5, minutes=30), name="IST")
31
+
32
+ def get_ist_now() -> datetime.datetime:
33
+ return datetime.datetime.now(IST)
34
+
35
+ # ─── ANSI Colors & Formatter ───────────────────────────────────────────────────
36
+ BOLD = "\033[1m"
37
+ DIM = "\033[2m"
38
+ RESET = "\033[0m"
39
+ CYAN = "\033[36m"
40
+ GREEN = "\033[32m"
41
+ YELLOW = "\033[33m"
42
+ WHITE = "\033[97m"
43
+ GRAY = "\033[90m"
44
+ RED = "\033[31m"
45
+
46
+ ANSI_REGEX = re.compile(r'\033\[[0-9;]*m')
47
+
48
+ def get_visual_width(text: str) -> int:
49
+ clean = ANSI_REGEX.sub('', text)
50
+ width = 0
51
+ for ch in clean:
52
+ ea = unicodedata.east_asian_width(ch)
53
+ if ea in ('W', 'F'):
54
+ width += 2
55
+ elif ord(ch) >= 0x1F300:
56
+ width += 2
57
+ else:
58
+ width += 1
59
+ return width
60
+
61
+ def format_box_line(content: str, width: int = 71, border: str = "│", border_color: str = CYAN) -> str:
62
+ vis = get_visual_width(content)
63
+ pad = " " * max(0, width - vis)
64
+ return f" {border_color}{border}{RESET} {content}{pad}{border_color}{border}{RESET}"
65
+
66
+
67
+ def find_latest_audit_run(runs_dir: Path) -> Optional[Path]:
68
+ if not runs_dir.is_dir():
69
+ return None
70
+ runs = sorted(runs_dir.glob("run-*-audit"), key=lambda p: p.stat().st_mtime, reverse=True)
71
+ return runs[0] if runs else None
72
+
73
+
74
+ def execute_rollback(target_root: Path, run_id_arg: Optional[str] = None) -> None:
75
+ """Restore all target files from the pre-apply backup snapshots."""
76
+ snapshots_base = target_root / ".torusguard" / "snapshots"
77
+ if not snapshots_base.is_dir():
78
+ print(f"\n {YELLOW}ℹ No snapshots directory found at: {snapshots_base}{RESET}\n")
79
+ sys.exit(0)
80
+
81
+ if run_id_arg:
82
+ snapshot_dir = snapshots_base / run_id_arg
83
+ else:
84
+ snapshots = sorted([d for d in snapshots_base.iterdir() if d.is_dir()], key=lambda p: p.stat().st_mtime, reverse=True)
85
+ snapshot_dir = snapshots[0] if snapshots else None
86
+
87
+ if not snapshot_dir or not snapshot_dir.is_dir():
88
+ print(f"\n {RED}✖ No rollback snapshot found for run: {run_id_arg or 'latest'}{RESET}\n")
89
+ sys.exit(1)
90
+
91
+ restored_files = []
92
+ for bak_file in snapshot_dir.rglob("*.bak"):
93
+ rel_path = bak_file.relative_to(snapshot_dir)
94
+ orig_rel = str(rel_path)[:-4] # Strip .bak
95
+ dest_file = target_root / orig_rel
96
+
97
+ dest_file.parent.mkdir(parents=True, exist_ok=True)
98
+ shutil.copy2(bak_file, dest_file)
99
+ restored_files.append(orig_rel)
100
+
101
+ print(f"\n {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}")
102
+ print(format_box_line(f"{BOLD}🛡️ TORUSGUARD ROLLBACK RESTORATION v1.3.1{RESET}", border_color=CYAN))
103
+ print(format_box_line(f"{DIM}Restored original files from pre-apply snapshot{RESET}", border_color=CYAN))
104
+ print(f" {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}\n")
105
+
106
+ print(f" {CYAN}┌─ Rollback Snapshot Restored ────────────────────────────────────────────┐{RESET}")
107
+ print(format_box_line(f"Snapshot Run: {WHITE}{snapshot_dir.name}{RESET}"))
108
+ print(format_box_line(f"Files Restored: {GREEN}{len(restored_files)} file(s) cleanly reverted{RESET}"))
109
+ for rf in restored_files:
110
+ print(format_box_line(f" ✔ {rf}"))
111
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
112
+ sys.exit(0)
113
+
114
+
115
+ def execute_apply(target_root: Path, run_id_arg: Optional[str] = None, auto_approve: bool = False) -> Dict[str, Any]:
116
+ runs_dir = target_root / ".torusguard" / "runs"
117
+ if run_id_arg:
118
+ run_folder = runs_dir / run_id_arg
119
+ else:
120
+ run_folder = find_latest_audit_run(runs_dir)
121
+
122
+ if not run_folder or not run_folder.is_dir():
123
+ print(f"\n {RED}✖ No audit runs found.{RESET}")
124
+ print(f" Run {CYAN}npx torusguard audit{RESET} followed by {CYAN}npx torusguard harden{RESET} first.\n")
125
+ sys.exit(1)
126
+
127
+ bundles_dir = run_folder / "bundles"
128
+ bundle_meta_files = list(bundles_dir.glob("*/metadata.json")) if bundles_dir.is_dir() else []
129
+ if not bundle_meta_files:
130
+ print(f"\n {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}")
131
+ print(f" {CYAN}│ │{RESET}")
132
+ print(format_box_line(f"{BOLD}🛡️ TORUSGUARD GOVERNED PATCH APPLIER v1.3.1{RESET}", border_color=CYAN))
133
+ print(format_box_line(f"{DIM}Human-Gate Authorization, Snapshots & Golden Recipe Distillation{RESET}", border_color=CYAN))
134
+ print(f" {CYAN}│ │{RESET}")
135
+ print(f" {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}\n")
136
+
137
+ print(f" {YELLOW}ℹ Zero candidate remediation bundles found in run: {run_folder.name}{RESET}")
138
+ print(f" {GRAY}The findings in this run require manual review or AI-assisted remediation.{RESET}\n")
139
+ print(f" {CYAN}┌─ Recommended Next Steps ────────────────────────────────────────────────┐{RESET}")
140
+ print(format_box_line("1. In AI Chat (Antigravity/Cursor/Claude): Run /torusguard-harden"))
141
+ print(format_box_line(" to formulate custom architectural patches with your AI agent."))
142
+ print(format_box_line(f"2. Inspect findings: .torusguard/runs/{run_folder.name}/findings.md"))
143
+ print(format_box_line("3. View visual posture report: npx torusguard report --html"))
144
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
145
+ sys.exit(0)
146
+
147
+ bundles = []
148
+ for mf in bundle_meta_files:
149
+ try:
150
+ bundles.append(json.loads(mf.read_text(encoding="utf-8")))
151
+ except Exception:
152
+ pass
153
+
154
+ # Snapshot directory
155
+ snapshot_dir = target_root / ".torusguard" / "snapshots" / run_folder.name
156
+ snapshot_dir.mkdir(parents=True, exist_ok=True)
157
+
158
+ # Header Card
159
+ print(f"\n {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}")
160
+ print(f" {CYAN}│ │{RESET}")
161
+ print(format_box_line(f"{BOLD}🛡️ TORUSGUARD GOVERNED PATCH APPLIER v1.3.0{RESET}", border_color=CYAN))
162
+ print(format_box_line(f"{DIM}Human-Gate Authorization, Snapshots & Golden Recipe Distillation{RESET}", border_color=CYAN))
163
+ print(f" {CYAN}│ │{RESET}")
164
+ print(f" {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}\n")
165
+
166
+ print(f" {CYAN}┌─ Candidate Bundles Ready for Application ───────────────────────────────┐{RESET}")
167
+ print(format_box_line(f"Active Run: {WHITE}{run_folder.name}{RESET}"))
168
+ print(format_box_line(f"Total Bundles: {GREEN}{len(bundles)} candidate surgical patches formulated{RESET}"))
169
+ print(format_box_line(f"Rollback Safety:Automatic pre-apply snapshot to .torusguard/snapshots/{run_folder.name}"))
170
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
171
+
172
+ applied_count = 0
173
+ skipped_count = 0
174
+ all_approved = auto_approve
175
+ diff_summary_lines = [f"# TorusGuard Applied Patch Summary: {run_folder.name}\n"]
176
+ applied_bundles = []
177
+
178
+ # Import memory_engine for Golden Recipe distillation
179
+ scripts_dir = Path(__file__).resolve().parent
180
+ if str(scripts_dir) not in sys.path:
181
+ sys.path.insert(0, str(scripts_dir))
182
+ import memory_engine
183
+
184
+ for idx, b in enumerate(bundles, 1):
185
+ rule_id = b.get("rule_id", "TG-SEC")
186
+ rel_path = b.get("target_file", "")
187
+ line_no = b.get("line_number", 1)
188
+ diff = b.get("proposed_diff", "")
189
+ desc = b.get("what_should_change", "")
190
+ patched_content = b.get("patched_content")
191
+
192
+ print(f" {YELLOW}─── [{idx}/{len(bundles)}] Candidate Patch: [{rule_id}] on {rel_path}:{line_no} ───{RESET}")
193
+ print(f" Strategy: {WHITE}{desc}{RESET}")
194
+ print(f" Ponytail: {GREEN}+{b.get('additions', 0)} / -{b.get('deletions', 0)}{RESET}\n")
195
+
196
+ # Display syntax-highlighted diff
197
+ for dline in diff.splitlines()[:12]:
198
+ if dline.startswith("+") and not dline.startswith("+++"):
199
+ print(f" {GREEN}{dline}{RESET}")
200
+ elif dline.startswith("-") and not dline.startswith("---"):
201
+ print(f" {RED}{dline}{RESET}")
202
+ elif dline.startswith("@"):
203
+ print(f" {CYAN}{dline}{RESET}")
204
+ else:
205
+ print(f" {DIM}{dline}{RESET}")
206
+ print()
207
+
208
+ if not all_approved:
209
+ try:
210
+ choice = input(f" {BOLD}Apply this patch?{RESET} ([y]es / [n]o / [a]ll / [q]uit): ").strip().lower()
211
+ except (EOFError, KeyboardInterrupt):
212
+ print(f"\n {YELLOW}Aborted by user.{RESET}\n")
213
+ break
214
+
215
+ if choice in ("q", "quit"):
216
+ print(f"\n {YELLOW}Exited review.{RESET}\n")
217
+ break
218
+ elif choice in ("a", "all"):
219
+ all_approved = True
220
+ elif choice not in ("y", "yes", ""):
221
+ print(f" {GRAY}Skipped.{RESET}\n")
222
+ skipped_count += 1
223
+ continue
224
+
225
+ # Execute Application
226
+ target_file = target_root / rel_path
227
+ if not target_file.is_file():
228
+ print(f" {RED}✖ Target file not found: {target_file}{RESET}\n")
229
+ continue
230
+
231
+ # 1. Pre-apply Snapshot (.bak)
232
+ bak_dest = snapshot_dir / (rel_path + ".bak")
233
+ bak_dest.parent.mkdir(parents=True, exist_ok=True)
234
+ shutil.copy2(target_file, bak_dest)
235
+
236
+ # 2. Write Patched Content
237
+ if patched_content:
238
+ target_file.write_text(patched_content, encoding="utf-8")
239
+ else:
240
+ continue
241
+
242
+ # 3. Distill into Golden Fix Recipe in Memory Engine
243
+ try:
244
+ fn = getattr(memory_engine, "record_golden_recipe", getattr(memory_engine, "store_golden_recipe", None))
245
+ if fn:
246
+ fn(
247
+ rule_id=rule_id,
248
+ before_snippet=target_file.read_text(encoding="utf-8").splitlines()[max(0, line_no-1)],
249
+ after_snippet=desc,
250
+ diff_snippet=diff,
251
+ file_type=target_file.suffix,
252
+ description=desc,
253
+ root_dir=target_root
254
+ )
255
+ # Record event
256
+ memory_engine.record_event("fix_applied", {
257
+ "rule_id": rule_id,
258
+ "file_path": rel_path,
259
+ "line_number": line_no,
260
+ "bundle_id": b.get("bundle_id")
261
+ }, root_dir=target_root)
262
+ except Exception:
263
+ pass
264
+
265
+ applied_count += 1
266
+ applied_bundles.append(b)
267
+ diff_summary_lines.append(f"## Applied: `[{rule_id}]` on `{rel_path}:{line_no}`")
268
+ diff_summary_lines.append("```diff")
269
+ diff_summary_lines.append(diff.strip())
270
+ diff_summary_lines.append("```\n")
271
+ print(f" {GREEN}✔ Applied successfully.{RESET} (Snapshot saved: {bak_dest.relative_to(target_root)})\n")
272
+
273
+ # Write apply artifacts in run folder
274
+ (run_folder / "diff_summary.md").write_text("\n".join(diff_summary_lines), encoding="utf-8")
275
+ apply_plan_lines = [
276
+ f"# TorusGuard Governed Application Plan: {run_folder.name}",
277
+ f"- **Total Candidate Patches:** {len(bundles)}",
278
+ f"- **Successfully Applied:** {applied_count}",
279
+ f"- **Skipped by Human Gate:** {skipped_count}",
280
+ f"- **Execution Timestamp:** {get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}",
281
+ f"- **Rollback Directory:** `.torusguard/snapshots/{run_folder.name}`"
282
+ ]
283
+ (run_folder / "apply_plan.md").write_text("\n".join(apply_plan_lines), encoding="utf-8")
284
+
285
+ # Update manifest
286
+ manifest_file = run_folder / "manifest.json"
287
+ if manifest_file.is_file():
288
+ try:
289
+ mdata = json.loads(manifest_file.read_text(encoding="utf-8"))
290
+ mdata["status"] = "patches_applied"
291
+ mdata["remediated"] = applied_count
292
+ manifest_file.write_text(json.dumps(mdata, indent=2), encoding="utf-8")
293
+ except Exception:
294
+ pass
295
+
296
+ # Summary Box
297
+ print(f" {CYAN}┌─ Application Summary ───────────────────────────────────────────────────┐{RESET}")
298
+ print(format_box_line(f"Applied Patches:{GREEN}{applied_count} applied cleanly{RESET}"))
299
+ print(format_box_line(f"Skipped / Pass: {GRAY}{skipped_count} skipped{RESET}"))
300
+ print(format_box_line(f"Golden Recipes: {GREEN}{applied_count} distilled into persistent memory{RESET}"))
301
+ print(format_box_line(f"Snapshot Safety:.torusguard/snapshots/{run_folder.name}"))
302
+ print(f" {CYAN}└─────────────────────────────────────────────────────────────────────────┘{RESET}\n")
303
+
304
+ print(f" {GREEN}╔═ Next Governed Action ═════════════════════════════════════════════════════╗{RESET}")
305
+ print(format_box_line(f"Differential Recheck: {BOLD}{WHITE}npx torusguard recheck{RESET} (Verify fix closure)", border="║", border_color=GREEN))
306
+ print(format_box_line(f"View Golden Recipes: {CYAN}npx torusguard recipes{RESET} (Inspect memory)", border="║", border_color=GREEN))
307
+ print(format_box_line(f"Emergency Rollback: {YELLOW}npx torusguard rollback{RESET} (Instant revert)", border="║", border_color=GREEN))
308
+ print(f" {GREEN}╚═════════════════════════════════════════════════════════════════════════════╝{RESET}\n")
309
+
310
+ return {
311
+ "applied_count": applied_count,
312
+ "skipped_count": skipped_count,
313
+ "applied_bundles": applied_bundles,
314
+ "snapshot_dir": str(snapshot_dir)
315
+ }
316
+
317
+
318
+ def main():
319
+ parser = argparse.ArgumentParser(description="TorusGuard Governed Patch Application Engine")
320
+ parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
321
+ parser.add_argument("--run", "-r", help="Explicit run ID to apply")
322
+ parser.add_argument("--yes", "-y", action="store_true", help="Auto-approve all patches (non-interactive)")
323
+ parser.add_argument("--rollback", action="store_true", help="Rollback all applied patches using snapshots")
324
+ parser.add_argument("--json", action="store_true", help="Output raw JSON")
325
+ args = parser.parse_args()
326
+
327
+ target = Path(args.path).resolve()
328
+
329
+ if args.rollback:
330
+ execute_rollback(target, run_id_arg=args.run)
331
+ return
332
+
333
+ result = execute_apply(target, run_id_arg=args.run, auto_approve=args.yes)
334
+ if args.json:
335
+ print(json.dumps(result, indent=2))
336
+
337
+
338
+ if __name__ == "__main__":
339
+ main()