@korayda4/vibe-security 0.3.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +333 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/engine/baseline.d.ts +19 -0
  7. package/dist/engine/baseline.js +48 -0
  8. package/dist/engine/baseline.js.map +1 -0
  9. package/dist/engine/config.d.ts +26 -0
  10. package/dist/engine/config.js +41 -0
  11. package/dist/engine/config.js.map +1 -0
  12. package/dist/engine/fixer.d.ts +22 -0
  13. package/dist/engine/fixer.js +87 -0
  14. package/dist/engine/fixer.js.map +1 -0
  15. package/dist/engine/language.d.ts +27 -0
  16. package/dist/engine/language.js +364 -0
  17. package/dist/engine/language.js.map +1 -0
  18. package/dist/engine/output.d.ts +6 -0
  19. package/dist/engine/output.js +155 -0
  20. package/dist/engine/output.js.map +1 -0
  21. package/dist/engine/reporter.d.ts +3 -0
  22. package/dist/engine/reporter.js +145 -0
  23. package/dist/engine/reporter.js.map +1 -0
  24. package/dist/engine/rules/_helpers.d.ts +9 -0
  25. package/dist/engine/rules/_helpers.js +64 -0
  26. package/dist/engine/rules/_helpers.js.map +1 -0
  27. package/dist/engine/rules/backend/fileUpload.d.ts +3 -0
  28. package/dist/engine/rules/backend/fileUpload.js +40 -0
  29. package/dist/engine/rules/backend/fileUpload.js.map +1 -0
  30. package/dist/engine/rules/backend/hashing.d.ts +3 -0
  31. package/dist/engine/rules/backend/hashing.js +40 -0
  32. package/dist/engine/rules/backend/hashing.js.map +1 -0
  33. package/dist/engine/rules/backend/idor.d.ts +3 -0
  34. package/dist/engine/rules/backend/idor.js +40 -0
  35. package/dist/engine/rules/backend/idor.js.map +1 -0
  36. package/dist/engine/rules/backend/index.d.ts +12 -0
  37. package/dist/engine/rules/backend/index.js +22 -0
  38. package/dist/engine/rules/backend/index.js.map +1 -0
  39. package/dist/engine/rules/backend/inputValidation.d.ts +3 -0
  40. package/dist/engine/rules/backend/inputValidation.js +37 -0
  41. package/dist/engine/rules/backend/inputValidation.js.map +1 -0
  42. package/dist/engine/rules/backend/jwt.d.ts +3 -0
  43. package/dist/engine/rules/backend/jwt.js +42 -0
  44. package/dist/engine/rules/backend/jwt.js.map +1 -0
  45. package/dist/engine/rules/backend/rateLimit.d.ts +3 -0
  46. package/dist/engine/rules/backend/rateLimit.js +45 -0
  47. package/dist/engine/rules/backend/rateLimit.js.map +1 -0
  48. package/dist/engine/rules/backend/sqlInjection.d.ts +3 -0
  49. package/dist/engine/rules/backend/sqlInjection.js +41 -0
  50. package/dist/engine/rules/backend/sqlInjection.js.map +1 -0
  51. package/dist/engine/rules/backend/tokenExpiry.d.ts +3 -0
  52. package/dist/engine/rules/backend/tokenExpiry.js +85 -0
  53. package/dist/engine/rules/backend/tokenExpiry.js.map +1 -0
  54. package/dist/engine/rules/backend/tokenInUrl.d.ts +3 -0
  55. package/dist/engine/rules/backend/tokenInUrl.js +112 -0
  56. package/dist/engine/rules/backend/tokenInUrl.js.map +1 -0
  57. package/dist/engine/rules/cicd/dependencies.d.ts +3 -0
  58. package/dist/engine/rules/cicd/dependencies.js +44 -0
  59. package/dist/engine/rules/cicd/dependencies.js.map +1 -0
  60. package/dist/engine/rules/cicd/dockerfile.d.ts +3 -0
  61. package/dist/engine/rules/cicd/dockerfile.js +42 -0
  62. package/dist/engine/rules/cicd/dockerfile.js.map +1 -0
  63. package/dist/engine/rules/cicd/index.d.ts +6 -0
  64. package/dist/engine/rules/cicd/index.js +10 -0
  65. package/dist/engine/rules/cicd/index.js.map +1 -0
  66. package/dist/engine/rules/cicd/secrets.d.ts +3 -0
  67. package/dist/engine/rules/cicd/secrets.js +41 -0
  68. package/dist/engine/rules/cicd/secrets.js.map +1 -0
  69. package/dist/engine/rules/database/encryption.d.ts +3 -0
  70. package/dist/engine/rules/database/encryption.js +37 -0
  71. package/dist/engine/rules/database/encryption.js.map +1 -0
  72. package/dist/engine/rules/database/index.d.ts +5 -0
  73. package/dist/engine/rules/database/index.js +8 -0
  74. package/dist/engine/rules/database/index.js.map +1 -0
  75. package/dist/engine/rules/database/privileges.d.ts +3 -0
  76. package/dist/engine/rules/database/privileges.js +40 -0
  77. package/dist/engine/rules/database/privileges.js.map +1 -0
  78. package/dist/engine/rules/frontend/clickjacking.d.ts +3 -0
  79. package/dist/engine/rules/frontend/clickjacking.js +41 -0
  80. package/dist/engine/rules/frontend/clickjacking.js.map +1 -0
  81. package/dist/engine/rules/frontend/cookies.d.ts +3 -0
  82. package/dist/engine/rules/frontend/cookies.js +35 -0
  83. package/dist/engine/rules/frontend/cookies.js.map +1 -0
  84. package/dist/engine/rules/frontend/envVars.d.ts +3 -0
  85. package/dist/engine/rules/frontend/envVars.js +34 -0
  86. package/dist/engine/rules/frontend/envVars.js.map +1 -0
  87. package/dist/engine/rules/frontend/eval.d.ts +3 -0
  88. package/dist/engine/rules/frontend/eval.js +35 -0
  89. package/dist/engine/rules/frontend/eval.js.map +1 -0
  90. package/dist/engine/rules/frontend/index.d.ts +9 -0
  91. package/dist/engine/rules/frontend/index.js +16 -0
  92. package/dist/engine/rules/frontend/index.js.map +1 -0
  93. package/dist/engine/rules/frontend/sourceMaps.d.ts +3 -0
  94. package/dist/engine/rules/frontend/sourceMaps.js +79 -0
  95. package/dist/engine/rules/frontend/sourceMaps.js.map +1 -0
  96. package/dist/engine/rules/frontend/xss.d.ts +3 -0
  97. package/dist/engine/rules/frontend/xss.js +70 -0
  98. package/dist/engine/rules/frontend/xss.js.map +1 -0
  99. package/dist/engine/rules/index.d.ts +8 -0
  100. package/dist/engine/rules/index.js +38 -0
  101. package/dist/engine/rules/index.js.map +1 -0
  102. package/dist/engine/rules/kotlin/index.d.ts +5 -0
  103. package/dist/engine/rules/kotlin/index.js +8 -0
  104. package/dist/engine/rules/kotlin/index.js.map +1 -0
  105. package/dist/engine/rules/kotlin/kotlinxHtml.d.ts +3 -0
  106. package/dist/engine/rules/kotlin/kotlinxHtml.js +54 -0
  107. package/dist/engine/rules/kotlin/kotlinxHtml.js.map +1 -0
  108. package/dist/engine/rules/kotlin/sqlInjection.d.ts +3 -0
  109. package/dist/engine/rules/kotlin/sqlInjection.js +57 -0
  110. package/dist/engine/rules/kotlin/sqlInjection.js.map +1 -0
  111. package/dist/engine/rules/network/cors.d.ts +3 -0
  112. package/dist/engine/rules/network/cors.js +106 -0
  113. package/dist/engine/rules/network/cors.js.map +1 -0
  114. package/dist/engine/rules/network/headers.d.ts +3 -0
  115. package/dist/engine/rules/network/headers.js +51 -0
  116. package/dist/engine/rules/network/headers.js.map +1 -0
  117. package/dist/engine/rules/network/index.d.ts +6 -0
  118. package/dist/engine/rules/network/index.js +10 -0
  119. package/dist/engine/rules/network/index.js.map +1 -0
  120. package/dist/engine/rules/network/tls.d.ts +3 -0
  121. package/dist/engine/rules/network/tls.js +40 -0
  122. package/dist/engine/rules/network/tls.js.map +1 -0
  123. package/dist/engine/rules/observability/errorHandler.d.ts +3 -0
  124. package/dist/engine/rules/observability/errorHandler.js +34 -0
  125. package/dist/engine/rules/observability/errorHandler.js.map +1 -0
  126. package/dist/engine/rules/observability/index.d.ts +5 -0
  127. package/dist/engine/rules/observability/index.js +8 -0
  128. package/dist/engine/rules/observability/index.js.map +1 -0
  129. package/dist/engine/rules/observability/logging.d.ts +3 -0
  130. package/dist/engine/rules/observability/logging.js +38 -0
  131. package/dist/engine/rules/observability/logging.js.map +1 -0
  132. package/dist/engine/rules/php/index.d.ts +6 -0
  133. package/dist/engine/rules/php/index.js +10 -0
  134. package/dist/engine/rules/php/index.js.map +1 -0
  135. package/dist/engine/rules/php/sqlInjection.d.ts +3 -0
  136. package/dist/engine/rules/php/sqlInjection.js +58 -0
  137. package/dist/engine/rules/php/sqlInjection.js.map +1 -0
  138. package/dist/engine/rules/php/weakHashing.d.ts +3 -0
  139. package/dist/engine/rules/php/weakHashing.js +36 -0
  140. package/dist/engine/rules/php/weakHashing.js.map +1 -0
  141. package/dist/engine/rules/php/xss.d.ts +3 -0
  142. package/dist/engine/rules/php/xss.js +56 -0
  143. package/dist/engine/rules/php/xss.js.map +1 -0
  144. package/dist/engine/rules/ruby/index.d.ts +6 -0
  145. package/dist/engine/rules/ruby/index.js +10 -0
  146. package/dist/engine/rules/ruby/index.js.map +1 -0
  147. package/dist/engine/rules/ruby/sqlInjection.d.ts +3 -0
  148. package/dist/engine/rules/ruby/sqlInjection.js +56 -0
  149. package/dist/engine/rules/ruby/sqlInjection.js.map +1 -0
  150. package/dist/engine/rules/ruby/strongParams.d.ts +3 -0
  151. package/dist/engine/rules/ruby/strongParams.js +35 -0
  152. package/dist/engine/rules/ruby/strongParams.js.map +1 -0
  153. package/dist/engine/rules/ruby/xss.d.ts +3 -0
  154. package/dist/engine/rules/ruby/xss.js +55 -0
  155. package/dist/engine/rules/ruby/xss.js.map +1 -0
  156. package/dist/engine/rules/rust/index.d.ts +6 -0
  157. package/dist/engine/rules/rust/index.js +10 -0
  158. package/dist/engine/rules/rust/index.js.map +1 -0
  159. package/dist/engine/rules/rust/secretInCode.d.ts +3 -0
  160. package/dist/engine/rules/rust/secretInCode.js +36 -0
  161. package/dist/engine/rules/rust/secretInCode.js.map +1 -0
  162. package/dist/engine/rules/rust/sqlInjection.d.ts +3 -0
  163. package/dist/engine/rules/rust/sqlInjection.js +55 -0
  164. package/dist/engine/rules/rust/sqlInjection.js.map +1 -0
  165. package/dist/engine/rules/rust/unsafeExpect.d.ts +3 -0
  166. package/dist/engine/rules/rust/unsafeExpect.js +56 -0
  167. package/dist/engine/rules/rust/unsafeExpect.js.map +1 -0
  168. package/dist/engine/scanner.d.ts +5 -0
  169. package/dist/engine/scanner.js +135 -0
  170. package/dist/engine/scanner.js.map +1 -0
  171. package/dist/engine/walker.d.ts +11 -0
  172. package/dist/engine/walker.js +90 -0
  173. package/dist/engine/walker.js.map +1 -0
  174. package/dist/index.d.ts +2 -0
  175. package/dist/index.js +7 -0
  176. package/dist/index.js.map +1 -0
  177. package/dist/server.d.ts +36 -0
  178. package/dist/server.js +360 -0
  179. package/dist/server.js.map +1 -0
  180. package/dist/types.d.ts +92 -0
  181. package/dist/types.js +2 -0
  182. package/dist/types.js.map +1 -0
  183. package/package.json +85 -0
@@ -0,0 +1,155 @@
1
+ export function toSarif(result) {
2
+ const rules = new Map();
3
+ for (const f of result.findings) {
4
+ if (rules.has(f.ruleId))
5
+ continue;
6
+ rules.set(f.ruleId, {
7
+ id: f.ruleId,
8
+ name: f.title,
9
+ helpText: f.remediation,
10
+ helpUri: f.references[0],
11
+ defaultSeverity: f.severity,
12
+ });
13
+ }
14
+ const sarifRules = Array.from(rules.values()).map((r) => ({
15
+ id: r.id,
16
+ name: r.name,
17
+ shortDescription: { text: r.name },
18
+ fullDescription: { text: r.helpText },
19
+ help: { text: r.helpText },
20
+ helpUri: r.helpUri,
21
+ defaultConfiguration: { level: severityToSarifLevel(r.defaultSeverity) },
22
+ }));
23
+ const sarifResults = result.findings.map((f) => ({
24
+ ruleId: f.ruleId,
25
+ level: severityToSarifLevel(f.severity),
26
+ message: { text: `${f.title} -- ${f.impact}` },
27
+ locations: [
28
+ {
29
+ physicalLocation: {
30
+ artifactLocation: { uri: f.file },
31
+ region: {
32
+ startLine: f.match.line,
33
+ startColumn: f.match.column + 1,
34
+ snippet: { text: f.match.snippet.trim() },
35
+ },
36
+ },
37
+ },
38
+ ],
39
+ fixes: f.fix
40
+ ? [
41
+ {
42
+ description: { text: f.fix.description },
43
+ artifactChanges: [
44
+ {
45
+ artifactLocation: { uri: f.file },
46
+ replacements: [
47
+ {
48
+ deletedRegion: { snippet: { text: f.fix.find } },
49
+ insertedText: { text: f.fix.replace },
50
+ },
51
+ ],
52
+ },
53
+ ],
54
+ },
55
+ ]
56
+ : undefined,
57
+ }));
58
+ return {
59
+ $schema: 'https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0.json',
60
+ version: '2.1.0',
61
+ runs: [
62
+ {
63
+ tool: {
64
+ driver: {
65
+ name: 'Vibe Security',
66
+ version: '0.1.0',
67
+ informationUri: 'https://github.com/korayda4/Vibe-Security',
68
+ rules: sarifRules,
69
+ },
70
+ },
71
+ originalUriBaseIds: { SRCROOT: { uri: 'file://' + result.rootDir + '/' } },
72
+ results: sarifResults,
73
+ invocations: [
74
+ {
75
+ startTimeUtc: result.startedAt,
76
+ endTimeUtc: result.finishedAt,
77
+ executionSuccessful: true,
78
+ },
79
+ ],
80
+ },
81
+ ],
82
+ };
83
+ }
84
+ function severityToSarifLevel(s) {
85
+ switch (s) {
86
+ case 'critical':
87
+ case 'high':
88
+ return 'error';
89
+ case 'medium':
90
+ return 'warning';
91
+ case 'low':
92
+ case 'info':
93
+ default:
94
+ return 'note';
95
+ }
96
+ }
97
+ export function toJson(result) {
98
+ return JSON.stringify(result, null, 2);
99
+ }
100
+ export function toJunit(result) {
101
+ const cases = result.findings.map((f) => ` <testcase classname="${escapeXml(f.layer)}" name="${escapeXml(f.ruleId)} ${escapeXml(f.title)}" time="0">\n` +
102
+ ` <failure type="${escapeXml(f.severity)}" message="${escapeXml(f.title)}">\n` +
103
+ ` ${escapeXml(f.file)}:${f.match.line} -- ${escapeXml(f.impact)}\n` +
104
+ ` </failure>\n` +
105
+ ` </testcase>`);
106
+ const tests = result.findings.length;
107
+ const failures = result.findings.filter((f) => f.severity === 'critical' || f.severity === 'high').length;
108
+ return (`<?xml version="1.0" encoding="UTF-8"?>\n` +
109
+ `<testsuite name="vibe-security" tests="${tests}" failures="${failures}" errors="0" time="${(result.durationMs / 1000).toFixed(3)}">\n` +
110
+ cases.join('\n') +
111
+ `\n</testsuite>\n`);
112
+ }
113
+ function escapeXml(s) {
114
+ return s
115
+ .replace(/&/g, '&amp;')
116
+ .replace(/</g, '&lt;')
117
+ .replace(/>/g, '&gt;')
118
+ .replace(/"/g, '&quot;')
119
+ .replace(/'/g, '&apos;');
120
+ }
121
+ export function toCompactMarkdown(result) {
122
+ const lines = [];
123
+ lines.push(`# Vibe Security Summary`);
124
+ lines.push('');
125
+ lines.push(`- **Total:** ${result.summary.totalFindings}`);
126
+ lines.push(`- **Critical:** ${result.summary.bySeverity.critical}`);
127
+ lines.push(`- **High:** ${result.summary.bySeverity.high}`);
128
+ lines.push(`- **Medium:** ${result.summary.bySeverity.medium}`);
129
+ lines.push('');
130
+ lines.push('| Severity | Rule | File |');
131
+ lines.push('| --- | --- | --- |');
132
+ for (const f of result.findings.slice(0, 50)) {
133
+ lines.push(`| ${f.severity} | \`${f.ruleId}\` | \`${f.file}:${f.match.line}\` |`);
134
+ }
135
+ if (result.findings.length > 50) {
136
+ lines.push(`| _...and ${result.findings.length - 50} more_ | | |`);
137
+ }
138
+ return lines.join('\n');
139
+ }
140
+ export function formatOutput(format, result) {
141
+ switch (format) {
142
+ case 'sarif':
143
+ return JSON.stringify(toSarif(result), null, 2);
144
+ case 'json':
145
+ return toJson(result);
146
+ case 'junit':
147
+ return toJunit(result);
148
+ case 'compact':
149
+ return toCompactMarkdown(result);
150
+ case 'markdown':
151
+ default:
152
+ return '';
153
+ }
154
+ }
155
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/engine/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScanResult } from '../types.js';
2
+ export declare function writeSecurityReport(result: ScanResult, reportPath: string): Promise<string>;
3
+ export declare function renderSecurityMarkdown(result: ScanResult): string;
@@ -0,0 +1,145 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const LAYER_LABELS = {
4
+ frontend: 'Frontend',
5
+ backend: 'Backend & API',
6
+ network: 'Network & Infrastructure',
7
+ database: 'Database',
8
+ cicd: 'CI/CD & DevOps',
9
+ observability: 'Observability',
10
+ };
11
+ const LAYER_DESCRIPTIONS = {
12
+ frontend: 'Client-side rendering, DOM manipulation, cookies, asset exposure',
13
+ backend: 'API endpoints, authentication, input validation, file uploads',
14
+ network: 'HTTP security headers, CORS, transport security',
15
+ database: 'Privilege separation, encryption at rest and in transit',
16
+ cicd: 'Dependency hygiene, secret management, build pipeline',
17
+ observability: 'Error handling, log safety, anomaly detection',
18
+ };
19
+ const SEVERITY_EMOJI = {
20
+ critical: '🟣',
21
+ high: '🔴',
22
+ medium: '🟠',
23
+ low: '🟡',
24
+ info: '🔵',
25
+ };
26
+ const SEVERITY_ORDER = {
27
+ critical: 0,
28
+ high: 1,
29
+ medium: 2,
30
+ low: 3,
31
+ info: 4,
32
+ };
33
+ export async function writeSecurityReport(result, reportPath) {
34
+ const md = renderSecurityMarkdown(result);
35
+ const absolute = path.resolve(reportPath);
36
+ await fs.mkdir(path.dirname(absolute), { recursive: true });
37
+ await fs.writeFile(absolute, md, 'utf8');
38
+ return absolute;
39
+ }
40
+ export function renderSecurityMarkdown(result) {
41
+ const lines = [];
42
+ const projectName = path.basename(result.rootDir);
43
+ lines.push(`# Security Audit -- ${projectName}`);
44
+ lines.push('');
45
+ lines.push(`> Generated by **Vibe Security** on ${result.startedAt}. ` +
46
+ `${result.summary.totalFindings} finding(s) across ${result.filesScanned} file(s) ` +
47
+ `using ${result.rulesEvaluated} rule(s) in ${result.durationMs}ms.`);
48
+ lines.push('');
49
+ lines.push('## Executive Summary');
50
+ lines.push('');
51
+ lines.push('| Severity | Count |');
52
+ lines.push('| --- | --- |');
53
+ for (const sev of ['critical', 'high', 'medium', 'low', 'info']) {
54
+ lines.push(`| ${SEVERITY_EMOJI[sev]} ${capitalize(sev)} | ${result.summary.bySeverity[sev]} |`);
55
+ }
56
+ lines.push('');
57
+ if (result.summary.totalFindings === 0) {
58
+ lines.push('**No security issues detected.** Maintain a healthy baseline by re-running this scan on every major change.');
59
+ lines.push('');
60
+ return lines.join('\n');
61
+ }
62
+ lines.push('## Findings by Layer');
63
+ lines.push('');
64
+ lines.push('| Layer | Description | Findings |');
65
+ lines.push('| --- | --- | --- |');
66
+ for (const layer of Object.keys(LAYER_LABELS)) {
67
+ if (result.summary.byLayer[layer] === 0)
68
+ continue;
69
+ lines.push(`| **${LAYER_LABELS[layer]}** | ${LAYER_DESCRIPTIONS[layer]} | ${result.summary.byLayer[layer]} |`);
70
+ }
71
+ lines.push('');
72
+ const byLayer = new Map();
73
+ for (const f of result.findings) {
74
+ if (!byLayer.has(f.layer))
75
+ byLayer.set(f.layer, []);
76
+ byLayer.get(f.layer).push(f);
77
+ }
78
+ for (const layer of Object.keys(LAYER_LABELS)) {
79
+ const items = byLayer.get(layer);
80
+ if (!items || items.length === 0)
81
+ continue;
82
+ lines.push(`## ${LAYER_LABELS[layer]}`);
83
+ lines.push('');
84
+ items.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
85
+ for (const f of items) {
86
+ lines.push(renderFinding(f));
87
+ lines.push('');
88
+ }
89
+ }
90
+ lines.push('## How to fix');
91
+ lines.push('');
92
+ lines.push('1. Address **Critical** and **High** findings first.');
93
+ lines.push('2. Apply remediations in the order suggested by each rule.');
94
+ lines.push('3. Re-run `vibe-security scan_project` after each fix batch.');
95
+ lines.push('4. Wire this scan into CI so regressions surface automatically.');
96
+ lines.push('');
97
+ lines.push('---');
98
+ lines.push('');
99
+ lines.push('Generated by [Vibe Security](https://github.com/korayda4/Vibe-Security) -- MCP server for AI Vibe Coders.');
100
+ lines.push('');
101
+ return lines.join('\n');
102
+ }
103
+ function renderFinding(f) {
104
+ const out = [];
105
+ out.push(`### ${SEVERITY_EMOJI[f.severity]} ${f.title}`);
106
+ out.push('');
107
+ out.push(`- **Rule ID:** \`${f.ruleId}\``);
108
+ out.push(`- **Severity:** ${capitalize(f.severity)}`);
109
+ if (f.cwe)
110
+ out.push(`- **CWE:** ${f.cwe}`);
111
+ if (f.owasp)
112
+ out.push(`- **OWASP:** ${f.owasp}`);
113
+ out.push(`- **File:** \`${f.file}\` (line ${f.match.line})`);
114
+ out.push('');
115
+ out.push('**Description**');
116
+ out.push('');
117
+ out.push(f.description);
118
+ out.push('');
119
+ out.push('**Impact**');
120
+ out.push('');
121
+ out.push(f.impact);
122
+ out.push('');
123
+ out.push('**Snippet**');
124
+ out.push('');
125
+ out.push('```');
126
+ out.push(f.match.snippet.trim() || '(empty)');
127
+ out.push('```');
128
+ out.push('');
129
+ out.push('**Remediation**');
130
+ out.push('');
131
+ out.push(f.remediation);
132
+ if (f.references.length > 0) {
133
+ out.push('');
134
+ out.push('**References**');
135
+ out.push('');
136
+ for (const ref of f.references) {
137
+ out.push(`- ${ref}`);
138
+ }
139
+ }
140
+ return out.join('\n');
141
+ }
142
+ function capitalize(s) {
143
+ return s.charAt(0).toUpperCase() + s.slice(1);
144
+ }
145
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/engine/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Finding, FixPatch, Rule, RuleContext } from '../../types.js';
2
+ export declare function matchAll(re: RegExp, source: string): Generator<RegExpExecArray>;
3
+ export declare function lineColumnFromIndex(source: string, index: number): {
4
+ line: number;
5
+ column: number;
6
+ };
7
+ export declare function snippetAt(source: string, line: number, contextLines?: number): string;
8
+ export declare function makeFinding(rule: Rule, ctx: RuleContext, matchIndex: number, matchLength: number, fix?: FixPatch): Finding;
9
+ export declare function grepRule(rule: Rule, ctx: RuleContext, re: RegExp): Finding[];
@@ -0,0 +1,64 @@
1
+ export function* matchAll(re, source) {
2
+ if (re.global || re.sticky) {
3
+ const matches = source.matchAll(re);
4
+ for (const m of matches)
5
+ yield m;
6
+ return;
7
+ }
8
+ const m = re.exec(source);
9
+ if (m)
10
+ yield m;
11
+ }
12
+ export function lineColumnFromIndex(source, index) {
13
+ let line = 1;
14
+ let col = 0;
15
+ for (let i = 0; i < index && i < source.length; i++) {
16
+ if (source[i] === '\n') {
17
+ line++;
18
+ col = 0;
19
+ }
20
+ else {
21
+ col++;
22
+ }
23
+ }
24
+ return { line, column: col };
25
+ }
26
+ export function snippetAt(source, line, contextLines = 1) {
27
+ const lines = source.split(/\r?\n/);
28
+ const start = Math.max(0, line - 1 - contextLines);
29
+ const end = Math.min(lines.length, line + contextLines);
30
+ return lines.slice(start, end).join('\n');
31
+ }
32
+ export function makeFinding(rule, ctx, matchIndex, matchLength, fix) {
33
+ const { line, column } = lineColumnFromIndex(ctx.source, matchIndex);
34
+ return {
35
+ id: `${rule.id}-${ctx.relativePath}-${line}-${column}`,
36
+ ruleId: rule.id,
37
+ title: rule.title,
38
+ layer: rule.layer,
39
+ severity: rule.severity,
40
+ file: ctx.relativePath,
41
+ match: {
42
+ snippet: snippetAt(ctx.source, line),
43
+ line,
44
+ column,
45
+ },
46
+ description: rule.description,
47
+ impact: rule.threat,
48
+ remediation: rule.remediation,
49
+ references: rule.references,
50
+ cwe: rule.cwe,
51
+ owasp: rule.owasp,
52
+ fix,
53
+ };
54
+ }
55
+ export function grepRule(rule, ctx, re) {
56
+ const out = [];
57
+ for (const m of matchAll(re, ctx.source)) {
58
+ if (m.index === undefined)
59
+ continue;
60
+ out.push(makeFinding(rule, ctx, m.index, m[0].length));
61
+ }
62
+ return out;
63
+ }
64
+ //# sourceMappingURL=_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../src/engine/rules/_helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../../types.js';
2
+ declare const rule: Rule;
3
+ export default rule;
@@ -0,0 +1,40 @@
1
+ import { grepRule } from '../_helpers.js';
2
+ const rule = {
3
+ id: 'BE-007',
4
+ title: 'Unsafe file upload (extension not validated, original filename used)',
5
+ layer: 'backend',
6
+ severity: 'high',
7
+ description: 'Dosya yuklemesinde sadece `Content-Type` veya extension kontrol edilip sunucuda orijinal isimle saklanirsa, saldirgan `.php`, `.jsp`, `.aspx` veya web-accessible dizine script yukleyebilir (RCE).',
8
+ threat: 'Remote code execution, XSS via SVG, web-shell upload',
9
+ remediation: '1) **Magic bytes** ile gercek MIME tespit edin (`file-type` paketi, `python-magic`, vb.). ' +
10
+ '2) Sadece izinli extension + MIME whitelist kabul edin (jpg, png, pdf, vb.). ' +
11
+ '3) Dosyayi **UUID** ile yeniden adlandirin (orijinal ismi KULLANMAYIN). ' +
12
+ '4) Sunucudan BAGIMSIZ depolama kullanin (S3, GCS, R2). Web root\'a yazmayin. ' +
13
+ '5) Boyut limiti koyun (multipart maxFileSize). ' +
14
+ '6) Antivirus / ClamAV ile tarayin. ' +
15
+ '7) Content-Disposition: attachment ile zorla indirme sunun. ' +
16
+ '8) SVG ve HTML\'i reddedin (XSS vektoru).',
17
+ references: [
18
+ 'https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload',
19
+ 'https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html',
20
+ ],
21
+ cwe: 'CWE-434',
22
+ owasp: 'A04:2021 Insecure Design',
23
+ languages: ['javascript', 'typescript', 'python', 'java', 'go'],
24
+ check: (ctx) => {
25
+ const patterns = [
26
+ /diskStorage\s*\([^)]*destination\s*:/g,
27
+ /filename\s*:\s*\(?\s*req\.file\.originalname/g,
28
+ /file\.save\s*\(\s*[^)]*originalname/gi,
29
+ /transferTo\s*\(\s*new\s+File\s*\(/g,
30
+ /filepath\.Join\s*\([^,]*Header\.Filename/g,
31
+ ];
32
+ const findings = [];
33
+ for (const re of patterns) {
34
+ findings.push(...grepRule(rule, ctx, re));
35
+ }
36
+ return findings;
37
+ },
38
+ };
39
+ export default rule;
40
+ //# sourceMappingURL=fileUpload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileUpload.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/fileUpload.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,sEAAsE;IAC7E,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,MAAM;IAChB,WAAW,EACT,qMAAqM;IACvM,MAAM,EAAE,sDAAsD;IAC9D,WAAW,EACT,4FAA4F;QAC5F,+EAA+E;QAC/E,0EAA0E;QAC1E,+EAA+E;QAC/E,iDAAiD;QACjD,qCAAqC;QACrC,8DAA8D;QAC9D,2CAA2C;IAC7C,UAAU,EAAE;QACV,0EAA0E;QAC1E,6EAA6E;KAC9E;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,0BAA0B;IACjC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,uCAAuC;YACjC,+CAA+C;YACrD,uCAAuC;YACvC,oCAAoC;YACpC,2CAA2C;SACtC,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../../types.js';
2
+ declare const rule: Rule;
3
+ export default rule;
@@ -0,0 +1,40 @@
1
+ import { grepRule } from '../_helpers.js';
2
+ const rule = {
3
+ id: 'BE-002',
4
+ title: 'Weak password hashing (MD5 / SHA-1 / SHA-256 / plain text)',
5
+ layer: 'backend',
6
+ severity: 'critical',
7
+ description: 'Parolalar MD5, SHA1, SHA256 veya duz metin olarak saklandiginda, veritabani sizintisinda aninda kirilabilir. Modern GPU\'lar MD5\'i saniyede milyarlarca kez deneyebilir.',
8
+ threat: 'Mass credential disclosure, credential stuffing on other services',
9
+ remediation: 'Parolalari **Argon2id** veya **bcrypt (work factor >= 12)** ile hashleyin. ' +
10
+ 'Her kullanici icin unique salt (Argon2/bcrypt otomatik ekler). ' +
11
+ 'Login sirasinda constant-time comparison kullanin. ' +
12
+ 'Yeni uyelikte minimum 12 karakter sifre zorunlulugu + zayif sifre listesi (HIBP). ' +
13
+ 'MFA\'yi yayginlastirin. Mevcut legacy hashleri acil olarak yeniden hashleyin.',
14
+ references: [
15
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html',
16
+ 'https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md',
17
+ 'https://auth0.com/blog/hashing-in-action-understanding-bcrypt-and-argon2/',
18
+ ],
19
+ cwe: 'CWE-916',
20
+ owasp: 'A02:2021 Cryptographic Failures',
21
+ languages: ['javascript', 'typescript', 'python', 'java', 'go'],
22
+ check: (ctx) => {
23
+ const patterns = [
24
+ /(?:createHash|hashlib\.\w+|MessageDigest\.getInstance)\s*\(\s*['"`](md5|sha1|sha-1|sha256|sha-256)['"`]/gi,
25
+ /['"`](md5|sha1|sha-1|sha256|sha-256)['"`]\s*\)/g,
26
+ /\bmd5\s*\(/gi,
27
+ /\bsha1\s*\(/gi,
28
+ /\bsha256\s*\(/gi,
29
+ /password\s*[:=]\s*req\.body\.(password|passwd|pwd)/gi,
30
+ /\bpassword\s*=\s*['"`][^'"`]+['"`]\s*[;\n]/g,
31
+ ];
32
+ const findings = [];
33
+ for (const re of patterns) {
34
+ findings.push(...grepRule(rule, ctx, re));
35
+ }
36
+ return findings;
37
+ },
38
+ };
39
+ export default rule;
40
+ //# sourceMappingURL=hashing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hashing.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/hashing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,4DAA4D;IACnE,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,UAAU;IACpB,WAAW,EACT,2KAA2K;IAC7K,MAAM,EAAE,mEAAmE;IAC3E,WAAW,EACT,6EAA6E;QAC7E,iEAAiE;QACjE,qDAAqD;QACrD,oFAAoF;QACpF,+EAA+E;IACjF,UAAU,EAAE;QACV,kFAAkF;QAClF,uEAAuE;QACvE,2EAA2E;KAC5E;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,iCAAiC;IACxC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,2GAA2G;YACrG,iDAAiD;YACjD,cAAc;YACd,eAAe;YACf,iBAAiB;YACvB,sDAAsD;YAChD,6CAA6C;SAC9C,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../../types.js';
2
+ declare const rule: Rule;
3
+ export default rule;
@@ -0,0 +1,40 @@
1
+ import { grepRule } from '../_helpers.js';
2
+ const rule = {
3
+ id: 'BE-001',
4
+ title: 'Potential IDOR / BOLA — ownership not verified',
5
+ layer: 'backend',
6
+ severity: 'high',
7
+ description: '`GET /api/resource/:id`, `app.get(\'/users/:id\')` gibi endpoint\'lerde, ID\'nin varligi kontrol edilse bile o kaynagin gercek sahibinin istegi yapan kullanici olup olmadigi sorgulanmiyor. Saldirgan baska kullanicilarin verilerine erisebilir (BOLA — Broken Object Level Authorization, OWASP API #1).',
8
+ threat: 'Unauthorized data access → account takeover, data breach, privacy violation',
9
+ remediation: 'Her resource erisiminden once sunucu tarafinda suni sorgu ekleyin: ' +
10
+ '`await db.resource.findFirst({ where: { id, ownerId: session.userId } })`. ' +
11
+ 'Ya da policy tabanli bir authz katmani kullanin (CASL, Oso, cerbos). ' +
12
+ 'Sadece `findUnique({ where: { id } })` ile cekmek YETERSIZ. ' +
13
+ 'Listeleme endpoint\'lerinde `where` filtresine her zaman `ownerId` ekleyin. ' +
14
+ 'Audit log ile anomalileri izleyin.',
15
+ references: [
16
+ 'https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/',
17
+ 'https://owasp.org/www-project-api-security/',
18
+ ],
19
+ cwe: 'CWE-639',
20
+ owasp: 'A01:2021 Broken Access Control',
21
+ languages: ['javascript', 'typescript', 'python', 'java', 'go'],
22
+ check: (ctx) => {
23
+ // This is a coarse heuristic — false positives are accepted in static analysis.
24
+ const suspiciousPatterns = [
25
+ /findUnique\s*\(\s*\{\s*where\s*:\s*\{\s*id\s*[:=]/g,
26
+ /findFirst\s*\(\s*\{\s*where\s*:\s*\{\s*id\s*[:=]/g,
27
+ /findOne\s*\(\s*\{\s*where\s*:\s*\{\s*id\s*[:=]/gi,
28
+ /findByPk\s*\(/g,
29
+ /getById\s*\(/g,
30
+ /\.find\s*\(\s*\{\s*id\s*[:=]/g,
31
+ ];
32
+ const findings = [];
33
+ for (const re of suspiciousPatterns) {
34
+ findings.push(...grepRule(rule, ctx, re));
35
+ }
36
+ return findings;
37
+ },
38
+ };
39
+ export default rule;
40
+ //# sourceMappingURL=idor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idor.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/idor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,gDAAgD;IACvD,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,MAAM;IAChB,WAAW,EACT,6SAA6S;IAC/S,MAAM,EAAE,6EAA6E;IACrF,WAAW,EACT,qEAAqE;QACrE,6EAA6E;QAC7E,uEAAuE;QACvE,8DAA8D;QAC9D,8EAA8E;QAC9E,oCAAoC;IACtC,UAAU,EAAE;QACV,yFAAyF;QACzF,6CAA6C;KAC9C;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,gCAAgC;IACvC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACjB,gFAAgF;QAC5E,MAAM,kBAAkB,GAAa;YACnC,oDAAoD;YACpD,mDAAmD;YACnD,kDAAkD;YAClD,gBAAgB;YAChB,eAAe;YACf,+BAA+B;SAChC,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,kBAAkB,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare const rules: {
2
+ idor: import("../../../types.js").Rule;
3
+ hashing: import("../../../types.js").Rule;
4
+ jwt: import("../../../types.js").Rule;
5
+ sqlInjection: import("../../../types.js").Rule;
6
+ inputValidation: import("../../../types.js").Rule;
7
+ rateLimit: import("../../../types.js").Rule;
8
+ fileUpload: import("../../../types.js").Rule;
9
+ tokenInUrl: import("../../../types.js").Rule;
10
+ tokenExpiry: import("../../../types.js").Rule;
11
+ };
12
+ export default rules;
@@ -0,0 +1,22 @@
1
+ import idor from './idor.js';
2
+ import hashing from './hashing.js';
3
+ import jwt from './jwt.js';
4
+ import sqlInjection from './sqlInjection.js';
5
+ import inputValidation from './inputValidation.js';
6
+ import rateLimit from './rateLimit.js';
7
+ import fileUpload from './fileUpload.js';
8
+ import tokenInUrl from './tokenInUrl.js';
9
+ import tokenExpiry from './tokenExpiry.js';
10
+ export const rules = {
11
+ idor,
12
+ hashing,
13
+ jwt,
14
+ sqlInjection,
15
+ inputValidation,
16
+ rateLimit,
17
+ fileUpload,
18
+ tokenInUrl,
19
+ tokenExpiry,
20
+ };
21
+ export default rules;
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,eAAe,MAAM,sBAAsB,CAAC;AACnD,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAE3C,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI;IACJ,OAAO;IACP,GAAG;IACH,YAAY;IACZ,eAAe;IACf,SAAS;IACT,UAAU;IACV,UAAU;IACV,WAAW;CACZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../../types.js';
2
+ declare const rule: Rule;
3
+ export default rule;
@@ -0,0 +1,37 @@
1
+ import { grepRule } from '../_helpers.js';
2
+ const rule = {
3
+ id: 'BE-005',
4
+ title: 'Mass assignment — input not validated against DTO',
5
+ layer: 'backend',
6
+ severity: 'high',
7
+ description: '`req.body` veya `request.json()`\'i dogrudan ORM\'a vermek (prisma.user.create({ data: req.body })) mass assignment saldirisina aciktir. Saldirgan `role: "admin"`, `isAdmin: true`, `balance: 99999` gibi alanlari enjekte edebilir.',
8
+ threat: 'Privilege escalation, data tampering, business logic bypass',
9
+ remediation: '1) **Zod / Joi / class-validator** ile explicit DTO semasi tanimlayin. ' +
10
+ '2) Schema\'da olmayan alanlari `.strict()` ile reddedin. ' +
11
+ '3) Sadece schema\'da tanimli alanlari ORM\'a gecirin: `prisma.user.create({ data: parsed.data })`. ' +
12
+ '4) `Object.assign(user, req.body)` veya spread `{...req.body, ...overrides}` yapilarindan kacinin. ' +
13
+ '5) Default olarak tum update endpointleri "PUT yerine PATCH" ile alan-bazli olmali.',
14
+ references: [
15
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html',
16
+ 'https://zod.dev/',
17
+ ],
18
+ cwe: 'CWE-915',
19
+ owasp: 'A04:2021 Insecure Design',
20
+ languages: ['javascript', 'typescript', 'python', 'java', 'go'],
21
+ check: (ctx) => {
22
+ const patterns = [
23
+ /\.(?:create|update|upsert)\s*\(\s*\{\s*data\s*:\s*(?:req\.body|request\.body|request\.json\(\)|input|body)/gi,
24
+ /\.(?:create|update|upsert)\s*\(\s*(?:req\.body|request\.body|request\.json\(\)|input|body)\b/gi,
25
+ /@ModelAttribute\s+\w+\s+\w+/g,
26
+ /(?:ModelForm|form\.save)\(\)/g,
27
+ /c\.BindJSON\s*\(\s*[a-zA-Z_][a-zA-Z0-9_]*\s*\)/g,
28
+ ];
29
+ const findings = [];
30
+ for (const re of patterns) {
31
+ findings.push(...grepRule(rule, ctx, re));
32
+ }
33
+ return findings;
34
+ },
35
+ };
36
+ export default rule;
37
+ //# sourceMappingURL=inputValidation.js.map