@nahisaho/musubix-security 1.8.0 → 1.8.1

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 (186) hide show
  1. package/README.md +27 -0
  2. package/dist/analyzers/ai/index.d.ts +6 -0
  3. package/dist/analyzers/ai/index.d.ts.map +1 -0
  4. package/dist/analyzers/ai/index.js +6 -0
  5. package/dist/analyzers/ai/index.js.map +1 -0
  6. package/dist/analyzers/ai/prompt-injection-detector.d.ts +152 -0
  7. package/dist/analyzers/ai/prompt-injection-detector.d.ts.map +1 -0
  8. package/dist/analyzers/ai/prompt-injection-detector.js +468 -0
  9. package/dist/analyzers/ai/prompt-injection-detector.js.map +1 -0
  10. package/dist/analyzers/api/api-security-analyzer.d.ts +263 -0
  11. package/dist/analyzers/api/api-security-analyzer.d.ts.map +1 -0
  12. package/dist/analyzers/api/api-security-analyzer.js +581 -0
  13. package/dist/analyzers/api/api-security-analyzer.js.map +1 -0
  14. package/dist/analyzers/compliance/compliance-checker.d.ts +201 -0
  15. package/dist/analyzers/compliance/compliance-checker.d.ts.map +1 -0
  16. package/dist/analyzers/compliance/compliance-checker.js +772 -0
  17. package/dist/analyzers/compliance/compliance-checker.js.map +1 -0
  18. package/dist/analyzers/container/image-scanner.d.ts +163 -0
  19. package/dist/analyzers/container/image-scanner.d.ts.map +1 -0
  20. package/dist/analyzers/container/image-scanner.js +459 -0
  21. package/dist/analyzers/container/image-scanner.js.map +1 -0
  22. package/dist/analyzers/container/index.d.ts +6 -0
  23. package/dist/analyzers/container/index.d.ts.map +1 -0
  24. package/dist/analyzers/container/index.js +6 -0
  25. package/dist/analyzers/container/index.js.map +1 -0
  26. package/dist/analyzers/dashboard/security-dashboard.d.ts +286 -0
  27. package/dist/analyzers/dashboard/security-dashboard.d.ts.map +1 -0
  28. package/dist/analyzers/dashboard/security-dashboard.js +796 -0
  29. package/dist/analyzers/dashboard/security-dashboard.js.map +1 -0
  30. package/dist/analyzers/iac/iac-checker.d.ts +124 -0
  31. package/dist/analyzers/iac/iac-checker.d.ts.map +1 -0
  32. package/dist/analyzers/iac/iac-checker.js +755 -0
  33. package/dist/analyzers/iac/iac-checker.js.map +1 -0
  34. package/dist/analyzers/iac/index.d.ts +6 -0
  35. package/dist/analyzers/iac/index.d.ts.map +1 -0
  36. package/dist/analyzers/iac/index.js +6 -0
  37. package/dist/analyzers/iac/index.js.map +1 -0
  38. package/dist/analyzers/index.d.ts +9 -0
  39. package/dist/analyzers/index.d.ts.map +1 -0
  40. package/dist/analyzers/index.js +13 -0
  41. package/dist/analyzers/index.js.map +1 -0
  42. package/dist/analyzers/monitor/realtime-monitor.d.ts +216 -0
  43. package/dist/analyzers/monitor/realtime-monitor.d.ts.map +1 -0
  44. package/dist/analyzers/monitor/realtime-monitor.js +601 -0
  45. package/dist/analyzers/monitor/realtime-monitor.js.map +1 -0
  46. package/dist/analyzers/sast/index.d.ts +7 -0
  47. package/dist/analyzers/sast/index.d.ts.map +1 -0
  48. package/dist/analyzers/sast/index.js +7 -0
  49. package/dist/analyzers/sast/index.js.map +1 -0
  50. package/dist/analyzers/sast/interprocedural-analyzer.d.ts +276 -0
  51. package/dist/analyzers/sast/interprocedural-analyzer.d.ts.map +1 -0
  52. package/dist/analyzers/sast/interprocedural-analyzer.js +635 -0
  53. package/dist/analyzers/sast/interprocedural-analyzer.js.map +1 -0
  54. package/dist/analyzers/sast/zero-day-detector.d.ts +183 -0
  55. package/dist/analyzers/sast/zero-day-detector.d.ts.map +1 -0
  56. package/dist/analyzers/sast/zero-day-detector.js +593 -0
  57. package/dist/analyzers/sast/zero-day-detector.js.map +1 -0
  58. package/dist/analyzers/sca/dependency-scanner.d.ts +275 -0
  59. package/dist/analyzers/sca/dependency-scanner.d.ts.map +1 -0
  60. package/dist/analyzers/sca/dependency-scanner.js +642 -0
  61. package/dist/analyzers/sca/dependency-scanner.js.map +1 -0
  62. package/dist/core/index.d.ts +8 -0
  63. package/dist/core/index.d.ts.map +1 -0
  64. package/dist/core/index.js +10 -0
  65. package/dist/core/index.js.map +1 -0
  66. package/dist/core/pipeline-manager.d.ts +105 -0
  67. package/dist/core/pipeline-manager.d.ts.map +1 -0
  68. package/dist/core/pipeline-manager.js +449 -0
  69. package/dist/core/pipeline-manager.js.map +1 -0
  70. package/dist/core/result-aggregator.d.ts +96 -0
  71. package/dist/core/result-aggregator.d.ts.map +1 -0
  72. package/dist/core/result-aggregator.js +462 -0
  73. package/dist/core/result-aggregator.js.map +1 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +68 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/integrations/ci-integration.d.ts +227 -0
  79. package/dist/integrations/ci-integration.d.ts.map +1 -0
  80. package/dist/integrations/ci-integration.js +472 -0
  81. package/dist/integrations/ci-integration.js.map +1 -0
  82. package/dist/integrations/git-hooks.d.ts +155 -0
  83. package/dist/integrations/git-hooks.d.ts.map +1 -0
  84. package/dist/integrations/git-hooks.js +425 -0
  85. package/dist/integrations/git-hooks.js.map +1 -0
  86. package/dist/integrations/index.d.ts +9 -0
  87. package/dist/integrations/index.d.ts.map +1 -0
  88. package/dist/integrations/index.js +9 -0
  89. package/dist/integrations/index.js.map +1 -0
  90. package/dist/integrations/report-aggregator.d.ts +250 -0
  91. package/dist/integrations/report-aggregator.d.ts.map +1 -0
  92. package/dist/integrations/report-aggregator.js +488 -0
  93. package/dist/integrations/report-aggregator.js.map +1 -0
  94. package/dist/integrations/vscode-integration.d.ts +245 -0
  95. package/dist/integrations/vscode-integration.d.ts.map +1 -0
  96. package/dist/integrations/vscode-integration.js +449 -0
  97. package/dist/integrations/vscode-integration.js.map +1 -0
  98. package/dist/intelligence/attack-pattern-matcher.d.ts +217 -0
  99. package/dist/intelligence/attack-pattern-matcher.d.ts.map +1 -0
  100. package/dist/intelligence/attack-pattern-matcher.js +887 -0
  101. package/dist/intelligence/attack-pattern-matcher.js.map +1 -0
  102. package/dist/intelligence/index.d.ts +12 -0
  103. package/dist/intelligence/index.d.ts.map +1 -0
  104. package/dist/intelligence/index.js +18 -0
  105. package/dist/intelligence/index.js.map +1 -0
  106. package/dist/intelligence/neuro-symbolic-core.d.ts +88 -0
  107. package/dist/intelligence/neuro-symbolic-core.d.ts.map +1 -0
  108. package/dist/intelligence/neuro-symbolic-core.js +403 -0
  109. package/dist/intelligence/neuro-symbolic-core.js.map +1 -0
  110. package/dist/intelligence/predictive-analyzer.d.ts +317 -0
  111. package/dist/intelligence/predictive-analyzer.d.ts.map +1 -0
  112. package/dist/intelligence/predictive-analyzer.js +714 -0
  113. package/dist/intelligence/predictive-analyzer.js.map +1 -0
  114. package/dist/intelligence/risk-scorer.d.ts +333 -0
  115. package/dist/intelligence/risk-scorer.d.ts.map +1 -0
  116. package/dist/intelligence/risk-scorer.js +824 -0
  117. package/dist/intelligence/risk-scorer.js.map +1 -0
  118. package/dist/intelligence/security-analytics.d.ts +349 -0
  119. package/dist/intelligence/security-analytics.d.ts.map +1 -0
  120. package/dist/intelligence/security-analytics.js +813 -0
  121. package/dist/intelligence/security-analytics.js.map +1 -0
  122. package/dist/intelligence/threat-intelligence.d.ts +288 -0
  123. package/dist/intelligence/threat-intelligence.d.ts.map +1 -0
  124. package/dist/intelligence/threat-intelligence.js +639 -0
  125. package/dist/intelligence/threat-intelligence.js.map +1 -0
  126. package/dist/policy/index.d.ts +6 -0
  127. package/dist/policy/index.d.ts.map +1 -0
  128. package/dist/policy/index.js +6 -0
  129. package/dist/policy/index.js.map +1 -0
  130. package/dist/policy/policy-engine.d.ts +254 -0
  131. package/dist/policy/policy-engine.d.ts.map +1 -0
  132. package/dist/policy/policy-engine.js +651 -0
  133. package/dist/policy/policy-engine.js.map +1 -0
  134. package/dist/remediation/auto-fixer.d.ts +179 -0
  135. package/dist/remediation/auto-fixer.d.ts.map +1 -0
  136. package/dist/remediation/auto-fixer.js +540 -0
  137. package/dist/remediation/auto-fixer.js.map +1 -0
  138. package/dist/remediation/fix-validator.d.ts +195 -0
  139. package/dist/remediation/fix-validator.d.ts.map +1 -0
  140. package/dist/remediation/fix-validator.js +462 -0
  141. package/dist/remediation/fix-validator.js.map +1 -0
  142. package/dist/remediation/index.d.ts +10 -0
  143. package/dist/remediation/index.d.ts.map +1 -0
  144. package/dist/remediation/index.js +15 -0
  145. package/dist/remediation/index.js.map +1 -0
  146. package/dist/remediation/patch-generator.d.ts +203 -0
  147. package/dist/remediation/patch-generator.d.ts.map +1 -0
  148. package/dist/remediation/patch-generator.js +533 -0
  149. package/dist/remediation/patch-generator.js.map +1 -0
  150. package/dist/remediation/remediation-planner.d.ts +262 -0
  151. package/dist/remediation/remediation-planner.d.ts.map +1 -0
  152. package/dist/remediation/remediation-planner.js +531 -0
  153. package/dist/remediation/remediation-planner.js.map +1 -0
  154. package/dist/remediation/secure-code-transformer.d.ts +222 -0
  155. package/dist/remediation/secure-code-transformer.d.ts.map +1 -0
  156. package/dist/remediation/secure-code-transformer.js +625 -0
  157. package/dist/remediation/secure-code-transformer.js.map +1 -0
  158. package/dist/types/fix.d.ts +3 -1
  159. package/dist/types/fix.d.ts.map +1 -1
  160. package/dist/types/index.d.ts +6 -0
  161. package/dist/types/index.d.ts.map +1 -1
  162. package/dist/types/index.js +1 -0
  163. package/dist/types/index.js.map +1 -1
  164. package/dist/types/interprocedural.d.ts +203 -0
  165. package/dist/types/interprocedural.d.ts.map +1 -0
  166. package/dist/types/interprocedural.js +7 -0
  167. package/dist/types/interprocedural.js.map +1 -0
  168. package/dist/types/neuro-symbolic.d.ts +179 -0
  169. package/dist/types/neuro-symbolic.d.ts.map +1 -0
  170. package/dist/types/neuro-symbolic.js +7 -0
  171. package/dist/types/neuro-symbolic.js.map +1 -0
  172. package/dist/types/pipeline.d.ts +173 -0
  173. package/dist/types/pipeline.d.ts.map +1 -0
  174. package/dist/types/pipeline.js +7 -0
  175. package/dist/types/pipeline.js.map +1 -0
  176. package/dist/types/result.d.ts +134 -0
  177. package/dist/types/result.d.ts.map +1 -0
  178. package/dist/types/result.js +25 -0
  179. package/dist/types/result.js.map +1 -0
  180. package/dist/types/vulnerability.d.ts +2 -2
  181. package/dist/types/vulnerability.d.ts.map +1 -1
  182. package/dist/types/zero-day.d.ts +146 -0
  183. package/dist/types/zero-day.d.ts.map +1 -0
  184. package/dist/types/zero-day.js +7 -0
  185. package/dist/types/zero-day.js.map +1 -0
  186. package/package.json +2 -2
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @fileoverview Fix Validator for Security Fixes
3
+ * @module @nahisaho/musubix-security/remediation/fix-validator
4
+ *
5
+ * Validates security fixes before and after application to ensure
6
+ * they correctly address vulnerabilities without introducing new issues.
7
+ */
8
+ import type { Fix, Vulnerability, SourceLocation } from '../types/index.js';
9
+ /**
10
+ * Validation result
11
+ */
12
+ export interface ValidationResult {
13
+ /** Whether validation passed */
14
+ valid: boolean;
15
+ /** Fix that was validated */
16
+ fixId: string;
17
+ /** Validation checks performed */
18
+ checks: ValidationCheck[];
19
+ /** Overall score (0-100) */
20
+ score: number;
21
+ /** Recommendations */
22
+ recommendations: string[];
23
+ /** Validation timestamp */
24
+ timestamp: Date;
25
+ }
26
+ /**
27
+ * Individual validation check
28
+ */
29
+ export interface ValidationCheck {
30
+ /** Check name */
31
+ name: string;
32
+ /** Check category */
33
+ category: 'syntax' | 'semantic' | 'security' | 'regression' | 'compatibility';
34
+ /** Whether check passed */
35
+ passed: boolean;
36
+ /** Check details */
37
+ details: string;
38
+ /** Severity if failed */
39
+ severity?: 'error' | 'warning' | 'info';
40
+ }
41
+ /**
42
+ * Syntax validation result
43
+ */
44
+ export interface SyntaxValidationResult {
45
+ /** Whether syntax is valid */
46
+ valid: boolean;
47
+ /** Syntax errors */
48
+ errors: SyntaxError[];
49
+ /** Abstract syntax tree available */
50
+ hasAST: boolean;
51
+ }
52
+ /**
53
+ * Syntax error
54
+ */
55
+ export interface SyntaxError {
56
+ /** Error message */
57
+ message: string;
58
+ /** Location */
59
+ location?: SourceLocation;
60
+ /** Error code */
61
+ code?: string;
62
+ }
63
+ /**
64
+ * Regression test result
65
+ */
66
+ export interface RegressionTestResult {
67
+ /** Total tests */
68
+ total: number;
69
+ /** Passed tests */
70
+ passed: number;
71
+ /** Failed tests */
72
+ failed: number;
73
+ /** Skipped tests */
74
+ skipped: number;
75
+ /** Test details */
76
+ details: TestDetail[];
77
+ }
78
+ /**
79
+ * Test detail
80
+ */
81
+ export interface TestDetail {
82
+ /** Test name */
83
+ name: string;
84
+ /** Test status */
85
+ status: 'passed' | 'failed' | 'skipped';
86
+ /** Duration in ms */
87
+ duration: number;
88
+ /** Error if failed */
89
+ error?: string;
90
+ }
91
+ /**
92
+ * Security re-scan result
93
+ */
94
+ export interface SecurityRescanResult {
95
+ /** Original vulnerability resolved */
96
+ vulnerabilityResolved: boolean;
97
+ /** New vulnerabilities introduced */
98
+ newVulnerabilities: Vulnerability[];
99
+ /** Remaining vulnerabilities */
100
+ remainingVulnerabilities: Vulnerability[];
101
+ /** Security improvement score */
102
+ improvementScore: number;
103
+ }
104
+ /**
105
+ * Fix validator options
106
+ */
107
+ export interface FixValidatorOptions {
108
+ /** Enable syntax validation */
109
+ syntaxValidation?: boolean;
110
+ /** Enable semantic validation */
111
+ semanticValidation?: boolean;
112
+ /** Enable security re-scan */
113
+ securityRescan?: boolean;
114
+ /** Enable regression testing */
115
+ regressionTesting?: boolean;
116
+ /** Strict mode (fail on warnings) */
117
+ strictMode?: boolean;
118
+ /** Custom validation rules */
119
+ customRules?: CustomValidationRule[];
120
+ }
121
+ /**
122
+ * Custom validation rule
123
+ */
124
+ export interface CustomValidationRule {
125
+ /** Rule ID */
126
+ id: string;
127
+ /** Rule name */
128
+ name: string;
129
+ /** Validation function */
130
+ validate: (fix: Fix, originalCode: string, fixedCode: string) => ValidationCheck;
131
+ }
132
+ /**
133
+ * Validator for security fixes
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const validator = createFixValidator();
138
+ * const result = await validator.validate(fix, originalCode, fixedCode);
139
+ * if (!result.valid) {
140
+ * console.log('Fix validation failed:', result.checks);
141
+ * }
142
+ * ```
143
+ */
144
+ export declare class FixValidator {
145
+ private options;
146
+ private customRules;
147
+ constructor(options?: FixValidatorOptions);
148
+ /**
149
+ * Validate a fix
150
+ */
151
+ validate(fix: Fix, originalCode: string, fixedCode: string, _originalVulnerability?: Vulnerability): Promise<ValidationResult>;
152
+ /**
153
+ * Validate fix syntax
154
+ */
155
+ validateSyntax(code: string): ValidationCheck;
156
+ /**
157
+ * Validate semantic properties
158
+ */
159
+ validateSemantics(originalCode: string, fixedCode: string): ValidationCheck[];
160
+ /**
161
+ * Validate security properties of the fix
162
+ */
163
+ validateSecurityProperties(fix: Fix, fixedCode: string): ValidationCheck[];
164
+ /**
165
+ * Register a custom validation rule
166
+ */
167
+ registerRule(rule: CustomValidationRule): void;
168
+ /**
169
+ * Remove a custom validation rule
170
+ */
171
+ removeRule(ruleId: string): boolean;
172
+ /**
173
+ * Get all validation rules
174
+ */
175
+ getRules(): CustomValidationRule[];
176
+ private validateFixStructure;
177
+ private checkBalancedBrackets;
178
+ private checkCommonSyntaxIssues;
179
+ private checkStructurePreservation;
180
+ private checkVariableUsage;
181
+ private fixAddressesVulnerabilityType;
182
+ private checkSecurityAntiPatterns;
183
+ private checkDangerousFunctions;
184
+ private calculateScore;
185
+ private determineValidity;
186
+ }
187
+ /**
188
+ * Create a fix validator
189
+ */
190
+ export declare function createFixValidator(options?: FixValidatorOptions): FixValidator;
191
+ /**
192
+ * Quick validate a fix
193
+ */
194
+ export declare function quickValidate(fix: Fix, originalCode: string, fixedCode: string): Promise<boolean>;
195
+ //# sourceMappingURL=fix-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-validator.d.ts","sourceRoot":"","sources":["../../src/remediation/fix-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,462 @@
1
+ /**
2
+ * @fileoverview Fix Validator for Security Fixes
3
+ * @module @nahisaho/musubix-security/remediation/fix-validator
4
+ *
5
+ * Validates security fixes before and after application to ensure
6
+ * they correctly address vulnerabilities without introducing new issues.
7
+ */
8
+ // ============================================================================
9
+ // FixValidator Class
10
+ // ============================================================================
11
+ /**
12
+ * Validator for security fixes
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const validator = createFixValidator();
17
+ * const result = await validator.validate(fix, originalCode, fixedCode);
18
+ * if (!result.valid) {
19
+ * console.log('Fix validation failed:', result.checks);
20
+ * }
21
+ * ```
22
+ */
23
+ export class FixValidator {
24
+ options;
25
+ customRules;
26
+ constructor(options = {}) {
27
+ this.options = {
28
+ syntaxValidation: options.syntaxValidation ?? true,
29
+ semanticValidation: options.semanticValidation ?? true,
30
+ securityRescan: options.securityRescan ?? true,
31
+ regressionTesting: options.regressionTesting ?? false,
32
+ strictMode: options.strictMode ?? false,
33
+ customRules: options.customRules ?? [],
34
+ };
35
+ this.customRules = new Map();
36
+ for (const rule of this.options.customRules) {
37
+ this.customRules.set(rule.id, rule);
38
+ }
39
+ }
40
+ /**
41
+ * Validate a fix
42
+ */
43
+ async validate(fix, originalCode, fixedCode, _originalVulnerability) {
44
+ const checks = [];
45
+ const recommendations = [];
46
+ // Basic fix validation
47
+ checks.push(this.validateFixStructure(fix));
48
+ // Syntax validation
49
+ if (this.options.syntaxValidation) {
50
+ const syntaxCheck = this.validateSyntax(fixedCode);
51
+ checks.push(syntaxCheck);
52
+ if (!syntaxCheck.passed) {
53
+ recommendations.push('Fix the syntax errors before applying this fix');
54
+ }
55
+ }
56
+ // Semantic validation
57
+ if (this.options.semanticValidation) {
58
+ const semanticChecks = this.validateSemantics(originalCode, fixedCode);
59
+ checks.push(...semanticChecks);
60
+ }
61
+ // Security checks
62
+ checks.push(...this.validateSecurityProperties(fix, fixedCode));
63
+ // Custom rules
64
+ for (const rule of this.customRules.values()) {
65
+ try {
66
+ const check = rule.validate(fix, originalCode, fixedCode);
67
+ checks.push(check);
68
+ }
69
+ catch (error) {
70
+ checks.push({
71
+ name: rule.name,
72
+ category: 'security',
73
+ passed: false,
74
+ details: `Custom rule failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
75
+ severity: 'warning',
76
+ });
77
+ }
78
+ }
79
+ // Calculate score
80
+ const score = this.calculateScore(checks);
81
+ // Determine validity
82
+ const valid = this.determineValidity(checks);
83
+ // Generate additional recommendations
84
+ if (fix.breakingChange) {
85
+ recommendations.push('This fix may cause breaking changes - review carefully');
86
+ }
87
+ if (fix.confidence < 0.8) {
88
+ recommendations.push('Low confidence fix - manual review recommended');
89
+ }
90
+ return {
91
+ valid,
92
+ fixId: fix.id,
93
+ checks,
94
+ score,
95
+ recommendations,
96
+ timestamp: new Date(),
97
+ };
98
+ }
99
+ /**
100
+ * Validate fix syntax
101
+ */
102
+ validateSyntax(code) {
103
+ const errors = [];
104
+ // Basic syntax checks
105
+ try {
106
+ // Check for balanced brackets
107
+ const balanced = this.checkBalancedBrackets(code);
108
+ if (!balanced.valid) {
109
+ errors.push({ message: balanced.message });
110
+ }
111
+ // Check for common syntax issues
112
+ const commonIssues = this.checkCommonSyntaxIssues(code);
113
+ errors.push(...commonIssues);
114
+ }
115
+ catch (error) {
116
+ errors.push({
117
+ message: error instanceof Error ? error.message : 'Unknown syntax error',
118
+ });
119
+ }
120
+ return {
121
+ name: 'Syntax Validation',
122
+ category: 'syntax',
123
+ passed: errors.length === 0,
124
+ details: errors.length === 0
125
+ ? 'Syntax validation passed'
126
+ : `Found ${errors.length} syntax error(s): ${errors.map(e => e.message).join(', ')}`,
127
+ severity: errors.length > 0 ? 'error' : undefined,
128
+ };
129
+ }
130
+ /**
131
+ * Validate semantic properties
132
+ */
133
+ validateSemantics(originalCode, fixedCode) {
134
+ const checks = [];
135
+ // Check code length change
136
+ const lengthRatio = fixedCode.length / originalCode.length;
137
+ checks.push({
138
+ name: 'Code Size Change',
139
+ category: 'semantic',
140
+ passed: lengthRatio > 0.5 && lengthRatio < 2.0,
141
+ details: `Code size changed by ${((lengthRatio - 1) * 100).toFixed(1)}%`,
142
+ severity: lengthRatio > 2.0 || lengthRatio < 0.5 ? 'warning' : undefined,
143
+ });
144
+ // Check for preserved structure
145
+ const structurePreserved = this.checkStructurePreservation(originalCode, fixedCode);
146
+ checks.push({
147
+ name: 'Structure Preservation',
148
+ category: 'semantic',
149
+ passed: structurePreserved,
150
+ details: structurePreserved
151
+ ? 'Code structure largely preserved'
152
+ : 'Significant structural changes detected',
153
+ severity: !structurePreserved ? 'warning' : undefined,
154
+ });
155
+ // Check for variable usage
156
+ const variableCheck = this.checkVariableUsage(originalCode, fixedCode);
157
+ checks.push(variableCheck);
158
+ return checks;
159
+ }
160
+ /**
161
+ * Validate security properties of the fix
162
+ */
163
+ validateSecurityProperties(fix, fixedCode) {
164
+ const checks = [];
165
+ // Check if fix addresses the vulnerability type
166
+ checks.push({
167
+ name: 'Vulnerability Type Match',
168
+ category: 'security',
169
+ passed: this.fixAddressesVulnerabilityType(fix),
170
+ details: `Fix strategy '${fix.strategy}' for vulnerability`,
171
+ });
172
+ // Check for security anti-patterns in fixed code
173
+ const antiPatterns = this.checkSecurityAntiPatterns(fixedCode);
174
+ checks.push({
175
+ name: 'Security Anti-patterns',
176
+ category: 'security',
177
+ passed: antiPatterns.length === 0,
178
+ details: antiPatterns.length === 0
179
+ ? 'No security anti-patterns detected'
180
+ : `Found anti-patterns: ${antiPatterns.join(', ')}`,
181
+ severity: antiPatterns.length > 0 ? 'error' : undefined,
182
+ });
183
+ // Check for dangerous function usage
184
+ const dangerousFunctions = this.checkDangerousFunctions(fixedCode);
185
+ checks.push({
186
+ name: 'Dangerous Functions',
187
+ category: 'security',
188
+ passed: dangerousFunctions.length === 0,
189
+ details: dangerousFunctions.length === 0
190
+ ? 'No dangerous functions detected'
191
+ : `Found dangerous functions: ${dangerousFunctions.join(', ')}`,
192
+ severity: dangerousFunctions.length > 0 ? 'warning' : undefined,
193
+ });
194
+ return checks;
195
+ }
196
+ /**
197
+ * Register a custom validation rule
198
+ */
199
+ registerRule(rule) {
200
+ this.customRules.set(rule.id, rule);
201
+ }
202
+ /**
203
+ * Remove a custom validation rule
204
+ */
205
+ removeRule(ruleId) {
206
+ return this.customRules.delete(ruleId);
207
+ }
208
+ /**
209
+ * Get all validation rules
210
+ */
211
+ getRules() {
212
+ return Array.from(this.customRules.values());
213
+ }
214
+ // ============================================================================
215
+ // Private Methods
216
+ // ============================================================================
217
+ validateFixStructure(fix) {
218
+ const issues = [];
219
+ if (!fix.id)
220
+ issues.push('Missing fix ID');
221
+ if (!fix.vulnerabilityId)
222
+ issues.push('Missing vulnerability reference');
223
+ if (!fix.strategy)
224
+ issues.push('Missing fix strategy');
225
+ if (!fix.edits || fix.edits.length === 0)
226
+ issues.push('No edits specified');
227
+ return {
228
+ name: 'Fix Structure',
229
+ category: 'syntax',
230
+ passed: issues.length === 0,
231
+ details: issues.length === 0
232
+ ? 'Fix structure is valid'
233
+ : `Structure issues: ${issues.join(', ')}`,
234
+ severity: issues.length > 0 ? 'error' : undefined,
235
+ };
236
+ }
237
+ checkBalancedBrackets(code) {
238
+ const stack = [];
239
+ const pairs = { '(': ')', '[': ']', '{': '}' };
240
+ const openers = new Set(Object.keys(pairs));
241
+ const closers = new Set(Object.values(pairs));
242
+ // Track if we're in a string or comment
243
+ let inString = false;
244
+ let stringChar = '';
245
+ let inSingleLineComment = false;
246
+ let inMultiLineComment = false;
247
+ for (let i = 0; i < code.length; i++) {
248
+ const char = code[i];
249
+ const prevChar = i > 0 ? code[i - 1] : '';
250
+ const nextChar = i < code.length - 1 ? code[i + 1] : '';
251
+ // Handle comments
252
+ if (!inString) {
253
+ if (char === '/' && nextChar === '/' && !inMultiLineComment) {
254
+ inSingleLineComment = true;
255
+ continue;
256
+ }
257
+ if (char === '/' && nextChar === '*' && !inSingleLineComment) {
258
+ inMultiLineComment = true;
259
+ continue;
260
+ }
261
+ if (char === '\n' && inSingleLineComment) {
262
+ inSingleLineComment = false;
263
+ continue;
264
+ }
265
+ if (char === '*' && nextChar === '/' && inMultiLineComment) {
266
+ inMultiLineComment = false;
267
+ i++; // Skip the '/'
268
+ continue;
269
+ }
270
+ }
271
+ if (inSingleLineComment || inMultiLineComment)
272
+ continue;
273
+ // Handle strings
274
+ if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
275
+ if (!inString) {
276
+ inString = true;
277
+ stringChar = char;
278
+ }
279
+ else if (char === stringChar) {
280
+ inString = false;
281
+ stringChar = '';
282
+ }
283
+ continue;
284
+ }
285
+ if (inString)
286
+ continue;
287
+ // Check brackets
288
+ if (openers.has(char)) {
289
+ stack.push(char);
290
+ }
291
+ else if (closers.has(char)) {
292
+ if (stack.length === 0) {
293
+ return { valid: false, message: `Unmatched closing bracket '${char}'` };
294
+ }
295
+ const opener = stack.pop();
296
+ if (pairs[opener] !== char) {
297
+ return { valid: false, message: `Mismatched brackets: '${opener}' and '${char}'` };
298
+ }
299
+ }
300
+ }
301
+ if (stack.length > 0) {
302
+ return { valid: false, message: `Unclosed brackets: ${stack.join(', ')}` };
303
+ }
304
+ return { valid: true, message: 'Brackets are balanced' };
305
+ }
306
+ checkCommonSyntaxIssues(code) {
307
+ const errors = [];
308
+ // Check for duplicate operators
309
+ if (/[+\-*\/]{3,}/.test(code)) {
310
+ errors.push({ message: 'Multiple consecutive operators detected' });
311
+ }
312
+ // Check for obvious missing semicolons (conservative)
313
+ // Note: Modern JS allows ASI, so we only flag clear issues
314
+ const lines = code.split('\n');
315
+ for (let i = 0; i < lines.length; i++) {
316
+ const trimmed = lines[i].trim();
317
+ // Check for specific patterns that almost always need semicolons
318
+ if (/^(const|let|var)\s+\w+\s*=\s*[^{[\n]+\s*$/.test(trimmed) &&
319
+ !trimmed.endsWith(';') &&
320
+ !trimmed.endsWith(',')) {
321
+ // Only flag if next line starts with something that would cause issues
322
+ const nextLine = lines[i + 1]?.trim() || '';
323
+ if (nextLine.startsWith('(') || nextLine.startsWith('[')) {
324
+ // Potential ASI hazard - but still don't flag as error
325
+ }
326
+ }
327
+ }
328
+ return errors;
329
+ }
330
+ checkStructurePreservation(original, fixed) {
331
+ // Count key structural elements
332
+ const countStructure = (code) => ({
333
+ functions: (code.match(/function\s+\w+/g) || []).length,
334
+ classes: (code.match(/class\s+\w+/g) || []).length,
335
+ arrows: (code.match(/=>/g) || []).length,
336
+ returns: (code.match(/return\s/g) || []).length,
337
+ });
338
+ const originalStructure = countStructure(original);
339
+ const fixedStructure = countStructure(fixed);
340
+ // Allow some variation but flag major changes
341
+ const functionDiff = Math.abs(originalStructure.functions - fixedStructure.functions);
342
+ const classDiff = Math.abs(originalStructure.classes - fixedStructure.classes);
343
+ return functionDiff <= 1 && classDiff === 0;
344
+ }
345
+ checkVariableUsage(original, fixed) {
346
+ // Extract variable declarations
347
+ const extractVars = (code) => {
348
+ const vars = new Set();
349
+ const matches = code.matchAll(/(?:const|let|var)\s+(\w+)/g);
350
+ for (const match of matches) {
351
+ vars.add(match[1]);
352
+ }
353
+ return vars;
354
+ };
355
+ const originalVars = extractVars(original);
356
+ const fixedVars = extractVars(fixed);
357
+ // Check for removed variables (might indicate important code removal)
358
+ const removedVars = [...originalVars].filter(v => !fixedVars.has(v));
359
+ return {
360
+ name: 'Variable Usage',
361
+ category: 'semantic',
362
+ passed: removedVars.length <= 2,
363
+ details: removedVars.length === 0
364
+ ? 'All original variables preserved'
365
+ : `${removedVars.length} variable(s) removed: ${removedVars.join(', ')}`,
366
+ severity: removedVars.length > 2 ? 'warning' : undefined,
367
+ };
368
+ }
369
+ fixAddressesVulnerabilityType(fix) {
370
+ // Map strategies to what they address
371
+ const strategyMap = {
372
+ sanitization: ['xss', 'injection', 'html_injection'],
373
+ encoding: ['xss', 'html_injection'],
374
+ parameterization: ['sql_injection', 'injection'],
375
+ validation: ['path_traversal', 'injection', 'input_validation'],
376
+ configuration: ['hardcoded_secret', 'exposed_credential', 'misconfiguration'],
377
+ replacement: ['weak_cryptography', 'deprecated_api'],
378
+ access_control: ['authentication', 'authorization', 'access_control'],
379
+ };
380
+ const addressedTypes = strategyMap[fix.strategy] || [];
381
+ return addressedTypes.length > 0;
382
+ }
383
+ checkSecurityAntiPatterns(code) {
384
+ const antiPatterns = [];
385
+ // eval usage
386
+ if (/\beval\s*\(/.test(code)) {
387
+ antiPatterns.push('eval()');
388
+ }
389
+ // innerHTML without sanitization
390
+ if (/\.innerHTML\s*=/.test(code) && !/sanitize|DOMPurify/i.test(code)) {
391
+ antiPatterns.push('innerHTML without sanitization');
392
+ }
393
+ // document.write
394
+ if (/document\.write\s*\(/.test(code)) {
395
+ antiPatterns.push('document.write()');
396
+ }
397
+ // new Function()
398
+ if (/new\s+Function\s*\(/.test(code)) {
399
+ antiPatterns.push('new Function()');
400
+ }
401
+ return antiPatterns;
402
+ }
403
+ checkDangerousFunctions(code) {
404
+ const dangerous = [];
405
+ const dangerousPatterns = [
406
+ { pattern: /child_process\.exec\s*\(/, name: 'child_process.exec' },
407
+ { pattern: /\.execSync\s*\(/, name: 'execSync' },
408
+ { pattern: /\$\(.*\)\.html\s*\(/, name: 'jQuery.html()' },
409
+ { pattern: /setTimeout\s*\(\s*["'`]/, name: 'setTimeout with string' },
410
+ { pattern: /setInterval\s*\(\s*["'`]/, name: 'setInterval with string' },
411
+ ];
412
+ for (const { pattern, name } of dangerousPatterns) {
413
+ if (pattern.test(code)) {
414
+ dangerous.push(name);
415
+ }
416
+ }
417
+ return dangerous;
418
+ }
419
+ calculateScore(checks) {
420
+ if (checks.length === 0)
421
+ return 100;
422
+ let score = 100;
423
+ const weights = { error: 25, warning: 10, info: 5 };
424
+ for (const check of checks) {
425
+ if (!check.passed) {
426
+ const weight = weights[check.severity || 'info'] || 5;
427
+ score -= weight;
428
+ }
429
+ }
430
+ return Math.max(0, score);
431
+ }
432
+ determineValidity(checks) {
433
+ if (this.options.strictMode) {
434
+ return checks.every(c => c.passed);
435
+ }
436
+ // In non-strict mode, only fail on errors
437
+ return !checks.some(c => !c.passed && c.severity === 'error');
438
+ }
439
+ }
440
+ // ============================================================================
441
+ // Factory Functions
442
+ // ============================================================================
443
+ /**
444
+ * Create a fix validator
445
+ */
446
+ export function createFixValidator(options) {
447
+ return new FixValidator(options);
448
+ }
449
+ /**
450
+ * Quick validate a fix
451
+ */
452
+ export async function quickValidate(fix, originalCode, fixedCode) {
453
+ const validator = createFixValidator({
454
+ syntaxValidation: true,
455
+ semanticValidation: false,
456
+ securityRescan: false,
457
+ regressionTesting: false,
458
+ });
459
+ const result = await validator.validate(fix, originalCode, fixedCode);
460
+ return result.valid;
461
+ }
462
+ //# sourceMappingURL=fix-validator.js.map