@agentic-qe/v3 3.0.0-alpha.3
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.
- package/README.md +429 -0
- package/dist/benchmarks/performance-benchmarks.d.ts +92 -0
- package/dist/benchmarks/performance-benchmarks.d.ts.map +1 -0
- package/dist/benchmarks/performance-benchmarks.js +477 -0
- package/dist/benchmarks/performance-benchmarks.js.map +1 -0
- package/dist/benchmarks/run-benchmarks.d.ts +12 -0
- package/dist/benchmarks/run-benchmarks.d.ts.map +1 -0
- package/dist/benchmarks/run-benchmarks.js +260 -0
- package/dist/benchmarks/run-benchmarks.js.map +1 -0
- package/dist/causal-discovery/causal-graph.d.ts +104 -0
- package/dist/causal-discovery/causal-graph.d.ts.map +1 -0
- package/dist/causal-discovery/causal-graph.js +384 -0
- package/dist/causal-discovery/causal-graph.js.map +1 -0
- package/dist/causal-discovery/discovery-engine.d.ts +120 -0
- package/dist/causal-discovery/discovery-engine.d.ts.map +1 -0
- package/dist/causal-discovery/discovery-engine.js +332 -0
- package/dist/causal-discovery/discovery-engine.js.map +1 -0
- package/dist/causal-discovery/index.d.ts +50 -0
- package/dist/causal-discovery/index.d.ts.map +1 -0
- package/dist/causal-discovery/index.js +69 -0
- package/dist/causal-discovery/index.js.map +1 -0
- package/dist/causal-discovery/types.d.ts +257 -0
- package/dist/causal-discovery/types.d.ts.map +1 -0
- package/dist/causal-discovery/types.js +72 -0
- package/dist/causal-discovery/types.js.map +1 -0
- package/dist/causal-discovery/weight-matrix.d.ts +130 -0
- package/dist/causal-discovery/weight-matrix.d.ts.map +1 -0
- package/dist/causal-discovery/weight-matrix.js +380 -0
- package/dist/causal-discovery/weight-matrix.js.map +1 -0
- package/dist/cli/commands/qe-tools.d.ts +27 -0
- package/dist/cli/commands/qe-tools.d.ts.map +1 -0
- package/dist/cli/commands/qe-tools.js +524 -0
- package/dist/cli/commands/qe-tools.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1725 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compatibility/agent-mapper.d.ts +45 -0
- package/dist/compatibility/agent-mapper.d.ts.map +1 -0
- package/dist/compatibility/agent-mapper.js +256 -0
- package/dist/compatibility/agent-mapper.js.map +1 -0
- package/dist/compatibility/cli-adapter.d.ts +53 -0
- package/dist/compatibility/cli-adapter.d.ts.map +1 -0
- package/dist/compatibility/cli-adapter.js +247 -0
- package/dist/compatibility/cli-adapter.js.map +1 -0
- package/dist/compatibility/config-migrator.d.ts +42 -0
- package/dist/compatibility/config-migrator.d.ts.map +1 -0
- package/dist/compatibility/config-migrator.js +280 -0
- package/dist/compatibility/config-migrator.js.map +1 -0
- package/dist/compatibility/index.d.ts +58 -0
- package/dist/compatibility/index.d.ts.map +1 -0
- package/dist/compatibility/index.js +90 -0
- package/dist/compatibility/index.js.map +1 -0
- package/dist/compatibility/mcp-adapter.d.ts +38 -0
- package/dist/compatibility/mcp-adapter.d.ts.map +1 -0
- package/dist/compatibility/mcp-adapter.js +202 -0
- package/dist/compatibility/mcp-adapter.js.map +1 -0
- package/dist/compatibility/types.d.ts +161 -0
- package/dist/compatibility/types.d.ts.map +1 -0
- package/dist/compatibility/types.js +5 -0
- package/dist/compatibility/types.js.map +1 -0
- package/dist/coordination/claims/claim-repository.d.ts +64 -0
- package/dist/coordination/claims/claim-repository.d.ts.map +1 -0
- package/dist/coordination/claims/claim-repository.js +524 -0
- package/dist/coordination/claims/claim-repository.js.map +1 -0
- package/dist/coordination/claims/claim-service.d.ts +45 -0
- package/dist/coordination/claims/claim-service.d.ts.map +1 -0
- package/dist/coordination/claims/claim-service.js +523 -0
- package/dist/coordination/claims/claim-service.js.map +1 -0
- package/dist/coordination/claims/handoff-manager.d.ts +95 -0
- package/dist/coordination/claims/handoff-manager.d.ts.map +1 -0
- package/dist/coordination/claims/handoff-manager.js +380 -0
- package/dist/coordination/claims/handoff-manager.js.map +1 -0
- package/dist/coordination/claims/index.d.ts +121 -0
- package/dist/coordination/claims/index.d.ts.map +1 -0
- package/dist/coordination/claims/index.js +129 -0
- package/dist/coordination/claims/index.js.map +1 -0
- package/dist/coordination/claims/interfaces.d.ts +471 -0
- package/dist/coordination/claims/interfaces.d.ts.map +1 -0
- package/dist/coordination/claims/interfaces.js +14 -0
- package/dist/coordination/claims/interfaces.js.map +1 -0
- package/dist/coordination/claims/work-stealing.d.ts +88 -0
- package/dist/coordination/claims/work-stealing.d.ts.map +1 -0
- package/dist/coordination/claims/work-stealing.js +335 -0
- package/dist/coordination/claims/work-stealing.js.map +1 -0
- package/dist/coordination/cross-domain-router.d.ts +104 -0
- package/dist/coordination/cross-domain-router.d.ts.map +1 -0
- package/dist/coordination/cross-domain-router.js +365 -0
- package/dist/coordination/cross-domain-router.js.map +1 -0
- package/dist/coordination/index.d.ts +14 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +29 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/interfaces.d.ts +482 -0
- package/dist/coordination/interfaces.d.ts.map +1 -0
- package/dist/coordination/interfaces.js +6 -0
- package/dist/coordination/interfaces.js.map +1 -0
- package/dist/coordination/protocol-executor.d.ts +119 -0
- package/dist/coordination/protocol-executor.d.ts.map +1 -0
- package/dist/coordination/protocol-executor.js +528 -0
- package/dist/coordination/protocol-executor.js.map +1 -0
- package/dist/coordination/protocols/code-intelligence-index.d.ts +204 -0
- package/dist/coordination/protocols/code-intelligence-index.d.ts.map +1 -0
- package/dist/coordination/protocols/code-intelligence-index.js +568 -0
- package/dist/coordination/protocols/code-intelligence-index.js.map +1 -0
- package/dist/coordination/protocols/defect-investigation.d.ts +202 -0
- package/dist/coordination/protocols/defect-investigation.d.ts.map +1 -0
- package/dist/coordination/protocols/defect-investigation.js +734 -0
- package/dist/coordination/protocols/defect-investigation.js.map +1 -0
- package/dist/coordination/protocols/index.d.ts +11 -0
- package/dist/coordination/protocols/index.d.ts.map +1 -0
- package/dist/coordination/protocols/index.js +11 -0
- package/dist/coordination/protocols/index.js.map +1 -0
- package/dist/coordination/protocols/learning-consolidation.d.ts +249 -0
- package/dist/coordination/protocols/learning-consolidation.d.ts.map +1 -0
- package/dist/coordination/protocols/learning-consolidation.js +811 -0
- package/dist/coordination/protocols/learning-consolidation.js.map +1 -0
- package/dist/coordination/protocols/morning-sync.d.ts +255 -0
- package/dist/coordination/protocols/morning-sync.d.ts.map +1 -0
- package/dist/coordination/protocols/morning-sync.js +730 -0
- package/dist/coordination/protocols/morning-sync.js.map +1 -0
- package/dist/coordination/protocols/quality-gate.d.ts +303 -0
- package/dist/coordination/protocols/quality-gate.d.ts.map +1 -0
- package/dist/coordination/protocols/quality-gate.js +924 -0
- package/dist/coordination/protocols/quality-gate.js.map +1 -0
- package/dist/coordination/protocols/security-audit.d.ts +263 -0
- package/dist/coordination/protocols/security-audit.d.ts.map +1 -0
- package/dist/coordination/protocols/security-audit.js +1159 -0
- package/dist/coordination/protocols/security-audit.js.map +1 -0
- package/dist/coordination/queen-coordinator.d.ts +214 -0
- package/dist/coordination/queen-coordinator.d.ts.map +1 -0
- package/dist/coordination/queen-coordinator.js +808 -0
- package/dist/coordination/queen-coordinator.js.map +1 -0
- package/dist/coordination/result-saver.d.ts +82 -0
- package/dist/coordination/result-saver.d.ts.map +1 -0
- package/dist/coordination/result-saver.js +536 -0
- package/dist/coordination/result-saver.js.map +1 -0
- package/dist/coordination/task-executor.d.ts +50 -0
- package/dist/coordination/task-executor.d.ts.map +1 -0
- package/dist/coordination/task-executor.js +965 -0
- package/dist/coordination/task-executor.js.map +1 -0
- package/dist/coordination/workflow-orchestrator.d.ts +362 -0
- package/dist/coordination/workflow-orchestrator.d.ts.map +1 -0
- package/dist/coordination/workflow-orchestrator.js +1298 -0
- package/dist/coordination/workflow-orchestrator.js.map +1 -0
- package/dist/domains/chaos-resilience/coordinator.d.ts +108 -0
- package/dist/domains/chaos-resilience/coordinator.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/coordinator.js +775 -0
- package/dist/domains/chaos-resilience/coordinator.js.map +1 -0
- package/dist/domains/chaos-resilience/index.d.ts +13 -0
- package/dist/domains/chaos-resilience/index.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/index.js +21 -0
- package/dist/domains/chaos-resilience/index.js.map +1 -0
- package/dist/domains/chaos-resilience/interfaces.d.ts +528 -0
- package/dist/domains/chaos-resilience/interfaces.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/interfaces.js +8 -0
- package/dist/domains/chaos-resilience/interfaces.js.map +1 -0
- package/dist/domains/chaos-resilience/plugin.d.ts +97 -0
- package/dist/domains/chaos-resilience/plugin.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/plugin.js +466 -0
- package/dist/domains/chaos-resilience/plugin.js.map +1 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.d.ts +97 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.js +875 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.js.map +1 -0
- package/dist/domains/chaos-resilience/services/index.d.ts +8 -0
- package/dist/domains/chaos-resilience/services/index.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/index.js +8 -0
- package/dist/domains/chaos-resilience/services/index.js.map +1 -0
- package/dist/domains/chaos-resilience/services/load-tester.d.ts +71 -0
- package/dist/domains/chaos-resilience/services/load-tester.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/load-tester.js +588 -0
- package/dist/domains/chaos-resilience/services/load-tester.js.map +1 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.d.ts +70 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.js +642 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.js.map +1 -0
- package/dist/domains/code-intelligence/coordinator.d.ts +104 -0
- package/dist/domains/code-intelligence/coordinator.d.ts.map +1 -0
- package/dist/domains/code-intelligence/coordinator.js +436 -0
- package/dist/domains/code-intelligence/coordinator.js.map +1 -0
- package/dist/domains/code-intelligence/index.d.ts +13 -0
- package/dist/domains/code-intelligence/index.d.ts.map +1 -0
- package/dist/domains/code-intelligence/index.js +21 -0
- package/dist/domains/code-intelligence/index.js.map +1 -0
- package/dist/domains/code-intelligence/interfaces.d.ts +130 -0
- package/dist/domains/code-intelligence/interfaces.d.ts.map +1 -0
- package/dist/domains/code-intelligence/interfaces.js +6 -0
- package/dist/domains/code-intelligence/interfaces.js.map +1 -0
- package/dist/domains/code-intelligence/plugin.d.ts +75 -0
- package/dist/domains/code-intelligence/plugin.d.ts.map +1 -0
- package/dist/domains/code-intelligence/plugin.js +279 -0
- package/dist/domains/code-intelligence/plugin.js.map +1 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.d.ts +80 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.js +391 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.js.map +1 -0
- package/dist/domains/code-intelligence/services/index.d.ts +8 -0
- package/dist/domains/code-intelligence/services/index.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/index.js +8 -0
- package/dist/domains/code-intelligence/services/index.js.map +1 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.d.ts +101 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.js +822 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.js.map +1 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +141 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.js +661 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.js.map +1 -0
- package/dist/domains/contract-testing/coordinator.d.ts +114 -0
- package/dist/domains/contract-testing/coordinator.d.ts.map +1 -0
- package/dist/domains/contract-testing/coordinator.js +805 -0
- package/dist/domains/contract-testing/coordinator.js.map +1 -0
- package/dist/domains/contract-testing/index.d.ts +13 -0
- package/dist/domains/contract-testing/index.d.ts.map +1 -0
- package/dist/domains/contract-testing/index.js +21 -0
- package/dist/domains/contract-testing/index.js.map +1 -0
- package/dist/domains/contract-testing/interfaces.d.ts +344 -0
- package/dist/domains/contract-testing/interfaces.d.ts.map +1 -0
- package/dist/domains/contract-testing/interfaces.js +8 -0
- package/dist/domains/contract-testing/interfaces.js.map +1 -0
- package/dist/domains/contract-testing/plugin.d.ts +112 -0
- package/dist/domains/contract-testing/plugin.d.ts.map +1 -0
- package/dist/domains/contract-testing/plugin.js +491 -0
- package/dist/domains/contract-testing/plugin.js.map +1 -0
- package/dist/domains/contract-testing/services/api-compatibility.d.ts +53 -0
- package/dist/domains/contract-testing/services/api-compatibility.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/api-compatibility.js +535 -0
- package/dist/domains/contract-testing/services/api-compatibility.js.map +1 -0
- package/dist/domains/contract-testing/services/contract-validator.d.ts +100 -0
- package/dist/domains/contract-testing/services/contract-validator.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/contract-validator.js +1398 -0
- package/dist/domains/contract-testing/services/contract-validator.js.map +1 -0
- package/dist/domains/contract-testing/services/index.d.ts +8 -0
- package/dist/domains/contract-testing/services/index.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/index.js +8 -0
- package/dist/domains/contract-testing/services/index.js.map +1 -0
- package/dist/domains/contract-testing/services/schema-validator.d.ts +65 -0
- package/dist/domains/contract-testing/services/schema-validator.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/schema-validator.js +860 -0
- package/dist/domains/contract-testing/services/schema-validator.js.map +1 -0
- package/dist/domains/coverage-analysis/coordinator.d.ts +66 -0
- package/dist/domains/coverage-analysis/coordinator.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/coordinator.js +353 -0
- package/dist/domains/coverage-analysis/coordinator.js.map +1 -0
- package/dist/domains/coverage-analysis/index.d.ts +33 -0
- package/dist/domains/coverage-analysis/index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/index.js +39 -0
- package/dist/domains/coverage-analysis/index.js.map +1 -0
- package/dist/domains/coverage-analysis/interfaces.d.ts +134 -0
- package/dist/domains/coverage-analysis/interfaces.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/interfaces.js +6 -0
- package/dist/domains/coverage-analysis/interfaces.js.map +1 -0
- package/dist/domains/coverage-analysis/plugin.d.ts +37 -0
- package/dist/domains/coverage-analysis/plugin.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/plugin.js +133 -0
- package/dist/domains/coverage-analysis/plugin.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +49 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +342 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.d.ts +165 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.js +550 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.d.ts +203 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.js +506 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.js.map +1 -0
- package/dist/domains/coverage-analysis/services/gap-detector.d.ts +61 -0
- package/dist/domains/coverage-analysis/services/gap-detector.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/gap-detector.js +474 -0
- package/dist/domains/coverage-analysis/services/gap-detector.js.map +1 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts +260 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.js +482 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -0
- package/dist/domains/coverage-analysis/services/index.d.ts +13 -0
- package/dist/domains/coverage-analysis/services/index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/index.js +16 -0
- package/dist/domains/coverage-analysis/services/index.js.map +1 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.d.ts +62 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.js +412 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.js.map +1 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts +237 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js +499 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js.map +1 -0
- package/dist/domains/defect-intelligence/coordinator.d.ts +104 -0
- package/dist/domains/defect-intelligence/coordinator.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/coordinator.js +423 -0
- package/dist/domains/defect-intelligence/coordinator.js.map +1 -0
- package/dist/domains/defect-intelligence/index.d.ts +13 -0
- package/dist/domains/defect-intelligence/index.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/index.js +21 -0
- package/dist/domains/defect-intelligence/index.js.map +1 -0
- package/dist/domains/defect-intelligence/interfaces.d.ts +127 -0
- package/dist/domains/defect-intelligence/interfaces.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/interfaces.js +6 -0
- package/dist/domains/defect-intelligence/interfaces.js.map +1 -0
- package/dist/domains/defect-intelligence/plugin.d.ts +76 -0
- package/dist/domains/defect-intelligence/plugin.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/plugin.js +287 -0
- package/dist/domains/defect-intelligence/plugin.js.map +1 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.d.ts +188 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.js +298 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.js.map +1 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.d.ts +129 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js +674 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js.map +1 -0
- package/dist/domains/defect-intelligence/services/index.d.ts +9 -0
- package/dist/domains/defect-intelligence/services/index.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/index.js +10 -0
- package/dist/domains/defect-intelligence/services/index.js.map +1 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.d.ts +96 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.js +548 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.js.map +1 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts +60 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +465 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js.map +1 -0
- package/dist/domains/domain-interface.d.ts +32 -0
- package/dist/domains/domain-interface.d.ts.map +1 -0
- package/dist/domains/domain-interface.js +61 -0
- package/dist/domains/domain-interface.js.map +1 -0
- package/dist/domains/index.d.ts +20 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +22 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/learning-optimization/coordinator.d.ts +107 -0
- package/dist/domains/learning-optimization/coordinator.d.ts.map +1 -0
- package/dist/domains/learning-optimization/coordinator.js +849 -0
- package/dist/domains/learning-optimization/coordinator.js.map +1 -0
- package/dist/domains/learning-optimization/index.d.ts +14 -0
- package/dist/domains/learning-optimization/index.d.ts.map +1 -0
- package/dist/domains/learning-optimization/index.js +22 -0
- package/dist/domains/learning-optimization/index.js.map +1 -0
- package/dist/domains/learning-optimization/interfaces.d.ts +453 -0
- package/dist/domains/learning-optimization/interfaces.d.ts.map +1 -0
- package/dist/domains/learning-optimization/interfaces.js +8 -0
- package/dist/domains/learning-optimization/interfaces.js.map +1 -0
- package/dist/domains/learning-optimization/plugin.d.ts +116 -0
- package/dist/domains/learning-optimization/plugin.d.ts.map +1 -0
- package/dist/domains/learning-optimization/plugin.js +523 -0
- package/dist/domains/learning-optimization/plugin.js.map +1 -0
- package/dist/domains/learning-optimization/services/index.d.ts +9 -0
- package/dist/domains/learning-optimization/services/index.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/index.js +9 -0
- package/dist/domains/learning-optimization/services/index.js.map +1 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.d.ts +98 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.js +730 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.js.map +1 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.d.ts +89 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.js +598 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.js.map +1 -0
- package/dist/domains/learning-optimization/services/production-intel.d.ts +137 -0
- package/dist/domains/learning-optimization/services/production-intel.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/production-intel.js +649 -0
- package/dist/domains/learning-optimization/services/production-intel.js.map +1 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.d.ts +86 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.js +495 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.d.ts +117 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.js +414 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/index.d.ts +102 -0
- package/dist/domains/quality-assessment/coherence/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/index.js +122 -0
- package/dist/domains/quality-assessment/coherence/index.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.d.ts +93 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.js +293 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.d.ts +109 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.js +338 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/types.d.ts +239 -0
- package/dist/domains/quality-assessment/coherence/types.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/types.js +62 -0
- package/dist/domains/quality-assessment/coherence/types.js.map +1 -0
- package/dist/domains/quality-assessment/coordinator.d.ts +98 -0
- package/dist/domains/quality-assessment/coordinator.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coordinator.js +391 -0
- package/dist/domains/quality-assessment/coordinator.js.map +1 -0
- package/dist/domains/quality-assessment/index.d.ts +15 -0
- package/dist/domains/quality-assessment/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/index.js +27 -0
- package/dist/domains/quality-assessment/index.js.map +1 -0
- package/dist/domains/quality-assessment/interfaces.d.ts +140 -0
- package/dist/domains/quality-assessment/interfaces.d.ts.map +1 -0
- package/dist/domains/quality-assessment/interfaces.js +6 -0
- package/dist/domains/quality-assessment/interfaces.js.map +1 -0
- package/dist/domains/quality-assessment/plugin.d.ts +75 -0
- package/dist/domains/quality-assessment/plugin.d.ts.map +1 -0
- package/dist/domains/quality-assessment/plugin.js +294 -0
- package/dist/domains/quality-assessment/plugin.js.map +1 -0
- package/dist/domains/quality-assessment/services/coherence-gate.d.ts +109 -0
- package/dist/domains/quality-assessment/services/coherence-gate.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/coherence-gate.js +234 -0
- package/dist/domains/quality-assessment/services/coherence-gate.js.map +1 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.d.ts +83 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.js +384 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.js.map +1 -0
- package/dist/domains/quality-assessment/services/index.d.ts +9 -0
- package/dist/domains/quality-assessment/services/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/index.js +12 -0
- package/dist/domains/quality-assessment/services/index.js.map +1 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.d.ts +74 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.js +518 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.js.map +1 -0
- package/dist/domains/quality-assessment/services/quality-gate.d.ts +57 -0
- package/dist/domains/quality-assessment/services/quality-gate.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/quality-gate.js +244 -0
- package/dist/domains/quality-assessment/services/quality-gate.js.map +1 -0
- package/dist/domains/requirements-validation/coordinator.d.ts +89 -0
- package/dist/domains/requirements-validation/coordinator.d.ts.map +1 -0
- package/dist/domains/requirements-validation/coordinator.js +574 -0
- package/dist/domains/requirements-validation/coordinator.js.map +1 -0
- package/dist/domains/requirements-validation/index.d.ts +13 -0
- package/dist/domains/requirements-validation/index.d.ts.map +1 -0
- package/dist/domains/requirements-validation/index.js +21 -0
- package/dist/domains/requirements-validation/index.js.map +1 -0
- package/dist/domains/requirements-validation/interfaces.d.ts +236 -0
- package/dist/domains/requirements-validation/interfaces.d.ts.map +1 -0
- package/dist/domains/requirements-validation/interfaces.js +8 -0
- package/dist/domains/requirements-validation/interfaces.js.map +1 -0
- package/dist/domains/requirements-validation/plugin.d.ts +103 -0
- package/dist/domains/requirements-validation/plugin.d.ts.map +1 -0
- package/dist/domains/requirements-validation/plugin.js +351 -0
- package/dist/domains/requirements-validation/plugin.js.map +1 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.d.ts +58 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.js +521 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.js.map +1 -0
- package/dist/domains/requirements-validation/services/index.d.ts +8 -0
- package/dist/domains/requirements-validation/services/index.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/index.js +8 -0
- package/dist/domains/requirements-validation/services/index.js.map +1 -0
- package/dist/domains/requirements-validation/services/requirements-validator.d.ts +51 -0
- package/dist/domains/requirements-validation/services/requirements-validator.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/requirements-validator.js +423 -0
- package/dist/domains/requirements-validation/services/requirements-validator.js.map +1 -0
- package/dist/domains/requirements-validation/services/testability-scorer.d.ts +79 -0
- package/dist/domains/requirements-validation/services/testability-scorer.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/testability-scorer.js +502 -0
- package/dist/domains/requirements-validation/services/testability-scorer.js.map +1 -0
- package/dist/domains/security-compliance/coordinator.d.ts +91 -0
- package/dist/domains/security-compliance/coordinator.d.ts.map +1 -0
- package/dist/domains/security-compliance/coordinator.js +497 -0
- package/dist/domains/security-compliance/coordinator.js.map +1 -0
- package/dist/domains/security-compliance/index.d.ts +13 -0
- package/dist/domains/security-compliance/index.d.ts.map +1 -0
- package/dist/domains/security-compliance/index.js +21 -0
- package/dist/domains/security-compliance/index.js.map +1 -0
- package/dist/domains/security-compliance/interfaces.d.ts +342 -0
- package/dist/domains/security-compliance/interfaces.d.ts.map +1 -0
- package/dist/domains/security-compliance/interfaces.js +8 -0
- package/dist/domains/security-compliance/interfaces.js.map +1 -0
- package/dist/domains/security-compliance/plugin.d.ts +81 -0
- package/dist/domains/security-compliance/plugin.d.ts.map +1 -0
- package/dist/domains/security-compliance/plugin.js +302 -0
- package/dist/domains/security-compliance/plugin.js.map +1 -0
- package/dist/domains/security-compliance/services/compliance-validator.d.ts +102 -0
- package/dist/domains/security-compliance/services/compliance-validator.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/compliance-validator.js +925 -0
- package/dist/domains/security-compliance/services/compliance-validator.js.map +1 -0
- package/dist/domains/security-compliance/services/index.d.ts +8 -0
- package/dist/domains/security-compliance/services/index.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/index.js +8 -0
- package/dist/domains/security-compliance/services/index.js.map +1 -0
- package/dist/domains/security-compliance/services/security-auditor.d.ts +174 -0
- package/dist/domains/security-compliance/services/security-auditor.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/security-auditor.js +1763 -0
- package/dist/domains/security-compliance/services/security-auditor.js.map +1 -0
- package/dist/domains/security-compliance/services/security-scanner.d.ts +185 -0
- package/dist/domains/security-compliance/services/security-scanner.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/security-scanner.js +1911 -0
- package/dist/domains/security-compliance/services/security-scanner.js.map +1 -0
- package/dist/domains/security-compliance/services/semgrep-integration.d.ts +95 -0
- package/dist/domains/security-compliance/services/semgrep-integration.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/semgrep-integration.js +209 -0
- package/dist/domains/security-compliance/services/semgrep-integration.js.map +1 -0
- package/dist/domains/test-execution/coordinator.d.ts +91 -0
- package/dist/domains/test-execution/coordinator.d.ts.map +1 -0
- package/dist/domains/test-execution/coordinator.js +280 -0
- package/dist/domains/test-execution/coordinator.js.map +1 -0
- package/dist/domains/test-execution/index.d.ts +11 -0
- package/dist/domains/test-execution/index.d.ts.map +1 -0
- package/dist/domains/test-execution/index.js +19 -0
- package/dist/domains/test-execution/index.js.map +1 -0
- package/dist/domains/test-execution/interfaces.d.ts +95 -0
- package/dist/domains/test-execution/interfaces.d.ts.map +1 -0
- package/dist/domains/test-execution/interfaces.js +6 -0
- package/dist/domains/test-execution/interfaces.js.map +1 -0
- package/dist/domains/test-execution/plugin.d.ts +27 -0
- package/dist/domains/test-execution/plugin.d.ts.map +1 -0
- package/dist/domains/test-execution/plugin.js +137 -0
- package/dist/domains/test-execution/plugin.js.map +1 -0
- package/dist/domains/test-execution/services/flaky-detector.d.ts +189 -0
- package/dist/domains/test-execution/services/flaky-detector.d.ts.map +1 -0
- package/dist/domains/test-execution/services/flaky-detector.js +834 -0
- package/dist/domains/test-execution/services/flaky-detector.js.map +1 -0
- package/dist/domains/test-execution/services/index.d.ts +8 -0
- package/dist/domains/test-execution/services/index.d.ts.map +1 -0
- package/dist/domains/test-execution/services/index.js +8 -0
- package/dist/domains/test-execution/services/index.js.map +1 -0
- package/dist/domains/test-execution/services/retry-handler.d.ts +169 -0
- package/dist/domains/test-execution/services/retry-handler.d.ts.map +1 -0
- package/dist/domains/test-execution/services/retry-handler.js +536 -0
- package/dist/domains/test-execution/services/retry-handler.js.map +1 -0
- package/dist/domains/test-execution/services/test-executor.d.ts +112 -0
- package/dist/domains/test-execution/services/test-executor.d.ts.map +1 -0
- package/dist/domains/test-execution/services/test-executor.js +657 -0
- package/dist/domains/test-execution/services/test-executor.js.map +1 -0
- package/dist/domains/test-generation/coordinator.d.ts +104 -0
- package/dist/domains/test-generation/coordinator.d.ts.map +1 -0
- package/dist/domains/test-generation/coordinator.js +446 -0
- package/dist/domains/test-generation/coordinator.js.map +1 -0
- package/dist/domains/test-generation/index.d.ts +12 -0
- package/dist/domains/test-generation/index.d.ts.map +1 -0
- package/dist/domains/test-generation/index.js +20 -0
- package/dist/domains/test-generation/index.js.map +1 -0
- package/dist/domains/test-generation/interfaces.d.ts +92 -0
- package/dist/domains/test-generation/interfaces.d.ts.map +1 -0
- package/dist/domains/test-generation/interfaces.js +6 -0
- package/dist/domains/test-generation/interfaces.js.map +1 -0
- package/dist/domains/test-generation/plugin.d.ts +70 -0
- package/dist/domains/test-generation/plugin.d.ts.map +1 -0
- package/dist/domains/test-generation/plugin.js +240 -0
- package/dist/domains/test-generation/plugin.js.map +1 -0
- package/dist/domains/test-generation/services/index.d.ts +7 -0
- package/dist/domains/test-generation/services/index.d.ts.map +1 -0
- package/dist/domains/test-generation/services/index.js +7 -0
- package/dist/domains/test-generation/services/index.js.map +1 -0
- package/dist/domains/test-generation/services/pattern-matcher.d.ts +276 -0
- package/dist/domains/test-generation/services/pattern-matcher.d.ts.map +1 -0
- package/dist/domains/test-generation/services/pattern-matcher.js +1271 -0
- package/dist/domains/test-generation/services/pattern-matcher.js.map +1 -0
- package/dist/domains/test-generation/services/test-generator.d.ts +226 -0
- package/dist/domains/test-generation/services/test-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/services/test-generator.js +2230 -0
- package/dist/domains/test-generation/services/test-generator.js.map +1 -0
- package/dist/domains/visual-accessibility/coordinator.d.ts +118 -0
- package/dist/domains/visual-accessibility/coordinator.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/coordinator.js +623 -0
- package/dist/domains/visual-accessibility/coordinator.js.map +1 -0
- package/dist/domains/visual-accessibility/index.d.ts +13 -0
- package/dist/domains/visual-accessibility/index.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/index.js +21 -0
- package/dist/domains/visual-accessibility/index.js.map +1 -0
- package/dist/domains/visual-accessibility/interfaces.d.ts +360 -0
- package/dist/domains/visual-accessibility/interfaces.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/interfaces.js +8 -0
- package/dist/domains/visual-accessibility/interfaces.js.map +1 -0
- package/dist/domains/visual-accessibility/plugin.d.ts +92 -0
- package/dist/domains/visual-accessibility/plugin.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/plugin.js +343 -0
- package/dist/domains/visual-accessibility/plugin.js.map +1 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +115 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.js +794 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.d.ts +219 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.js +427 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.js.map +1 -0
- package/dist/domains/visual-accessibility/services/index.d.ts +8 -0
- package/dist/domains/visual-accessibility/services/index.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/index.js +8 -0
- package/dist/domains/visual-accessibility/services/index.js.map +1 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.d.ts +149 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.js +667 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.js.map +1 -0
- package/dist/domains/visual-accessibility/services/visual-tester.d.ts +78 -0
- package/dist/domains/visual-accessibility/services/visual-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/visual-tester.js +335 -0
- package/dist/domains/visual-accessibility/services/visual-tester.js.map +1 -0
- package/dist/early-exit/early-exit-controller.d.ts +158 -0
- package/dist/early-exit/early-exit-controller.d.ts.map +1 -0
- package/dist/early-exit/early-exit-controller.js +354 -0
- package/dist/early-exit/early-exit-controller.js.map +1 -0
- package/dist/early-exit/early-exit-decision.d.ts +110 -0
- package/dist/early-exit/early-exit-decision.d.ts.map +1 -0
- package/dist/early-exit/early-exit-decision.js +241 -0
- package/dist/early-exit/early-exit-decision.js.map +1 -0
- package/dist/early-exit/index.d.ts +38 -0
- package/dist/early-exit/index.d.ts.map +1 -0
- package/dist/early-exit/index.js +53 -0
- package/dist/early-exit/index.js.map +1 -0
- package/dist/early-exit/quality-signal.d.ts +61 -0
- package/dist/early-exit/quality-signal.d.ts.map +1 -0
- package/dist/early-exit/quality-signal.js +306 -0
- package/dist/early-exit/quality-signal.js.map +1 -0
- package/dist/early-exit/speculative-executor.d.ts +131 -0
- package/dist/early-exit/speculative-executor.d.ts.map +1 -0
- package/dist/early-exit/speculative-executor.js +385 -0
- package/dist/early-exit/speculative-executor.js.map +1 -0
- package/dist/early-exit/types.d.ts +271 -0
- package/dist/early-exit/types.d.ts.map +1 -0
- package/dist/early-exit/types.js +69 -0
- package/dist/early-exit/types.js.map +1 -0
- package/dist/feedback/coverage-learner.d.ts +117 -0
- package/dist/feedback/coverage-learner.d.ts.map +1 -0
- package/dist/feedback/coverage-learner.js +367 -0
- package/dist/feedback/coverage-learner.js.map +1 -0
- package/dist/feedback/feedback-loop.d.ts +170 -0
- package/dist/feedback/feedback-loop.d.ts.map +1 -0
- package/dist/feedback/feedback-loop.js +281 -0
- package/dist/feedback/feedback-loop.js.map +1 -0
- package/dist/feedback/index.d.ts +17 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +20 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/feedback/pattern-promotion.d.ts +126 -0
- package/dist/feedback/pattern-promotion.d.ts.map +1 -0
- package/dist/feedback/pattern-promotion.js +282 -0
- package/dist/feedback/pattern-promotion.js.map +1 -0
- package/dist/feedback/quality-score-calculator.d.ts +93 -0
- package/dist/feedback/quality-score-calculator.d.ts.map +1 -0
- package/dist/feedback/quality-score-calculator.js +285 -0
- package/dist/feedback/quality-score-calculator.js.map +1 -0
- package/dist/feedback/test-outcome-tracker.d.ts +103 -0
- package/dist/feedback/test-outcome-tracker.d.ts.map +1 -0
- package/dist/feedback/test-outcome-tracker.js +347 -0
- package/dist/feedback/test-outcome-tracker.js.map +1 -0
- package/dist/feedback/types.d.ts +322 -0
- package/dist/feedback/types.d.ts.map +1 -0
- package/dist/feedback/types.js +60 -0
- package/dist/feedback/types.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/init/agents-installer.d.ts +88 -0
- package/dist/init/agents-installer.d.ts.map +1 -0
- package/dist/init/agents-installer.js +441 -0
- package/dist/init/agents-installer.js.map +1 -0
- package/dist/init/index.d.ts +18 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +14 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/init-wizard.d.ts +107 -0
- package/dist/init/init-wizard.d.ts.map +1 -0
- package/dist/init/init-wizard.js +906 -0
- package/dist/init/init-wizard.js.map +1 -0
- package/dist/init/project-analyzer.d.ts +95 -0
- package/dist/init/project-analyzer.d.ts.map +1 -0
- package/dist/init/project-analyzer.js +608 -0
- package/dist/init/project-analyzer.js.map +1 -0
- package/dist/init/self-configurator.d.ts +74 -0
- package/dist/init/self-configurator.d.ts.map +1 -0
- package/dist/init/self-configurator.js +384 -0
- package/dist/init/self-configurator.js.map +1 -0
- package/dist/init/skills-installer.d.ts +88 -0
- package/dist/init/skills-installer.d.ts.map +1 -0
- package/dist/init/skills-installer.js +386 -0
- package/dist/init/skills-installer.js.map +1 -0
- package/dist/init/types.d.ts +280 -0
- package/dist/init/types.d.ts.map +1 -0
- package/dist/init/types.js +110 -0
- package/dist/init/types.js.map +1 -0
- package/dist/integrations/ruvector/ast-complexity.d.ts +134 -0
- package/dist/integrations/ruvector/ast-complexity.d.ts.map +1 -0
- package/dist/integrations/ruvector/ast-complexity.js +383 -0
- package/dist/integrations/ruvector/ast-complexity.js.map +1 -0
- package/dist/integrations/ruvector/coverage-router.d.ts +128 -0
- package/dist/integrations/ruvector/coverage-router.d.ts.map +1 -0
- package/dist/integrations/ruvector/coverage-router.js +463 -0
- package/dist/integrations/ruvector/coverage-router.js.map +1 -0
- package/dist/integrations/ruvector/diff-risk-classifier.d.ts +129 -0
- package/dist/integrations/ruvector/diff-risk-classifier.d.ts.map +1 -0
- package/dist/integrations/ruvector/diff-risk-classifier.js +569 -0
- package/dist/integrations/ruvector/diff-risk-classifier.js.map +1 -0
- package/dist/integrations/ruvector/fallback.d.ts +138 -0
- package/dist/integrations/ruvector/fallback.d.ts.map +1 -0
- package/dist/integrations/ruvector/fallback.js +737 -0
- package/dist/integrations/ruvector/fallback.js.map +1 -0
- package/dist/integrations/ruvector/graph-boundaries.d.ts +151 -0
- package/dist/integrations/ruvector/graph-boundaries.d.ts.map +1 -0
- package/dist/integrations/ruvector/graph-boundaries.js +627 -0
- package/dist/integrations/ruvector/graph-boundaries.js.map +1 -0
- package/dist/integrations/ruvector/index.d.ts +82 -0
- package/dist/integrations/ruvector/index.d.ts.map +1 -0
- package/dist/integrations/ruvector/index.js +254 -0
- package/dist/integrations/ruvector/index.js.map +1 -0
- package/dist/integrations/ruvector/interfaces.d.ts +488 -0
- package/dist/integrations/ruvector/interfaces.d.ts.map +1 -0
- package/dist/integrations/ruvector/interfaces.js +64 -0
- package/dist/integrations/ruvector/interfaces.js.map +1 -0
- package/dist/integrations/ruvector/q-learning-router.d.ts +128 -0
- package/dist/integrations/ruvector/q-learning-router.d.ts.map +1 -0
- package/dist/integrations/ruvector/q-learning-router.js +427 -0
- package/dist/integrations/ruvector/q-learning-router.js.map +1 -0
- package/dist/kernel/agent-coordinator.d.ts +22 -0
- package/dist/kernel/agent-coordinator.d.ts.map +1 -0
- package/dist/kernel/agent-coordinator.js +113 -0
- package/dist/kernel/agent-coordinator.js.map +1 -0
- package/dist/kernel/agentdb-backend.d.ts +131 -0
- package/dist/kernel/agentdb-backend.d.ts.map +1 -0
- package/dist/kernel/agentdb-backend.js +359 -0
- package/dist/kernel/agentdb-backend.js.map +1 -0
- package/dist/kernel/event-bus.d.ts +18 -0
- package/dist/kernel/event-bus.d.ts.map +1 -0
- package/dist/kernel/event-bus.js +99 -0
- package/dist/kernel/event-bus.js.map +1 -0
- package/dist/kernel/hybrid-backend.d.ts +124 -0
- package/dist/kernel/hybrid-backend.d.ts.map +1 -0
- package/dist/kernel/hybrid-backend.js +395 -0
- package/dist/kernel/hybrid-backend.js.map +1 -0
- package/dist/kernel/index.d.ts +16 -0
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +17 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/kernel/interfaces.d.ts +174 -0
- package/dist/kernel/interfaces.d.ts.map +1 -0
- package/dist/kernel/interfaces.js +6 -0
- package/dist/kernel/interfaces.js.map +1 -0
- package/dist/kernel/kernel.d.ts +50 -0
- package/dist/kernel/kernel.d.ts.map +1 -0
- package/dist/kernel/kernel.js +228 -0
- package/dist/kernel/kernel.js.map +1 -0
- package/dist/kernel/memory-backend.d.ts +28 -0
- package/dist/kernel/memory-backend.d.ts.map +1 -0
- package/dist/kernel/memory-backend.js +126 -0
- package/dist/kernel/memory-backend.js.map +1 -0
- package/dist/kernel/memory-factory.d.ts +100 -0
- package/dist/kernel/memory-factory.d.ts.map +1 -0
- package/dist/kernel/memory-factory.js +209 -0
- package/dist/kernel/memory-factory.js.map +1 -0
- package/dist/kernel/plugin-loader.d.ts +36 -0
- package/dist/kernel/plugin-loader.d.ts.map +1 -0
- package/dist/kernel/plugin-loader.js +145 -0
- package/dist/kernel/plugin-loader.js.map +1 -0
- package/dist/learning/index.d.ts +58 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +90 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/pattern-store.d.ts +242 -0
- package/dist/learning/pattern-store.d.ts.map +1 -0
- package/dist/learning/pattern-store.js +657 -0
- package/dist/learning/pattern-store.js.map +1 -0
- package/dist/learning/qe-guidance.d.ts +125 -0
- package/dist/learning/qe-guidance.d.ts.map +1 -0
- package/dist/learning/qe-guidance.js +712 -0
- package/dist/learning/qe-guidance.js.map +1 -0
- package/dist/learning/qe-hooks.d.ts +111 -0
- package/dist/learning/qe-hooks.d.ts.map +1 -0
- package/dist/learning/qe-hooks.js +475 -0
- package/dist/learning/qe-hooks.js.map +1 -0
- package/dist/learning/qe-patterns.d.ts +203 -0
- package/dist/learning/qe-patterns.d.ts.map +1 -0
- package/dist/learning/qe-patterns.js +181 -0
- package/dist/learning/qe-patterns.js.map +1 -0
- package/dist/learning/qe-reasoning-bank.d.ts +263 -0
- package/dist/learning/qe-reasoning-bank.d.ts.map +1 -0
- package/dist/learning/qe-reasoning-bank.js +617 -0
- package/dist/learning/qe-reasoning-bank.js.map +1 -0
- package/dist/learning/real-embeddings.d.ts +61 -0
- package/dist/learning/real-embeddings.d.ts.map +1 -0
- package/dist/learning/real-embeddings.js +219 -0
- package/dist/learning/real-embeddings.js.map +1 -0
- package/dist/learning/real-qe-reasoning-bank.d.ts +182 -0
- package/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -0
- package/dist/learning/real-qe-reasoning-bank.js +597 -0
- package/dist/learning/real-qe-reasoning-bank.js.map +1 -0
- package/dist/learning/sqlite-persistence.d.ts +121 -0
- package/dist/learning/sqlite-persistence.d.ts.map +1 -0
- package/dist/learning/sqlite-persistence.js +438 -0
- package/dist/learning/sqlite-persistence.js.map +1 -0
- package/dist/mcp/entry.d.ts +13 -0
- package/dist/mcp/entry.d.ts.map +1 -0
- package/dist/mcp/entry.js +53 -0
- package/dist/mcp/entry.js.map +1 -0
- package/dist/mcp/handlers/agent-handlers.d.ts +62 -0
- package/dist/mcp/handlers/agent-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/agent-handlers.js +173 -0
- package/dist/mcp/handlers/agent-handlers.js.map +1 -0
- package/dist/mcp/handlers/core-handlers.d.ts +30 -0
- package/dist/mcp/handlers/core-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/core-handlers.js +250 -0
- package/dist/mcp/handlers/core-handlers.js.map +1 -0
- package/dist/mcp/handlers/domain-handlers.d.ts +135 -0
- package/dist/mcp/handlers/domain-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/domain-handlers.js +990 -0
- package/dist/mcp/handlers/domain-handlers.js.map +1 -0
- package/dist/mcp/handlers/index.d.ts +10 -0
- package/dist/mcp/handlers/index.d.ts.map +1 -0
- package/dist/mcp/handlers/index.js +15 -0
- package/dist/mcp/handlers/index.js.map +1 -0
- package/dist/mcp/handlers/memory-handlers.d.ts +53 -0
- package/dist/mcp/handlers/memory-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/memory-handlers.js +228 -0
- package/dist/mcp/handlers/memory-handlers.js.map +1 -0
- package/dist/mcp/handlers/task-handlers.d.ts +26 -0
- package/dist/mcp/handlers/task-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/task-handlers.js +293 -0
- package/dist/mcp/handlers/task-handlers.js.map +1 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +18 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/metrics/index.d.ts +6 -0
- package/dist/mcp/metrics/index.d.ts.map +1 -0
- package/dist/mcp/metrics/index.js +6 -0
- package/dist/mcp/metrics/index.js.map +1 -0
- package/dist/mcp/metrics/metrics-collector.d.ts +154 -0
- package/dist/mcp/metrics/metrics-collector.d.ts.map +1 -0
- package/dist/mcp/metrics/metrics-collector.js +377 -0
- package/dist/mcp/metrics/metrics-collector.js.map +1 -0
- package/dist/mcp/protocol-server.d.ts +66 -0
- package/dist/mcp/protocol-server.d.ts.map +1 -0
- package/dist/mcp/protocol-server.js +600 -0
- package/dist/mcp/protocol-server.js.map +1 -0
- package/dist/mcp/security/cve-prevention.d.ts +150 -0
- package/dist/mcp/security/cve-prevention.d.ts.map +1 -0
- package/dist/mcp/security/cve-prevention.js +570 -0
- package/dist/mcp/security/cve-prevention.js.map +1 -0
- package/dist/mcp/security/index.d.ts +116 -0
- package/dist/mcp/security/index.d.ts.map +1 -0
- package/dist/mcp/security/index.js +184 -0
- package/dist/mcp/security/index.js.map +1 -0
- package/dist/mcp/security/oauth21-provider.d.ts +229 -0
- package/dist/mcp/security/oauth21-provider.d.ts.map +1 -0
- package/dist/mcp/security/oauth21-provider.js +558 -0
- package/dist/mcp/security/oauth21-provider.js.map +1 -0
- package/dist/mcp/security/rate-limiter.d.ts +191 -0
- package/dist/mcp/security/rate-limiter.d.ts.map +1 -0
- package/dist/mcp/security/rate-limiter.js +437 -0
- package/dist/mcp/security/rate-limiter.js.map +1 -0
- package/dist/mcp/security/sampling-server.d.ts +289 -0
- package/dist/mcp/security/sampling-server.d.ts.map +1 -0
- package/dist/mcp/security/sampling-server.js +450 -0
- package/dist/mcp/security/sampling-server.js.map +1 -0
- package/dist/mcp/security/schema-validator.d.ts +197 -0
- package/dist/mcp/security/schema-validator.d.ts.map +1 -0
- package/dist/mcp/security/schema-validator.js +633 -0
- package/dist/mcp/security/schema-validator.js.map +1 -0
- package/dist/mcp/server.d.ts +46 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +576 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +98 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +321 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tools/base.d.ts +186 -0
- package/dist/mcp/tools/base.d.ts.map +1 -0
- package/dist/mcp/tools/base.js +249 -0
- package/dist/mcp/tools/base.js.map +1 -0
- package/dist/mcp/tools/chaos-resilience/inject.d.ts +61 -0
- package/dist/mcp/tools/chaos-resilience/inject.d.ts.map +1 -0
- package/dist/mcp/tools/chaos-resilience/inject.js +520 -0
- package/dist/mcp/tools/chaos-resilience/inject.js.map +1 -0
- package/dist/mcp/tools/code-intelligence/analyze.d.ts +140 -0
- package/dist/mcp/tools/code-intelligence/analyze.d.ts.map +1 -0
- package/dist/mcp/tools/code-intelligence/analyze.js +570 -0
- package/dist/mcp/tools/code-intelligence/analyze.js.map +1 -0
- package/dist/mcp/tools/contract-testing/validate.d.ts +90 -0
- package/dist/mcp/tools/contract-testing/validate.d.ts.map +1 -0
- package/dist/mcp/tools/contract-testing/validate.js +515 -0
- package/dist/mcp/tools/contract-testing/validate.js.map +1 -0
- package/dist/mcp/tools/coverage-analysis/index.d.ts +111 -0
- package/dist/mcp/tools/coverage-analysis/index.d.ts.map +1 -0
- package/dist/mcp/tools/coverage-analysis/index.js +577 -0
- package/dist/mcp/tools/coverage-analysis/index.js.map +1 -0
- package/dist/mcp/tools/defect-intelligence/predict.d.ts +67 -0
- package/dist/mcp/tools/defect-intelligence/predict.d.ts.map +1 -0
- package/dist/mcp/tools/defect-intelligence/predict.js +359 -0
- package/dist/mcp/tools/defect-intelligence/predict.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +40 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +82 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/learning-optimization/optimize.d.ts +123 -0
- package/dist/mcp/tools/learning-optimization/optimize.d.ts.map +1 -0
- package/dist/mcp/tools/learning-optimization/optimize.js +563 -0
- package/dist/mcp/tools/learning-optimization/optimize.js.map +1 -0
- package/dist/mcp/tools/quality-assessment/evaluate.d.ts +83 -0
- package/dist/mcp/tools/quality-assessment/evaluate.d.ts.map +1 -0
- package/dist/mcp/tools/quality-assessment/evaluate.js +277 -0
- package/dist/mcp/tools/quality-assessment/evaluate.js.map +1 -0
- package/dist/mcp/tools/registry.d.ts +79 -0
- package/dist/mcp/tools/registry.d.ts.map +1 -0
- package/dist/mcp/tools/registry.js +181 -0
- package/dist/mcp/tools/registry.js.map +1 -0
- package/dist/mcp/tools/requirements-validation/validate.d.ts +81 -0
- package/dist/mcp/tools/requirements-validation/validate.d.ts.map +1 -0
- package/dist/mcp/tools/requirements-validation/validate.js +270 -0
- package/dist/mcp/tools/requirements-validation/validate.js.map +1 -0
- package/dist/mcp/tools/security-compliance/scan.d.ts +75 -0
- package/dist/mcp/tools/security-compliance/scan.d.ts.map +1 -0
- package/dist/mcp/tools/security-compliance/scan.js +258 -0
- package/dist/mcp/tools/security-compliance/scan.js.map +1 -0
- package/dist/mcp/tools/test-execution/execute.d.ts +65 -0
- package/dist/mcp/tools/test-execution/execute.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/execute.js +196 -0
- package/dist/mcp/tools/test-execution/execute.js.map +1 -0
- package/dist/mcp/tools/test-generation/generate.d.ts +53 -0
- package/dist/mcp/tools/test-generation/generate.d.ts.map +1 -0
- package/dist/mcp/tools/test-generation/generate.js +437 -0
- package/dist/mcp/tools/test-generation/generate.js.map +1 -0
- package/dist/mcp/tools/visual-accessibility/index.d.ts +144 -0
- package/dist/mcp/tools/visual-accessibility/index.d.ts.map +1 -0
- package/dist/mcp/tools/visual-accessibility/index.js +562 -0
- package/dist/mcp/tools/visual-accessibility/index.js.map +1 -0
- package/dist/mcp/transport/index.d.ts +12 -0
- package/dist/mcp/transport/index.d.ts.map +1 -0
- package/dist/mcp/transport/index.js +21 -0
- package/dist/mcp/transport/index.js.map +1 -0
- package/dist/mcp/transport/stdio.d.ts +95 -0
- package/dist/mcp/transport/stdio.d.ts.map +1 -0
- package/dist/mcp/transport/stdio.js +226 -0
- package/dist/mcp/transport/stdio.js.map +1 -0
- package/dist/mcp/types.d.ts +455 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/neural-optimizer/index.d.ts +55 -0
- package/dist/neural-optimizer/index.d.ts.map +1 -0
- package/dist/neural-optimizer/index.js +57 -0
- package/dist/neural-optimizer/index.js.map +1 -0
- package/dist/neural-optimizer/replay-buffer.d.ts +126 -0
- package/dist/neural-optimizer/replay-buffer.d.ts.map +1 -0
- package/dist/neural-optimizer/replay-buffer.js +355 -0
- package/dist/neural-optimizer/replay-buffer.js.map +1 -0
- package/dist/neural-optimizer/swarm-topology.d.ts +157 -0
- package/dist/neural-optimizer/swarm-topology.d.ts.map +1 -0
- package/dist/neural-optimizer/swarm-topology.js +384 -0
- package/dist/neural-optimizer/swarm-topology.js.map +1 -0
- package/dist/neural-optimizer/topology-optimizer.d.ts +137 -0
- package/dist/neural-optimizer/topology-optimizer.d.ts.map +1 -0
- package/dist/neural-optimizer/topology-optimizer.js +656 -0
- package/dist/neural-optimizer/topology-optimizer.js.map +1 -0
- package/dist/neural-optimizer/types.d.ts +333 -0
- package/dist/neural-optimizer/types.d.ts.map +1 -0
- package/dist/neural-optimizer/types.js +57 -0
- package/dist/neural-optimizer/types.js.map +1 -0
- package/dist/neural-optimizer/value-network.d.ts +129 -0
- package/dist/neural-optimizer/value-network.d.ts.map +1 -0
- package/dist/neural-optimizer/value-network.js +278 -0
- package/dist/neural-optimizer/value-network.js.map +1 -0
- package/dist/optimization/auto-tuner.d.ts +207 -0
- package/dist/optimization/auto-tuner.d.ts.map +1 -0
- package/dist/optimization/auto-tuner.js +641 -0
- package/dist/optimization/auto-tuner.js.map +1 -0
- package/dist/optimization/index.d.ts +16 -0
- package/dist/optimization/index.d.ts.map +1 -0
- package/dist/optimization/index.js +14 -0
- package/dist/optimization/index.js.map +1 -0
- package/dist/optimization/metric-collectors.d.ts +145 -0
- package/dist/optimization/metric-collectors.d.ts.map +1 -0
- package/dist/optimization/metric-collectors.js +401 -0
- package/dist/optimization/metric-collectors.js.map +1 -0
- package/dist/optimization/qe-workers.d.ts +143 -0
- package/dist/optimization/qe-workers.d.ts.map +1 -0
- package/dist/optimization/qe-workers.js +510 -0
- package/dist/optimization/qe-workers.js.map +1 -0
- package/dist/optimization/tuning-algorithm.d.ts +93 -0
- package/dist/optimization/tuning-algorithm.d.ts.map +1 -0
- package/dist/optimization/tuning-algorithm.js +278 -0
- package/dist/optimization/tuning-algorithm.js.map +1 -0
- package/dist/optimization/types.d.ts +211 -0
- package/dist/optimization/types.d.ts.map +1 -0
- package/dist/optimization/types.js +81 -0
- package/dist/optimization/types.js.map +1 -0
- package/dist/routing/index.d.ts +15 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +17 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/qe-agent-registry.d.ts +58 -0
- package/dist/routing/qe-agent-registry.d.ts.map +1 -0
- package/dist/routing/qe-agent-registry.js +909 -0
- package/dist/routing/qe-agent-registry.js.map +1 -0
- package/dist/routing/qe-task-router.d.ts +82 -0
- package/dist/routing/qe-task-router.d.ts.map +1 -0
- package/dist/routing/qe-task-router.js +453 -0
- package/dist/routing/qe-task-router.js.map +1 -0
- package/dist/routing/routing-feedback.d.ts +82 -0
- package/dist/routing/routing-feedback.d.ts.map +1 -0
- package/dist/routing/routing-feedback.js +272 -0
- package/dist/routing/routing-feedback.js.map +1 -0
- package/dist/routing/types.d.ts +225 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +27 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/shared/embeddings/embedding-cache.d.ts +62 -0
- package/dist/shared/embeddings/embedding-cache.d.ts.map +1 -0
- package/dist/shared/embeddings/embedding-cache.js +136 -0
- package/dist/shared/embeddings/embedding-cache.js.map +1 -0
- package/dist/shared/embeddings/index.d.ts +35 -0
- package/dist/shared/embeddings/index.d.ts.map +1 -0
- package/dist/shared/embeddings/index.js +33 -0
- package/dist/shared/embeddings/index.js.map +1 -0
- package/dist/shared/embeddings/nomic-embedder.d.ts +128 -0
- package/dist/shared/embeddings/nomic-embedder.d.ts.map +1 -0
- package/dist/shared/embeddings/nomic-embedder.js +322 -0
- package/dist/shared/embeddings/nomic-embedder.js.map +1 -0
- package/dist/shared/embeddings/ollama-client.d.ts +40 -0
- package/dist/shared/embeddings/ollama-client.d.ts.map +1 -0
- package/dist/shared/embeddings/ollama-client.js +140 -0
- package/dist/shared/embeddings/ollama-client.js.map +1 -0
- package/dist/shared/embeddings/types.d.ts +136 -0
- package/dist/shared/embeddings/types.d.ts.map +1 -0
- package/dist/shared/embeddings/types.js +26 -0
- package/dist/shared/embeddings/types.js.map +1 -0
- package/dist/shared/entities/agent.d.ts +40 -0
- package/dist/shared/entities/agent.d.ts.map +1 -0
- package/dist/shared/entities/agent.js +107 -0
- package/dist/shared/entities/agent.js.map +1 -0
- package/dist/shared/entities/base-entity.d.ts +37 -0
- package/dist/shared/entities/base-entity.d.ts.map +1 -0
- package/dist/shared/entities/base-entity.js +56 -0
- package/dist/shared/entities/base-entity.js.map +1 -0
- package/dist/shared/entities/index.d.ts +6 -0
- package/dist/shared/entities/index.d.ts.map +1 -0
- package/dist/shared/entities/index.js +6 -0
- package/dist/shared/entities/index.js.map +1 -0
- package/dist/shared/events/domain-events.d.ts +194 -0
- package/dist/shared/events/domain-events.d.ts.map +1 -0
- package/dist/shared/events/domain-events.js +74 -0
- package/dist/shared/events/domain-events.js.map +1 -0
- package/dist/shared/events/index.d.ts +5 -0
- package/dist/shared/events/index.d.ts.map +1 -0
- package/dist/shared/events/index.js +5 -0
- package/dist/shared/events/index.js.map +1 -0
- package/dist/shared/git/git-analyzer.d.ts +135 -0
- package/dist/shared/git/git-analyzer.d.ts.map +1 -0
- package/dist/shared/git/git-analyzer.js +562 -0
- package/dist/shared/git/git-analyzer.js.map +1 -0
- package/dist/shared/git/index.d.ts +6 -0
- package/dist/shared/git/index.d.ts.map +1 -0
- package/dist/shared/git/index.js +5 -0
- package/dist/shared/git/index.js.map +1 -0
- package/dist/shared/http/http-client.d.ts +92 -0
- package/dist/shared/http/http-client.d.ts.map +1 -0
- package/dist/shared/http/http-client.js +295 -0
- package/dist/shared/http/http-client.js.map +1 -0
- package/dist/shared/http/index.d.ts +5 -0
- package/dist/shared/http/index.d.ts.map +1 -0
- package/dist/shared/http/index.js +5 -0
- package/dist/shared/http/index.js.map +1 -0
- package/dist/shared/index.d.ts +18 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +17 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/io/file-reader.d.ts +107 -0
- package/dist/shared/io/file-reader.d.ts.map +1 -0
- package/dist/shared/io/file-reader.js +408 -0
- package/dist/shared/io/file-reader.js.map +1 -0
- package/dist/shared/io/index.d.ts +6 -0
- package/dist/shared/io/index.d.ts.map +1 -0
- package/dist/shared/io/index.js +12 -0
- package/dist/shared/io/index.js.map +1 -0
- package/dist/shared/llm/cache.d.ts +163 -0
- package/dist/shared/llm/cache.d.ts.map +1 -0
- package/dist/shared/llm/cache.js +368 -0
- package/dist/shared/llm/cache.js.map +1 -0
- package/dist/shared/llm/circuit-breaker.d.ts +117 -0
- package/dist/shared/llm/circuit-breaker.d.ts.map +1 -0
- package/dist/shared/llm/circuit-breaker.js +294 -0
- package/dist/shared/llm/circuit-breaker.js.map +1 -0
- package/dist/shared/llm/cost-tracker.d.ts +133 -0
- package/dist/shared/llm/cost-tracker.d.ts.map +1 -0
- package/dist/shared/llm/cost-tracker.js +342 -0
- package/dist/shared/llm/cost-tracker.js.map +1 -0
- package/dist/shared/llm/index.d.ts +50 -0
- package/dist/shared/llm/index.d.ts.map +1 -0
- package/dist/shared/llm/index.js +56 -0
- package/dist/shared/llm/index.js.map +1 -0
- package/dist/shared/llm/interfaces.d.ts +503 -0
- package/dist/shared/llm/interfaces.d.ts.map +1 -0
- package/dist/shared/llm/interfaces.js +33 -0
- package/dist/shared/llm/interfaces.js.map +1 -0
- package/dist/shared/llm/provider-manager.d.ts +158 -0
- package/dist/shared/llm/provider-manager.d.ts.map +1 -0
- package/dist/shared/llm/provider-manager.js +527 -0
- package/dist/shared/llm/provider-manager.js.map +1 -0
- package/dist/shared/llm/providers/claude.d.ts +99 -0
- package/dist/shared/llm/providers/claude.d.ts.map +1 -0
- package/dist/shared/llm/providers/claude.js +394 -0
- package/dist/shared/llm/providers/claude.js.map +1 -0
- package/dist/shared/llm/providers/index.d.ts +8 -0
- package/dist/shared/llm/providers/index.d.ts.map +1 -0
- package/dist/shared/llm/providers/index.js +8 -0
- package/dist/shared/llm/providers/index.js.map +1 -0
- package/dist/shared/llm/providers/ollama.d.ts +91 -0
- package/dist/shared/llm/providers/ollama.d.ts.map +1 -0
- package/dist/shared/llm/providers/ollama.js +391 -0
- package/dist/shared/llm/providers/ollama.js.map +1 -0
- package/dist/shared/llm/providers/openai.d.ts +98 -0
- package/dist/shared/llm/providers/openai.d.ts.map +1 -0
- package/dist/shared/llm/providers/openai.js +440 -0
- package/dist/shared/llm/providers/openai.js.map +1 -0
- package/dist/shared/metrics/code-metrics.d.ts +75 -0
- package/dist/shared/metrics/code-metrics.d.ts.map +1 -0
- package/dist/shared/metrics/code-metrics.js +395 -0
- package/dist/shared/metrics/code-metrics.js.map +1 -0
- package/dist/shared/metrics/index.d.ts +9 -0
- package/dist/shared/metrics/index.d.ts.map +1 -0
- package/dist/shared/metrics/index.js +7 -0
- package/dist/shared/metrics/index.js.map +1 -0
- package/dist/shared/metrics/system-metrics.d.ts +109 -0
- package/dist/shared/metrics/system-metrics.d.ts.map +1 -0
- package/dist/shared/metrics/system-metrics.js +267 -0
- package/dist/shared/metrics/system-metrics.js.map +1 -0
- package/dist/shared/parsers/index.d.ts +6 -0
- package/dist/shared/parsers/index.d.ts.map +1 -0
- package/dist/shared/parsers/index.js +6 -0
- package/dist/shared/parsers/index.js.map +1 -0
- package/dist/shared/parsers/typescript-parser.d.ts +211 -0
- package/dist/shared/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/shared/parsers/typescript-parser.js +561 -0
- package/dist/shared/parsers/typescript-parser.js.map +1 -0
- package/dist/shared/security/compliance-patterns.d.ts +78 -0
- package/dist/shared/security/compliance-patterns.d.ts.map +1 -0
- package/dist/shared/security/compliance-patterns.js +543 -0
- package/dist/shared/security/compliance-patterns.js.map +1 -0
- package/dist/shared/security/index.d.ts +8 -0
- package/dist/shared/security/index.d.ts.map +1 -0
- package/dist/shared/security/index.js +6 -0
- package/dist/shared/security/index.js.map +1 -0
- package/dist/shared/security/osv-client.d.ts +191 -0
- package/dist/shared/security/osv-client.d.ts.map +1 -0
- package/dist/shared/security/osv-client.js +256 -0
- package/dist/shared/security/osv-client.js.map +1 -0
- package/dist/shared/types/index.d.ts +66 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/shared/types/index.js +25 -0
- package/dist/shared/types/index.js.map +1 -0
- package/dist/shared/value-objects/index.d.ts +73 -0
- package/dist/shared/value-objects/index.d.ts.map +1 -0
- package/dist/shared/value-objects/index.js +229 -0
- package/dist/shared/value-objects/index.js.map +1 -0
- package/dist/strange-loop/healing-controller.d.ts +125 -0
- package/dist/strange-loop/healing-controller.d.ts.map +1 -0
- package/dist/strange-loop/healing-controller.js +648 -0
- package/dist/strange-loop/healing-controller.js.map +1 -0
- package/dist/strange-loop/index.d.ts +26 -0
- package/dist/strange-loop/index.d.ts.map +1 -0
- package/dist/strange-loop/index.js +30 -0
- package/dist/strange-loop/index.js.map +1 -0
- package/dist/strange-loop/self-model.d.ts +84 -0
- package/dist/strange-loop/self-model.d.ts.map +1 -0
- package/dist/strange-loop/self-model.js +378 -0
- package/dist/strange-loop/self-model.js.map +1 -0
- package/dist/strange-loop/strange-loop.d.ts +112 -0
- package/dist/strange-loop/strange-loop.d.ts.map +1 -0
- package/dist/strange-loop/strange-loop.js +354 -0
- package/dist/strange-loop/strange-loop.js.map +1 -0
- package/dist/strange-loop/swarm-observer.d.ts +89 -0
- package/dist/strange-loop/swarm-observer.d.ts.map +1 -0
- package/dist/strange-loop/swarm-observer.js +341 -0
- package/dist/strange-loop/swarm-observer.js.map +1 -0
- package/dist/strange-loop/topology-analyzer.d.ts +87 -0
- package/dist/strange-loop/topology-analyzer.d.ts.map +1 -0
- package/dist/strange-loop/topology-analyzer.js +441 -0
- package/dist/strange-loop/topology-analyzer.js.map +1 -0
- package/dist/strange-loop/types.d.ts +425 -0
- package/dist/strange-loop/types.d.ts.map +1 -0
- package/dist/strange-loop/types.js +22 -0
- package/dist/strange-loop/types.js.map +1 -0
- package/dist/time-crystal/default-phases.d.ts +95 -0
- package/dist/time-crystal/default-phases.d.ts.map +1 -0
- package/dist/time-crystal/default-phases.js +456 -0
- package/dist/time-crystal/default-phases.js.map +1 -0
- package/dist/time-crystal/index.d.ts +28 -0
- package/dist/time-crystal/index.d.ts.map +1 -0
- package/dist/time-crystal/index.js +55 -0
- package/dist/time-crystal/index.js.map +1 -0
- package/dist/time-crystal/oscillator.d.ts +195 -0
- package/dist/time-crystal/oscillator.d.ts.map +1 -0
- package/dist/time-crystal/oscillator.js +358 -0
- package/dist/time-crystal/oscillator.js.map +1 -0
- package/dist/time-crystal/phase-executor.d.ts +212 -0
- package/dist/time-crystal/phase-executor.d.ts.map +1 -0
- package/dist/time-crystal/phase-executor.js +327 -0
- package/dist/time-crystal/phase-executor.js.map +1 -0
- package/dist/time-crystal/scheduler.d.ts +239 -0
- package/dist/time-crystal/scheduler.d.ts.map +1 -0
- package/dist/time-crystal/scheduler.js +860 -0
- package/dist/time-crystal/scheduler.js.map +1 -0
- package/dist/time-crystal/test-runner.d.ts +141 -0
- package/dist/time-crystal/test-runner.d.ts.map +1 -0
- package/dist/time-crystal/test-runner.js +529 -0
- package/dist/time-crystal/test-runner.js.map +1 -0
- package/dist/time-crystal/types.d.ts +269 -0
- package/dist/time-crystal/types.d.ts.map +1 -0
- package/dist/time-crystal/types.js +51 -0
- package/dist/time-crystal/types.js.map +1 -0
- package/dist/workers/base-worker.d.ts +83 -0
- package/dist/workers/base-worker.d.ts.map +1 -0
- package/dist/workers/base-worker.js +235 -0
- package/dist/workers/base-worker.js.map +1 -0
- package/dist/workers/daemon.d.ts +73 -0
- package/dist/workers/daemon.d.ts.map +1 -0
- package/dist/workers/daemon.js +193 -0
- package/dist/workers/daemon.js.map +1 -0
- package/dist/workers/index.d.ts +91 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +95 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/interfaces.d.ts +270 -0
- package/dist/workers/interfaces.d.ts.map +1 -0
- package/dist/workers/interfaces.js +9 -0
- package/dist/workers/interfaces.js.map +1 -0
- package/dist/workers/worker-manager.d.ts +87 -0
- package/dist/workers/worker-manager.d.ts.map +1 -0
- package/dist/workers/worker-manager.js +345 -0
- package/dist/workers/worker-manager.js.map +1 -0
- package/dist/workers/workers/compliance-checker.d.ts +28 -0
- package/dist/workers/workers/compliance-checker.d.ts.map +1 -0
- package/dist/workers/workers/compliance-checker.js +334 -0
- package/dist/workers/workers/compliance-checker.js.map +1 -0
- package/dist/workers/workers/coverage-tracker.d.ts +24 -0
- package/dist/workers/workers/coverage-tracker.d.ts.map +1 -0
- package/dist/workers/workers/coverage-tracker.js +265 -0
- package/dist/workers/workers/coverage-tracker.js.map +1 -0
- package/dist/workers/workers/defect-predictor.d.ts +22 -0
- package/dist/workers/workers/defect-predictor.d.ts.map +1 -0
- package/dist/workers/workers/defect-predictor.js +292 -0
- package/dist/workers/workers/defect-predictor.js.map +1 -0
- package/dist/workers/workers/flaky-detector.d.ts +25 -0
- package/dist/workers/workers/flaky-detector.d.ts.map +1 -0
- package/dist/workers/workers/flaky-detector.js +288 -0
- package/dist/workers/workers/flaky-detector.js.map +1 -0
- package/dist/workers/workers/index.d.ts +17 -0
- package/dist/workers/workers/index.d.ts.map +1 -0
- package/dist/workers/workers/index.js +17 -0
- package/dist/workers/workers/index.js.map +1 -0
- package/dist/workers/workers/learning-consolidation.d.ts +25 -0
- package/dist/workers/workers/learning-consolidation.d.ts.map +1 -0
- package/dist/workers/workers/learning-consolidation.js +324 -0
- package/dist/workers/workers/learning-consolidation.js.map +1 -0
- package/dist/workers/workers/performance-baseline.d.ts +25 -0
- package/dist/workers/workers/performance-baseline.d.ts.map +1 -0
- package/dist/workers/workers/performance-baseline.js +315 -0
- package/dist/workers/workers/performance-baseline.js.map +1 -0
- package/dist/workers/workers/quality-gate.d.ts +23 -0
- package/dist/workers/workers/quality-gate.d.ts.map +1 -0
- package/dist/workers/workers/quality-gate.js +348 -0
- package/dist/workers/workers/quality-gate.js.map +1 -0
- package/dist/workers/workers/regression-monitor.d.ts +24 -0
- package/dist/workers/workers/regression-monitor.d.ts.map +1 -0
- package/dist/workers/workers/regression-monitor.js +280 -0
- package/dist/workers/workers/regression-monitor.js.map +1 -0
- package/dist/workers/workers/security-scan.d.ts +22 -0
- package/dist/workers/workers/security-scan.d.ts.map +1 -0
- package/dist/workers/workers/security-scan.js +264 -0
- package/dist/workers/workers/security-scan.js.map +1 -0
- package/dist/workers/workers/test-health.d.ts +26 -0
- package/dist/workers/workers/test-health.d.ts.map +1 -0
- package/dist/workers/workers/test-health.js +258 -0
- package/dist/workers/workers/test-health.js.map +1 -0
- package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +352 -0
- package/implementation/README.md +90 -0
- package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +312 -0
- package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +484 -0
- package/implementation/adrs/ADR-032-time-crystal-scheduling.md +530 -0
- package/implementation/adrs/ADR-033-early-exit-testing.md +634 -0
- package/implementation/adrs/ADR-034-neural-topology-optimizer.md +589 -0
- package/implementation/adrs/ADR-035-causal-discovery.md +610 -0
- package/implementation/adrs/ADR-036-result-persistence.md +326 -0
- package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +105 -0
- package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +154 -0
- package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +179 -0
- package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +240 -0
- package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +296 -0
- package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +517 -0
- package/implementation/adrs/v3-adrs.md +2783 -0
- package/implementation/planning/AQE-V3-MASTER-PLAN.md +815 -0
- package/package.json +88 -0
- package/security-scan-report-2026-01-11.md +410 -0
- package/security-verification-report-2026-01-11.md +278 -0
- package/src/benchmarks/performance-benchmarks.ts +646 -0
- package/src/benchmarks/run-benchmarks.ts +324 -0
- package/src/causal-discovery/causal-graph.ts +450 -0
- package/src/causal-discovery/discovery-engine.ts +438 -0
- package/src/causal-discovery/index.ts +117 -0
- package/src/causal-discovery/types.ts +456 -0
- package/src/causal-discovery/weight-matrix.ts +453 -0
- package/src/cli/commands/qe-tools.ts +634 -0
- package/src/cli/index.ts +1976 -0
- package/src/compatibility/agent-mapper.ts +291 -0
- package/src/compatibility/cli-adapter.ts +277 -0
- package/src/compatibility/config-migrator.ts +334 -0
- package/src/compatibility/index.ts +112 -0
- package/src/compatibility/mcp-adapter.ts +248 -0
- package/src/compatibility/types.ts +156 -0
- package/src/coordination/claims/claim-repository.ts +636 -0
- package/src/coordination/claims/claim-service.ts +675 -0
- package/src/coordination/claims/handoff-manager.ts +535 -0
- package/src/coordination/claims/index.ts +276 -0
- package/src/coordination/claims/interfaces.ts +687 -0
- package/src/coordination/claims/work-stealing.ts +436 -0
- package/src/coordination/cross-domain-router.ts +492 -0
- package/src/coordination/index.ts +127 -0
- package/src/coordination/interfaces.ts +691 -0
- package/src/coordination/protocol-executor.ts +760 -0
- package/src/coordination/protocols/code-intelligence-index.ts +855 -0
- package/src/coordination/protocols/defect-investigation.ts +1184 -0
- package/src/coordination/protocols/index.ts +11 -0
- package/src/coordination/protocols/learning-consolidation.ts +1181 -0
- package/src/coordination/protocols/morning-sync.ts +1055 -0
- package/src/coordination/protocols/quality-gate.ts +1566 -0
- package/src/coordination/protocols/security-audit.ts +1587 -0
- package/src/coordination/queen-coordinator.ts +1176 -0
- package/src/coordination/result-saver.ts +780 -0
- package/src/coordination/task-executor.ts +1146 -0
- package/src/coordination/workflow-orchestrator.ts +1917 -0
- package/src/domains/chaos-resilience/coordinator.ts +1032 -0
- package/src/domains/chaos-resilience/index.ts +143 -0
- package/src/domains/chaos-resilience/interfaces.ts +659 -0
- package/src/domains/chaos-resilience/plugin.ts +691 -0
- package/src/domains/chaos-resilience/services/chaos-engineer.ts +1097 -0
- package/src/domains/chaos-resilience/services/index.ts +19 -0
- package/src/domains/chaos-resilience/services/load-tester.ts +799 -0
- package/src/domains/chaos-resilience/services/performance-profiler.ts +792 -0
- package/src/domains/code-intelligence/coordinator.ts +631 -0
- package/src/domains/code-intelligence/index.ts +86 -0
- package/src/domains/code-intelligence/interfaces.ts +162 -0
- package/src/domains/code-intelligence/plugin.ts +451 -0
- package/src/domains/code-intelligence/services/impact-analyzer.ts +567 -0
- package/src/domains/code-intelligence/services/index.ts +26 -0
- package/src/domains/code-intelligence/services/knowledge-graph.ts +1067 -0
- package/src/domains/code-intelligence/services/semantic-analyzer.ts +901 -0
- package/src/domains/contract-testing/coordinator.ts +1038 -0
- package/src/domains/contract-testing/index.ts +122 -0
- package/src/domains/contract-testing/interfaces.ts +458 -0
- package/src/domains/contract-testing/plugin.ts +746 -0
- package/src/domains/contract-testing/services/api-compatibility.ts +748 -0
- package/src/domains/contract-testing/services/contract-validator.ts +1700 -0
- package/src/domains/contract-testing/services/index.ts +19 -0
- package/src/domains/contract-testing/services/schema-validator.ts +1102 -0
- package/src/domains/coverage-analysis/coordinator.ts +485 -0
- package/src/domains/coverage-analysis/index.ts +114 -0
- package/src/domains/coverage-analysis/interfaces.ts +142 -0
- package/src/domains/coverage-analysis/plugin.ts +172 -0
- package/src/domains/coverage-analysis/services/coverage-analyzer.ts +449 -0
- package/src/domains/coverage-analysis/services/coverage-embedder.ts +733 -0
- package/src/domains/coverage-analysis/services/coverage-parser.ts +753 -0
- package/src/domains/coverage-analysis/services/gap-detector.ts +592 -0
- package/src/domains/coverage-analysis/services/hnsw-index.ts +728 -0
- package/src/domains/coverage-analysis/services/index.ts +61 -0
- package/src/domains/coverage-analysis/services/risk-scorer.ts +540 -0
- package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +747 -0
- package/src/domains/defect-intelligence/coordinator.ts +635 -0
- package/src/domains/defect-intelligence/index.ts +83 -0
- package/src/domains/defect-intelligence/interfaces.ts +152 -0
- package/src/domains/defect-intelligence/plugin.ts +483 -0
- package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +494 -0
- package/src/domains/defect-intelligence/services/defect-predictor.ts +852 -0
- package/src/domains/defect-intelligence/services/index.ts +37 -0
- package/src/domains/defect-intelligence/services/pattern-learner.ts +738 -0
- package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +637 -0
- package/src/domains/domain-interface.ts +77 -0
- package/src/domains/index.ts +23 -0
- package/src/domains/learning-optimization/coordinator.ts +1215 -0
- package/src/domains/learning-optimization/index.ts +127 -0
- package/src/domains/learning-optimization/interfaces.ts +570 -0
- package/src/domains/learning-optimization/plugin.ts +851 -0
- package/src/domains/learning-optimization/services/index.ts +29 -0
- package/src/domains/learning-optimization/services/learning-coordinator.ts +972 -0
- package/src/domains/learning-optimization/services/metrics-optimizer.ts +915 -0
- package/src/domains/learning-optimization/services/production-intel.ts +971 -0
- package/src/domains/learning-optimization/services/transfer-specialist.ts +723 -0
- package/src/domains/quality-assessment/coherence/gate-controller.ts +549 -0
- package/src/domains/quality-assessment/coherence/index.ts +211 -0
- package/src/domains/quality-assessment/coherence/lambda-calculator.ts +384 -0
- package/src/domains/quality-assessment/coherence/partition-detector.ts +469 -0
- package/src/domains/quality-assessment/coherence/types.ts +384 -0
- package/src/domains/quality-assessment/coordinator.ts +605 -0
- package/src/domains/quality-assessment/index.ts +97 -0
- package/src/domains/quality-assessment/interfaces.ts +152 -0
- package/src/domains/quality-assessment/plugin.ts +496 -0
- package/src/domains/quality-assessment/services/coherence-gate.ts +358 -0
- package/src/domains/quality-assessment/services/deployment-advisor.ts +571 -0
- package/src/domains/quality-assessment/services/index.ts +34 -0
- package/src/domains/quality-assessment/services/quality-analyzer.ts +670 -0
- package/src/domains/quality-assessment/services/quality-gate.ts +384 -0
- package/src/domains/requirements-validation/coordinator.ts +812 -0
- package/src/domains/requirements-validation/index.ts +92 -0
- package/src/domains/requirements-validation/interfaces.ts +303 -0
- package/src/domains/requirements-validation/plugin.ts +576 -0
- package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +676 -0
- package/src/domains/requirements-validation/services/index.ts +20 -0
- package/src/domains/requirements-validation/services/requirements-validator.ts +559 -0
- package/src/domains/requirements-validation/services/testability-scorer.ts +639 -0
- package/src/domains/security-compliance/coordinator.ts +757 -0
- package/src/domains/security-compliance/index.ts +120 -0
- package/src/domains/security-compliance/interfaces.ts +434 -0
- package/src/domains/security-compliance/plugin.ts +509 -0
- package/src/domains/security-compliance/services/compliance-validator.ts +1226 -0
- package/src/domains/security-compliance/services/index.ts +31 -0
- package/src/domains/security-compliance/services/security-auditor.ts +2227 -0
- package/src/domains/security-compliance/services/security-scanner.ts +2354 -0
- package/src/domains/security-compliance/services/semgrep-integration.ts +289 -0
- package/src/domains/test-execution/coordinator.ts +426 -0
- package/src/domains/test-execution/index.ts +76 -0
- package/src/domains/test-execution/interfaces.ts +119 -0
- package/src/domains/test-execution/plugin.ts +208 -0
- package/src/domains/test-execution/services/flaky-detector.ts +1240 -0
- package/src/domains/test-execution/services/index.ts +8 -0
- package/src/domains/test-execution/services/retry-handler.ts +820 -0
- package/src/domains/test-execution/services/test-executor.ts +885 -0
- package/src/domains/test-generation/coordinator.ts +656 -0
- package/src/domains/test-generation/index.ts +77 -0
- package/src/domains/test-generation/interfaces.ts +118 -0
- package/src/domains/test-generation/plugin.ts +397 -0
- package/src/domains/test-generation/services/index.ts +23 -0
- package/src/domains/test-generation/services/pattern-matcher.ts +1725 -0
- package/src/domains/test-generation/services/test-generator.ts +2750 -0
- package/src/domains/visual-accessibility/coordinator.ts +860 -0
- package/src/domains/visual-accessibility/index.ts +116 -0
- package/src/domains/visual-accessibility/interfaces.ts +435 -0
- package/src/domains/visual-accessibility/plugin.ts +568 -0
- package/src/domains/visual-accessibility/services/accessibility-tester.ts +982 -0
- package/src/domains/visual-accessibility/services/axe-core-audit.ts +630 -0
- package/src/domains/visual-accessibility/services/index.ts +28 -0
- package/src/domains/visual-accessibility/services/responsive-tester.ts +934 -0
- package/src/domains/visual-accessibility/services/visual-tester.ts +458 -0
- package/src/early-exit/early-exit-controller.ts +490 -0
- package/src/early-exit/early-exit-decision.ts +391 -0
- package/src/early-exit/index.ts +115 -0
- package/src/early-exit/quality-signal.ts +389 -0
- package/src/early-exit/speculative-executor.ts +505 -0
- package/src/early-exit/types.ts +407 -0
- package/src/feedback/coverage-learner.ts +456 -0
- package/src/feedback/feedback-loop.ts +426 -0
- package/src/feedback/index.ts +72 -0
- package/src/feedback/pattern-promotion.ts +373 -0
- package/src/feedback/quality-score-calculator.ts +334 -0
- package/src/feedback/test-outcome-tracker.ts +450 -0
- package/src/feedback/types.ts +497 -0
- package/src/index.ts +224 -0
- package/src/init/agents-installer.ts +536 -0
- package/src/init/index.ts +80 -0
- package/src/init/init-wizard.ts +1061 -0
- package/src/init/project-analyzer.ts +696 -0
- package/src/init/self-configurator.ts +488 -0
- package/src/init/skills-installer.ts +467 -0
- package/src/init/types.ts +432 -0
- package/src/integrations/ruvector/ast-complexity.ts +470 -0
- package/src/integrations/ruvector/coverage-router.ts +594 -0
- package/src/integrations/ruvector/diff-risk-classifier.ts +759 -0
- package/src/integrations/ruvector/fallback.ts +942 -0
- package/src/integrations/ruvector/graph-boundaries.ts +809 -0
- package/src/integrations/ruvector/index.ts +363 -0
- package/src/integrations/ruvector/interfaces.ts +609 -0
- package/src/integrations/ruvector/q-learning-router.ts +550 -0
- package/src/kernel/agent-coordinator.ts +165 -0
- package/src/kernel/agentdb-backend.ts +504 -0
- package/src/kernel/event-bus.ts +129 -0
- package/src/kernel/hybrid-backend.ts +538 -0
- package/src/kernel/index.ts +28 -0
- package/src/kernel/interfaces.ts +257 -0
- package/src/kernel/kernel.ts +285 -0
- package/src/kernel/memory-backend.ts +169 -0
- package/src/kernel/memory-factory.ts +293 -0
- package/src/kernel/plugin-loader.ts +179 -0
- package/src/learning/index.ts +219 -0
- package/src/learning/pattern-store.ts +990 -0
- package/src/learning/qe-guidance.ts +832 -0
- package/src/learning/qe-hooks.ts +644 -0
- package/src/learning/qe-patterns.ts +449 -0
- package/src/learning/qe-reasoning-bank.ts +951 -0
- package/src/learning/real-embeddings.ts +277 -0
- package/src/learning/real-qe-reasoning-bank.ts +833 -0
- package/src/learning/sqlite-persistence.ts +554 -0
- package/src/mcp/entry.ts +59 -0
- package/src/mcp/handlers/agent-handlers.ts +285 -0
- package/src/mcp/handlers/core-handlers.ts +317 -0
- package/src/mcp/handlers/domain-handlers.ts +1444 -0
- package/src/mcp/handlers/index.ts +57 -0
- package/src/mcp/handlers/memory-handlers.ts +338 -0
- package/src/mcp/handlers/task-handlers.ts +363 -0
- package/src/mcp/index.ts +30 -0
- package/src/mcp/metrics/index.ts +14 -0
- package/src/mcp/metrics/metrics-collector.ts +503 -0
- package/src/mcp/protocol-server.ts +752 -0
- package/src/mcp/security/cve-prevention.ts +742 -0
- package/src/mcp/security/index.ts +356 -0
- package/src/mcp/security/oauth21-provider.ts +821 -0
- package/src/mcp/security/rate-limiter.ts +615 -0
- package/src/mcp/security/sampling-server.ts +662 -0
- package/src/mcp/security/schema-validator.ts +855 -0
- package/src/mcp/server.ts +657 -0
- package/src/mcp/tool-registry.ts +391 -0
- package/src/mcp/tools/base.ts +399 -0
- package/src/mcp/tools/chaos-resilience/inject.ts +699 -0
- package/src/mcp/tools/code-intelligence/analyze.ts +745 -0
- package/src/mcp/tools/contract-testing/validate.ts +708 -0
- package/src/mcp/tools/coverage-analysis/index.ts +770 -0
- package/src/mcp/tools/defect-intelligence/predict.ts +466 -0
- package/src/mcp/tools/index.ts +214 -0
- package/src/mcp/tools/learning-optimization/optimize.ts +772 -0
- package/src/mcp/tools/quality-assessment/evaluate.ts +385 -0
- package/src/mcp/tools/registry.ts +248 -0
- package/src/mcp/tools/requirements-validation/validate.ts +394 -0
- package/src/mcp/tools/security-compliance/scan.ts +365 -0
- package/src/mcp/tools/test-execution/execute.ts +291 -0
- package/src/mcp/tools/test-generation/generate.ts +544 -0
- package/src/mcp/tools/visual-accessibility/index.ts +791 -0
- package/src/mcp/transport/index.ts +31 -0
- package/src/mcp/transport/stdio.ts +318 -0
- package/src/mcp/types.ts +543 -0
- package/src/neural-optimizer/index.ts +111 -0
- package/src/neural-optimizer/replay-buffer.ts +455 -0
- package/src/neural-optimizer/swarm-topology.ts +508 -0
- package/src/neural-optimizer/topology-optimizer.ts +828 -0
- package/src/neural-optimizer/types.ts +481 -0
- package/src/neural-optimizer/value-network.ts +351 -0
- package/src/optimization/auto-tuner.ts +817 -0
- package/src/optimization/index.ts +77 -0
- package/src/optimization/metric-collectors.ts +474 -0
- package/src/optimization/qe-workers.ts +704 -0
- package/src/optimization/tuning-algorithm.ts +401 -0
- package/src/optimization/types.ts +314 -0
- package/src/routing/index.ts +51 -0
- package/src/routing/qe-agent-registry.ts +963 -0
- package/src/routing/qe-task-router.ts +564 -0
- package/src/routing/routing-feedback.ts +365 -0
- package/src/routing/types.ts +406 -0
- package/src/shared/embeddings/embedding-cache.ts +157 -0
- package/src/shared/embeddings/index.ts +50 -0
- package/src/shared/embeddings/nomic-embedder.ts +404 -0
- package/src/shared/embeddings/ollama-client.ts +195 -0
- package/src/shared/embeddings/types.ts +147 -0
- package/src/shared/entities/agent.ts +141 -0
- package/src/shared/entities/base-entity.ts +79 -0
- package/src/shared/entities/index.ts +6 -0
- package/src/shared/events/domain-events.ts +259 -0
- package/src/shared/events/index.ts +5 -0
- package/src/shared/git/git-analyzer.ts +656 -0
- package/src/shared/git/index.ts +11 -0
- package/src/shared/http/http-client.ts +420 -0
- package/src/shared/http/index.ts +13 -0
- package/src/shared/index.ts +41 -0
- package/src/shared/io/file-reader.ts +525 -0
- package/src/shared/io/index.ts +25 -0
- package/src/shared/llm/cache.ts +473 -0
- package/src/shared/llm/circuit-breaker.ts +369 -0
- package/src/shared/llm/cost-tracker.ts +460 -0
- package/src/shared/llm/index.ts +140 -0
- package/src/shared/llm/interfaces.ts +629 -0
- package/src/shared/llm/provider-manager.ts +685 -0
- package/src/shared/llm/providers/claude.ts +524 -0
- package/src/shared/llm/providers/index.ts +8 -0
- package/src/shared/llm/providers/ollama.ts +575 -0
- package/src/shared/llm/providers/openai.ts +609 -0
- package/src/shared/metrics/code-metrics.ts +520 -0
- package/src/shared/metrics/index.ts +23 -0
- package/src/shared/metrics/system-metrics.ts +353 -0
- package/src/shared/parsers/index.ts +6 -0
- package/src/shared/parsers/typescript-parser.ts +841 -0
- package/src/shared/security/compliance-patterns.ts +666 -0
- package/src/shared/security/index.ts +30 -0
- package/src/shared/security/osv-client.ts +468 -0
- package/src/shared/types/index.ts +150 -0
- package/src/shared/value-objects/index.ts +273 -0
- package/src/strange-loop/healing-controller.ts +833 -0
- package/src/strange-loop/index.ts +104 -0
- package/src/strange-loop/self-model.ts +494 -0
- package/src/strange-loop/strange-loop.ts +446 -0
- package/src/strange-loop/swarm-observer.ts +448 -0
- package/src/strange-loop/topology-analyzer.ts +565 -0
- package/src/strange-loop/types.ts +640 -0
- package/src/time-crystal/default-phases.ts +520 -0
- package/src/time-crystal/index.ts +164 -0
- package/src/time-crystal/oscillator.ts +425 -0
- package/src/time-crystal/phase-executor.ts +521 -0
- package/src/time-crystal/scheduler.ts +1025 -0
- package/src/time-crystal/test-runner.ts +787 -0
- package/src/time-crystal/types.ts +421 -0
- package/src/workers/base-worker.ts +304 -0
- package/src/workers/daemon.ts +264 -0
- package/src/workers/index.ts +119 -0
- package/src/workers/interfaces.ts +393 -0
- package/src/workers/worker-manager.ts +424 -0
- package/src/workers/workers/compliance-checker.ts +445 -0
- package/src/workers/workers/coverage-tracker.ts +344 -0
- package/src/workers/workers/defect-predictor.ts +375 -0
- package/src/workers/workers/flaky-detector.ts +390 -0
- package/src/workers/workers/index.ts +17 -0
- package/src/workers/workers/learning-consolidation.ts +442 -0
- package/src/workers/workers/performance-baseline.ts +434 -0
- package/src/workers/workers/quality-gate.ts +419 -0
- package/src/workers/workers/regression-monitor.ts +357 -0
- package/src/workers/workers/security-scan.ts +349 -0
- package/src/workers/workers/test-health.ts +359 -0
- package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +540 -0
- package/tests/integration/coordination/cross-domain-router.test.ts +403 -0
- package/tests/integration/coordination/protocol-executor.test.ts +454 -0
- package/tests/integration/coordination/workflow-orchestrator.test.ts +418 -0
- package/tests/integration/feedback/feedback-loop-integration.test.ts +560 -0
- package/tests/integration/migration/v2-to-v3-migration.test.ts +471 -0
- package/tests/integration/parsers/typescript-parser.test.ts +463 -0
- package/tests/integration/security/vulnerability-detection.test.ts +628 -0
- package/tests/integration/test-execution/coordinator.test.ts +410 -0
- package/tests/integration/test-generation/coordinator.test.ts +361 -0
- package/tests/mocks/index.ts +228 -0
- package/tests/time-crystal/default-phases.test.ts +476 -0
- package/tests/time-crystal/oscillator.test.ts +541 -0
- package/tests/time-crystal/phase-executor.test.ts +653 -0
- package/tests/time-crystal/scheduler.test.ts +626 -0
- package/tests/time-crystal/test-runner.test.ts +594 -0
- package/tests/unit/causal-discovery/causal-graph.test.ts +504 -0
- package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +347 -0
- package/tests/unit/causal-discovery/discovery-engine.test.ts +435 -0
- package/tests/unit/causal-discovery/weight-matrix.test.ts +328 -0
- package/tests/unit/cli/cli.test.ts +341 -0
- package/tests/unit/cli/commands.test.ts +414 -0
- package/tests/unit/cli/init-command.test.ts +274 -0
- package/tests/unit/cli/migrate-command.test.ts +396 -0
- package/tests/unit/coordination/claims/claim-service.test.ts +949 -0
- package/tests/unit/coordination/claims/handoff-manager.test.ts +773 -0
- package/tests/unit/coordination/claims/work-stealing.test.ts +492 -0
- package/tests/unit/coordination/queen-coordinator.test.ts +966 -0
- package/tests/unit/coordination/result-saver.test.ts +653 -0
- package/tests/unit/coordination/task-executor.test.ts +810 -0
- package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +484 -0
- package/tests/unit/domains/chaos-resilience/load-tester.test.ts +559 -0
- package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +490 -0
- package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +560 -0
- package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +460 -0
- package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +584 -0
- package/tests/unit/domains/contract-testing/api-compatibility.test.ts +483 -0
- package/tests/unit/domains/contract-testing/contract-validator.test.ts +370 -0
- package/tests/unit/domains/contract-testing/schema-validator.test.ts +610 -0
- package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +298 -0
- package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +292 -0
- package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +506 -0
- package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +370 -0
- package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +546 -0
- package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +534 -0
- package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +541 -0
- package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +552 -0
- package/tests/unit/domains/learning-optimization/production-intel.test.ts +589 -0
- package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +453 -0
- package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +1006 -0
- package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +515 -0
- package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +401 -0
- package/tests/unit/domains/quality-assessment/quality-gate.test.ts +324 -0
- package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +479 -0
- package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +452 -0
- package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +505 -0
- package/tests/unit/domains/security-compliance/compliance-validator.test.ts +500 -0
- package/tests/unit/domains/security-compliance/security-auditor.test.ts +498 -0
- package/tests/unit/domains/security-compliance/security-scanner.test.ts +412 -0
- package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +432 -0
- package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +506 -0
- package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +412 -0
- package/tests/unit/early-exit/early-exit-controller.test.ts +548 -0
- package/tests/unit/early-exit/early-exit-decision.test.ts +617 -0
- package/tests/unit/early-exit/index.test.ts +254 -0
- package/tests/unit/early-exit/quality-signal.test.ts +589 -0
- package/tests/unit/early-exit/speculative-executor.test.ts +453 -0
- package/tests/unit/feedback/coverage-learner.test.ts +288 -0
- package/tests/unit/feedback/feedback-loop.test.ts +458 -0
- package/tests/unit/feedback/pattern-promotion.test.ts +390 -0
- package/tests/unit/feedback/quality-score-calculator.test.ts +364 -0
- package/tests/unit/feedback/test-outcome-tracker.test.ts +243 -0
- package/tests/unit/init/init-wizard.test.ts +881 -0
- package/tests/unit/init/project-analyzer.test.ts +807 -0
- package/tests/unit/init/self-configurator.test.ts +493 -0
- package/tests/unit/integrations/ruvector/ast-complexity.test.ts +240 -0
- package/tests/unit/integrations/ruvector/coverage-router.test.ts +366 -0
- package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +340 -0
- package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +355 -0
- package/tests/unit/integrations/ruvector/q-learning-router.test.ts +314 -0
- package/tests/unit/kernel/agent-coordinator.test.ts +220 -0
- package/tests/unit/kernel/event-bus.test.ts +197 -0
- package/tests/unit/learning/qe-reasoning-bank.test.ts +666 -0
- package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +415 -0
- package/tests/unit/mcp/mcp-server.test.ts +544 -0
- package/tests/unit/mcp/metrics/metrics-collector.test.ts +340 -0
- package/tests/unit/mcp/security/cve-prevention.test.ts +512 -0
- package/tests/unit/mcp/security/oauth21-provider.test.ts +624 -0
- package/tests/unit/mcp/security/rate-limiter.test.ts +410 -0
- package/tests/unit/mcp/security/sampling-server.test.ts +420 -0
- package/tests/unit/mcp/security/schema-validator.test.ts +494 -0
- package/tests/unit/mcp/tools/base.test.ts +336 -0
- package/tests/unit/mcp/tools/domain-tools.test.ts +759 -0
- package/tests/unit/mcp/tools/registry.test.ts +240 -0
- package/tests/unit/neural-optimizer/replay-buffer.test.ts +403 -0
- package/tests/unit/neural-optimizer/swarm-topology.test.ts +473 -0
- package/tests/unit/neural-optimizer/topology-optimizer.test.ts +595 -0
- package/tests/unit/neural-optimizer/value-network.test.ts +343 -0
- package/tests/unit/optimization/auto-tuner.test.ts +506 -0
- package/tests/unit/optimization/metric-collectors.test.ts +352 -0
- package/tests/unit/optimization/qe-workers.test.ts +407 -0
- package/tests/unit/optimization/tuning-algorithm.test.ts +467 -0
- package/tests/unit/routing/qe-agent-registry.test.ts +229 -0
- package/tests/unit/routing/qe-task-router.test.ts +390 -0
- package/tests/unit/routing/routing-feedback.test.ts +339 -0
- package/tests/unit/shared/embeddings/nomic-embedder.test.ts +419 -0
- package/tests/unit/shared/http/http-client.test.ts +719 -0
- package/tests/unit/shared/io/file-reader.test.ts +511 -0
- package/tests/unit/shared/llm/cache.test.ts +391 -0
- package/tests/unit/shared/llm/circuit-breaker.test.ts +293 -0
- package/tests/unit/shared/llm/cost-tracker.test.ts +431 -0
- package/tests/unit/shared/llm/provider-manager.test.ts +550 -0
- package/tests/unit/shared/llm/providers.test.ts +532 -0
- package/tests/unit/shared/parsers/typescript-parser.test.ts +693 -0
- package/tests/unit/shared/value-objects.test.ts +184 -0
- package/tests/unit/strange-loop/strange-loop.test.ts +1170 -0
- package/tests/unit/workers/base-worker.test.ts +341 -0
- package/tests/unit/workers/daemon.test.ts +291 -0
- package/tests/unit/workers/worker-manager.test.ts +284 -0
- package/tsconfig.json +32 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,2354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Security Scanner Service
|
|
3
|
+
* Implements SAST and DAST security scanning capabilities
|
|
4
|
+
* Includes OSV API integration for dependency vulnerability scanning
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
8
|
+
import { Result, ok, err } from '../../../shared/types/index.js';
|
|
9
|
+
import type { MemoryBackend } from '../../../kernel/interfaces.js';
|
|
10
|
+
import type { FilePath } from '../../../shared/value-objects/index.js';
|
|
11
|
+
import type {
|
|
12
|
+
SASTResult,
|
|
13
|
+
DASTResult,
|
|
14
|
+
DASTOptions,
|
|
15
|
+
AuthCredentials,
|
|
16
|
+
RuleSet,
|
|
17
|
+
FalsePositiveCheck,
|
|
18
|
+
Vulnerability,
|
|
19
|
+
VulnerabilitySeverity,
|
|
20
|
+
VulnerabilityCategory,
|
|
21
|
+
VulnerabilityLocation,
|
|
22
|
+
RemediationAdvice,
|
|
23
|
+
ScanSummary,
|
|
24
|
+
SecurityCoverage,
|
|
25
|
+
ScanStatus,
|
|
26
|
+
} from '../interfaces.js';
|
|
27
|
+
import { OSVClient, ParsedVulnerability } from '../../../shared/security/index.js';
|
|
28
|
+
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Service Interfaces
|
|
31
|
+
// ============================================================================
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Dependency scan result
|
|
35
|
+
*/
|
|
36
|
+
export interface DependencyScanResult {
|
|
37
|
+
readonly scanId: string;
|
|
38
|
+
readonly vulnerabilities: Vulnerability[];
|
|
39
|
+
readonly packagesScanned: number;
|
|
40
|
+
readonly vulnerablePackages: number;
|
|
41
|
+
readonly summary: ScanSummary;
|
|
42
|
+
readonly scanDurationMs: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Combined security scanner service interface
|
|
47
|
+
* Note: We define separate methods for SAST and DAST to avoid interface conflicts
|
|
48
|
+
*/
|
|
49
|
+
export interface ISecurityScannerService {
|
|
50
|
+
// SAST Methods
|
|
51
|
+
scanFiles(files: FilePath[]): Promise<Result<SASTResult>>;
|
|
52
|
+
scanWithRules(files: FilePath[], ruleSetIds: string[]): Promise<Result<SASTResult>>;
|
|
53
|
+
getAvailableRuleSets(): Promise<RuleSet[]>;
|
|
54
|
+
checkFalsePositive(vulnerability: Vulnerability): Promise<Result<FalsePositiveCheck>>;
|
|
55
|
+
|
|
56
|
+
// DAST Methods
|
|
57
|
+
scanUrl(targetUrl: string, options?: DASTOptions): Promise<Result<DASTResult>>;
|
|
58
|
+
scanAuthenticated(
|
|
59
|
+
targetUrl: string,
|
|
60
|
+
credentials: AuthCredentials,
|
|
61
|
+
options?: DASTOptions
|
|
62
|
+
): Promise<Result<DASTResult>>;
|
|
63
|
+
getScanStatus(scanId: string): Promise<ScanStatus>;
|
|
64
|
+
|
|
65
|
+
// Dependency Scanning (OSV)
|
|
66
|
+
scanDependencies(dependencies: Record<string, string>): Promise<Result<DependencyScanResult>>;
|
|
67
|
+
scanPackageJson(packageJsonPath: string): Promise<Result<DependencyScanResult>>;
|
|
68
|
+
|
|
69
|
+
// Combined
|
|
70
|
+
runFullScan(
|
|
71
|
+
files: FilePath[],
|
|
72
|
+
targetUrl?: string,
|
|
73
|
+
options?: DASTOptions
|
|
74
|
+
): Promise<Result<FullScanResult>>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface FullScanResult {
|
|
78
|
+
readonly sastResult: SASTResult;
|
|
79
|
+
readonly dastResult?: DASTResult;
|
|
80
|
+
readonly combinedSummary: ScanSummary;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// Configuration
|
|
85
|
+
// ============================================================================
|
|
86
|
+
|
|
87
|
+
export interface SecurityScannerConfig {
|
|
88
|
+
defaultRuleSets: string[];
|
|
89
|
+
maxConcurrentScans: number;
|
|
90
|
+
timeout: number;
|
|
91
|
+
enableFalsePositiveDetection: boolean;
|
|
92
|
+
dastMaxDepth: number;
|
|
93
|
+
dastActiveScanning: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const DEFAULT_CONFIG: SecurityScannerConfig = {
|
|
97
|
+
defaultRuleSets: ['owasp-top-10', 'cwe-sans-25'],
|
|
98
|
+
maxConcurrentScans: 4,
|
|
99
|
+
timeout: 300000, // 5 minutes
|
|
100
|
+
enableFalsePositiveDetection: true,
|
|
101
|
+
dastMaxDepth: 5,
|
|
102
|
+
dastActiveScanning: false,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// Security Pattern Definitions
|
|
107
|
+
// ============================================================================
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Pattern definition for vulnerability detection
|
|
111
|
+
*/
|
|
112
|
+
interface SecurityPattern {
|
|
113
|
+
readonly id: string;
|
|
114
|
+
readonly pattern: RegExp;
|
|
115
|
+
readonly category: VulnerabilityCategory;
|
|
116
|
+
readonly severity: VulnerabilitySeverity;
|
|
117
|
+
readonly title: string;
|
|
118
|
+
readonly description: string;
|
|
119
|
+
readonly owaspId: string;
|
|
120
|
+
readonly cweId: string;
|
|
121
|
+
readonly remediation: string;
|
|
122
|
+
readonly fixExample?: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* SQL Injection Detection Patterns
|
|
127
|
+
* OWASP A03:2021 - Injection
|
|
128
|
+
*/
|
|
129
|
+
const SQL_INJECTION_PATTERNS: SecurityPattern[] = [
|
|
130
|
+
{
|
|
131
|
+
id: 'sqli-string-concat',
|
|
132
|
+
pattern: /query\s*\(\s*['"`].*\+.*['"`]\s*\)/g,
|
|
133
|
+
category: 'injection',
|
|
134
|
+
severity: 'critical',
|
|
135
|
+
title: 'SQL Injection via String Concatenation',
|
|
136
|
+
description: 'SQL query constructed using string concatenation with potentially untrusted input',
|
|
137
|
+
owaspId: 'A03:2021',
|
|
138
|
+
cweId: 'CWE-89',
|
|
139
|
+
remediation: 'Use parameterized queries or prepared statements instead of string concatenation',
|
|
140
|
+
fixExample: 'db.query("SELECT * FROM users WHERE id = $1", [userId])',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'sqli-template-literal',
|
|
144
|
+
pattern: /execute\s*\(\s*`[^`]*\$\{[^}]+\}[^`]*`\s*\)/g,
|
|
145
|
+
category: 'injection',
|
|
146
|
+
severity: 'critical',
|
|
147
|
+
title: 'SQL Injection via Template Literal',
|
|
148
|
+
description: 'SQL query constructed using template literals with embedded expressions',
|
|
149
|
+
owaspId: 'A03:2021',
|
|
150
|
+
cweId: 'CWE-89',
|
|
151
|
+
remediation: 'Use parameterized queries instead of template literals for SQL',
|
|
152
|
+
fixExample: 'db.execute("DELETE FROM users WHERE id = ?", [userId])',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'sqli-raw-query',
|
|
156
|
+
pattern: /\.raw\s*\(\s*['"`].*\+|\.raw\s*\(\s*`[^`]*\$\{/g,
|
|
157
|
+
category: 'injection',
|
|
158
|
+
severity: 'high',
|
|
159
|
+
title: 'SQL Injection via Raw Query',
|
|
160
|
+
description: 'Raw SQL query with potential user input interpolation',
|
|
161
|
+
owaspId: 'A03:2021',
|
|
162
|
+
cweId: 'CWE-89',
|
|
163
|
+
remediation: 'Avoid raw queries with user input; use ORM methods or parameterized queries',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'sqli-exec',
|
|
167
|
+
pattern: /exec(?:ute)?(?:Sql|Query)?\s*\([^)]*\+[^)]*\)/gi,
|
|
168
|
+
category: 'injection',
|
|
169
|
+
severity: 'critical',
|
|
170
|
+
title: 'SQL Injection via Dynamic Execution',
|
|
171
|
+
description: 'Dynamic SQL execution with string concatenation detected',
|
|
172
|
+
owaspId: 'A03:2021',
|
|
173
|
+
cweId: 'CWE-89',
|
|
174
|
+
remediation: 'Never concatenate user input into SQL queries',
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* XSS (Cross-Site Scripting) Detection Patterns
|
|
180
|
+
* OWASP A03:2021 - Injection (includes XSS)
|
|
181
|
+
*/
|
|
182
|
+
const XSS_PATTERNS: SecurityPattern[] = [
|
|
183
|
+
{
|
|
184
|
+
id: 'xss-innerhtml',
|
|
185
|
+
pattern: /\.innerHTML\s*=\s*[^'"`;\n]+/g,
|
|
186
|
+
category: 'xss',
|
|
187
|
+
severity: 'high',
|
|
188
|
+
title: 'XSS via innerHTML Assignment',
|
|
189
|
+
description: 'Direct innerHTML assignment with potentially unsanitized content',
|
|
190
|
+
owaspId: 'A03:2021',
|
|
191
|
+
cweId: 'CWE-79',
|
|
192
|
+
remediation: 'Use textContent for text, or sanitize HTML with DOMPurify before innerHTML assignment',
|
|
193
|
+
fixExample: 'element.textContent = userInput; // or DOMPurify.sanitize(userInput)',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: 'xss-document-write',
|
|
197
|
+
pattern: /document\.write\s*\([^)]+\)/g,
|
|
198
|
+
category: 'xss',
|
|
199
|
+
severity: 'high',
|
|
200
|
+
title: 'XSS via document.write',
|
|
201
|
+
description: 'document.write() can execute scripts from untrusted data',
|
|
202
|
+
owaspId: 'A03:2021',
|
|
203
|
+
cweId: 'CWE-79',
|
|
204
|
+
remediation: 'Avoid document.write(); use DOM manipulation methods instead',
|
|
205
|
+
fixExample: 'document.body.appendChild(document.createTextNode(text))',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'xss-dangerously-set',
|
|
209
|
+
pattern: /dangerouslySetInnerHTML\s*=\s*\{/g,
|
|
210
|
+
category: 'xss',
|
|
211
|
+
severity: 'medium',
|
|
212
|
+
title: 'React dangerouslySetInnerHTML Usage',
|
|
213
|
+
description: 'dangerouslySetInnerHTML bypasses React XSS protections',
|
|
214
|
+
owaspId: 'A03:2021',
|
|
215
|
+
cweId: 'CWE-79',
|
|
216
|
+
remediation: 'Sanitize HTML content with DOMPurify before using dangerouslySetInnerHTML',
|
|
217
|
+
fixExample: 'dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }}',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: 'xss-eval',
|
|
221
|
+
pattern: /eval\s*\([^)]+\)/g,
|
|
222
|
+
category: 'xss',
|
|
223
|
+
severity: 'critical',
|
|
224
|
+
title: 'Code Injection via eval()',
|
|
225
|
+
description: 'eval() executes arbitrary code and is a major security risk',
|
|
226
|
+
owaspId: 'A03:2021',
|
|
227
|
+
cweId: 'CWE-95',
|
|
228
|
+
remediation: 'Never use eval(); use JSON.parse() for JSON data or safer alternatives',
|
|
229
|
+
fixExample: 'JSON.parse(jsonString) // instead of eval(jsonString)',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'xss-new-function',
|
|
233
|
+
pattern: /new\s+Function\s*\([^)]+\)/g,
|
|
234
|
+
category: 'xss',
|
|
235
|
+
severity: 'critical',
|
|
236
|
+
title: 'Code Injection via Function Constructor',
|
|
237
|
+
description: 'Function constructor can execute arbitrary code like eval()',
|
|
238
|
+
owaspId: 'A03:2021',
|
|
239
|
+
cweId: 'CWE-95',
|
|
240
|
+
remediation: 'Avoid the Function constructor; use predefined functions instead',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
id: 'xss-outerhtml',
|
|
244
|
+
pattern: /\.outerHTML\s*=\s*[^'"`;\n]+/g,
|
|
245
|
+
category: 'xss',
|
|
246
|
+
severity: 'high',
|
|
247
|
+
title: 'XSS via outerHTML Assignment',
|
|
248
|
+
description: 'Direct outerHTML assignment with potentially unsanitized content',
|
|
249
|
+
owaspId: 'A03:2021',
|
|
250
|
+
cweId: 'CWE-79',
|
|
251
|
+
remediation: 'Sanitize content before outerHTML assignment',
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Hardcoded Secrets Detection Patterns
|
|
257
|
+
* OWASP A02:2021 - Cryptographic Failures
|
|
258
|
+
*/
|
|
259
|
+
const SECRET_PATTERNS: SecurityPattern[] = [
|
|
260
|
+
{
|
|
261
|
+
id: 'secret-aws-access-key',
|
|
262
|
+
pattern: /['"`]AKIA[0-9A-Z]{16}['"`]/g,
|
|
263
|
+
category: 'sensitive-data',
|
|
264
|
+
severity: 'critical',
|
|
265
|
+
title: 'AWS Access Key Detected',
|
|
266
|
+
description: 'Hardcoded AWS Access Key ID found in source code',
|
|
267
|
+
owaspId: 'A02:2021',
|
|
268
|
+
cweId: 'CWE-798',
|
|
269
|
+
remediation: 'Use environment variables or AWS Secrets Manager for credentials',
|
|
270
|
+
fixExample: 'const accessKey = process.env.AWS_ACCESS_KEY_ID',
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
id: 'secret-aws-secret-key',
|
|
274
|
+
pattern: /['"`][A-Za-z0-9/+=]{40}['"`]/g,
|
|
275
|
+
category: 'sensitive-data',
|
|
276
|
+
severity: 'critical',
|
|
277
|
+
title: 'Potential AWS Secret Key Detected',
|
|
278
|
+
description: 'Potential hardcoded AWS Secret Access Key found',
|
|
279
|
+
owaspId: 'A02:2021',
|
|
280
|
+
cweId: 'CWE-798',
|
|
281
|
+
remediation: 'Store secrets in environment variables or secrets manager',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: 'secret-openai-key',
|
|
285
|
+
pattern: /['"`]sk-[a-zA-Z0-9]{48,}['"`]/g,
|
|
286
|
+
category: 'sensitive-data',
|
|
287
|
+
severity: 'critical',
|
|
288
|
+
title: 'OpenAI API Key Detected',
|
|
289
|
+
description: 'Hardcoded OpenAI API key found in source code',
|
|
290
|
+
owaspId: 'A02:2021',
|
|
291
|
+
cweId: 'CWE-798',
|
|
292
|
+
remediation: 'Use environment variables for API keys',
|
|
293
|
+
fixExample: 'const apiKey = process.env.OPENAI_API_KEY',
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: 'secret-generic-password',
|
|
297
|
+
pattern: /password\s*[:=]\s*['"`][^'"`]{4,}['"`]/gi,
|
|
298
|
+
category: 'sensitive-data',
|
|
299
|
+
severity: 'high',
|
|
300
|
+
title: 'Hardcoded Password Detected',
|
|
301
|
+
description: 'Hardcoded password found in source code',
|
|
302
|
+
owaspId: 'A02:2021',
|
|
303
|
+
cweId: 'CWE-798',
|
|
304
|
+
remediation: 'Never hardcode passwords; use environment variables or secrets manager',
|
|
305
|
+
fixExample: 'const password = process.env.DB_PASSWORD',
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
id: 'secret-api-key',
|
|
309
|
+
pattern: /api[_-]?key\s*[:=]\s*['"`][a-zA-Z0-9_\-]{16,}['"`]/gi,
|
|
310
|
+
category: 'sensitive-data',
|
|
311
|
+
severity: 'high',
|
|
312
|
+
title: 'Hardcoded API Key Detected',
|
|
313
|
+
description: 'Hardcoded API key found in source code',
|
|
314
|
+
owaspId: 'A02:2021',
|
|
315
|
+
cweId: 'CWE-798',
|
|
316
|
+
remediation: 'Use environment variables for API keys',
|
|
317
|
+
fixExample: 'const apiKey = process.env.API_KEY',
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
id: 'secret-jwt',
|
|
321
|
+
pattern: /['"`]eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+['"`]/g,
|
|
322
|
+
category: 'sensitive-data',
|
|
323
|
+
severity: 'high',
|
|
324
|
+
title: 'Hardcoded JWT Token Detected',
|
|
325
|
+
description: 'Hardcoded JWT token found in source code',
|
|
326
|
+
owaspId: 'A02:2021',
|
|
327
|
+
cweId: 'CWE-798',
|
|
328
|
+
remediation: 'Generate JWT tokens dynamically; never hardcode them',
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: 'secret-private-key',
|
|
332
|
+
pattern: /-----BEGIN\s+(RSA|EC|OPENSSH|DSA)?\s*PRIVATE\s+KEY-----/g,
|
|
333
|
+
category: 'sensitive-data',
|
|
334
|
+
severity: 'critical',
|
|
335
|
+
title: 'Private Key Detected',
|
|
336
|
+
description: 'Private key found in source code',
|
|
337
|
+
owaspId: 'A02:2021',
|
|
338
|
+
cweId: 'CWE-798',
|
|
339
|
+
remediation: 'Store private keys in secure key management systems, not in code',
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: 'secret-github-token',
|
|
343
|
+
pattern: /['"`]ghp_[a-zA-Z0-9]{36}['"`]|['"`]github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}['"`]/g,
|
|
344
|
+
category: 'sensitive-data',
|
|
345
|
+
severity: 'critical',
|
|
346
|
+
title: 'GitHub Token Detected',
|
|
347
|
+
description: 'Hardcoded GitHub personal access token found',
|
|
348
|
+
owaspId: 'A02:2021',
|
|
349
|
+
cweId: 'CWE-798',
|
|
350
|
+
remediation: 'Use environment variables or GitHub Actions secrets',
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
id: 'secret-slack-token',
|
|
354
|
+
pattern: /['"`]xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*['"`]/g,
|
|
355
|
+
category: 'sensitive-data',
|
|
356
|
+
severity: 'high',
|
|
357
|
+
title: 'Slack Token Detected',
|
|
358
|
+
description: 'Hardcoded Slack token found in source code',
|
|
359
|
+
owaspId: 'A02:2021',
|
|
360
|
+
cweId: 'CWE-798',
|
|
361
|
+
remediation: 'Use environment variables for Slack tokens',
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Path Traversal Detection Patterns
|
|
367
|
+
* OWASP A01:2021 - Broken Access Control
|
|
368
|
+
*/
|
|
369
|
+
const PATH_TRAVERSAL_PATTERNS: SecurityPattern[] = [
|
|
370
|
+
{
|
|
371
|
+
id: 'path-traversal-readfile',
|
|
372
|
+
pattern: /(?:readFile|readFileSync)\s*\([^)]*\+/g,
|
|
373
|
+
category: 'access-control',
|
|
374
|
+
severity: 'high',
|
|
375
|
+
title: 'Path Traversal via File Read',
|
|
376
|
+
description: 'File read operation with concatenated path may allow directory traversal',
|
|
377
|
+
owaspId: 'A01:2021',
|
|
378
|
+
cweId: 'CWE-22',
|
|
379
|
+
remediation: 'Validate and sanitize file paths; use path.resolve() and check against base directory',
|
|
380
|
+
fixExample: 'const safePath = path.resolve(baseDir, path.basename(userInput))',
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: 'path-traversal-pattern',
|
|
384
|
+
pattern: /\.\.\/.*\.\.\//g,
|
|
385
|
+
category: 'access-control',
|
|
386
|
+
severity: 'medium',
|
|
387
|
+
title: 'Path Traversal Pattern Detected',
|
|
388
|
+
description: 'Suspicious path traversal pattern (../) found in code',
|
|
389
|
+
owaspId: 'A01:2021',
|
|
390
|
+
cweId: 'CWE-22',
|
|
391
|
+
remediation: 'Validate paths and ensure they resolve within expected directories',
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
id: 'path-traversal-writefile',
|
|
395
|
+
pattern: /(?:writeFile|writeFileSync)\s*\([^)]*\+/g,
|
|
396
|
+
category: 'access-control',
|
|
397
|
+
severity: 'high',
|
|
398
|
+
title: 'Path Traversal via File Write',
|
|
399
|
+
description: 'File write operation with concatenated path may allow directory traversal',
|
|
400
|
+
owaspId: 'A01:2021',
|
|
401
|
+
cweId: 'CWE-22',
|
|
402
|
+
remediation: 'Validate file paths before writing; ensure path is within allowed directory',
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
id: 'path-traversal-createstream',
|
|
406
|
+
pattern: /createReadStream\s*\([^)]*\+/g,
|
|
407
|
+
category: 'access-control',
|
|
408
|
+
severity: 'high',
|
|
409
|
+
title: 'Path Traversal via Stream',
|
|
410
|
+
description: 'Stream creation with concatenated path may allow directory traversal',
|
|
411
|
+
owaspId: 'A01:2021',
|
|
412
|
+
cweId: 'CWE-22',
|
|
413
|
+
remediation: 'Validate and sanitize file paths before creating streams',
|
|
414
|
+
},
|
|
415
|
+
];
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Command Injection Detection Patterns
|
|
419
|
+
* OWASP A03:2021 - Injection
|
|
420
|
+
*/
|
|
421
|
+
const COMMAND_INJECTION_PATTERNS: SecurityPattern[] = [
|
|
422
|
+
{
|
|
423
|
+
id: 'cmd-injection-exec',
|
|
424
|
+
pattern: /exec\s*\([^)]*\+[^)]*\)|exec\s*\(\s*`[^`]*\$\{/g,
|
|
425
|
+
category: 'injection',
|
|
426
|
+
severity: 'critical',
|
|
427
|
+
title: 'Command Injection via exec()',
|
|
428
|
+
description: 'Shell command execution with unsanitized input',
|
|
429
|
+
owaspId: 'A03:2021',
|
|
430
|
+
cweId: 'CWE-78',
|
|
431
|
+
remediation: 'Use execFile() with argument array instead of exec() with string concatenation',
|
|
432
|
+
fixExample: 'execFile("command", [arg1, arg2], callback)',
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
id: 'cmd-injection-spawn',
|
|
436
|
+
pattern: /spawn\s*\(\s*[^,]+\+|spawn\s*\(\s*`[^`]*\$\{/g,
|
|
437
|
+
category: 'injection',
|
|
438
|
+
severity: 'critical',
|
|
439
|
+
title: 'Command Injection via spawn()',
|
|
440
|
+
description: 'Process spawn with potentially unsanitized command',
|
|
441
|
+
owaspId: 'A03:2021',
|
|
442
|
+
cweId: 'CWE-78',
|
|
443
|
+
remediation: 'Use spawn with command and args array; validate inputs',
|
|
444
|
+
fixExample: 'spawn("command", [sanitizedArg1, sanitizedArg2])',
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
id: 'cmd-injection-shell-true',
|
|
448
|
+
pattern: /spawn\s*\([^)]+,\s*\{[^}]*shell\s*:\s*true/g,
|
|
449
|
+
category: 'injection',
|
|
450
|
+
severity: 'high',
|
|
451
|
+
title: 'Dangerous Shell Option in spawn()',
|
|
452
|
+
description: 'spawn() with shell: true can enable command injection',
|
|
453
|
+
owaspId: 'A03:2021',
|
|
454
|
+
cweId: 'CWE-78',
|
|
455
|
+
remediation: 'Avoid shell: true option; use direct command execution',
|
|
456
|
+
},
|
|
457
|
+
];
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Insecure Configuration Detection Patterns
|
|
461
|
+
* OWASP A05:2021 - Security Misconfiguration
|
|
462
|
+
*/
|
|
463
|
+
const MISCONFIGURATION_PATTERNS: SecurityPattern[] = [
|
|
464
|
+
{
|
|
465
|
+
id: 'misc-cors-wildcard',
|
|
466
|
+
pattern: /cors\s*\(\s*\{[^}]*origin\s*:\s*['"]\*['"]/gi,
|
|
467
|
+
category: 'security-misconfiguration',
|
|
468
|
+
severity: 'medium',
|
|
469
|
+
title: 'Permissive CORS Configuration',
|
|
470
|
+
description: 'CORS allows all origins (*) which may expose sensitive data',
|
|
471
|
+
owaspId: 'A05:2021',
|
|
472
|
+
cweId: 'CWE-942',
|
|
473
|
+
remediation: 'Restrict CORS to specific trusted origins',
|
|
474
|
+
fixExample: 'cors({ origin: ["https://trusted-domain.com"] })',
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
id: 'misc-debug-enabled',
|
|
478
|
+
pattern: /debug\s*[:=]\s*true|DEBUG\s*[:=]\s*['"]?true['"]?/gi,
|
|
479
|
+
category: 'security-misconfiguration',
|
|
480
|
+
severity: 'low',
|
|
481
|
+
title: 'Debug Mode Enabled',
|
|
482
|
+
description: 'Debug mode may expose sensitive information in production',
|
|
483
|
+
owaspId: 'A05:2021',
|
|
484
|
+
cweId: 'CWE-489',
|
|
485
|
+
remediation: 'Disable debug mode in production environments',
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
id: 'misc-ssl-disabled',
|
|
489
|
+
pattern: /rejectUnauthorized\s*:\s*false|NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*['"]?0['"]?/g,
|
|
490
|
+
category: 'security-misconfiguration',
|
|
491
|
+
severity: 'high',
|
|
492
|
+
title: 'TLS Certificate Validation Disabled',
|
|
493
|
+
description: 'Disabling TLS certificate validation exposes to MITM attacks',
|
|
494
|
+
owaspId: 'A05:2021',
|
|
495
|
+
cweId: 'CWE-295',
|
|
496
|
+
remediation: 'Always enable TLS certificate validation in production',
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
id: 'misc-helmet-missing',
|
|
500
|
+
pattern: /app\.use\s*\(\s*express\s*\(\s*\)\s*\)/g,
|
|
501
|
+
category: 'security-misconfiguration',
|
|
502
|
+
severity: 'low',
|
|
503
|
+
title: 'Express App Without Security Headers',
|
|
504
|
+
description: 'Express app initialized without helmet or security headers',
|
|
505
|
+
owaspId: 'A05:2021',
|
|
506
|
+
cweId: 'CWE-693',
|
|
507
|
+
remediation: 'Use helmet middleware for security headers',
|
|
508
|
+
fixExample: 'app.use(helmet())',
|
|
509
|
+
},
|
|
510
|
+
];
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Insecure Deserialization Patterns
|
|
514
|
+
* OWASP A08:2021 - Software and Data Integrity Failures
|
|
515
|
+
*/
|
|
516
|
+
const DESERIALIZATION_PATTERNS: SecurityPattern[] = [
|
|
517
|
+
{
|
|
518
|
+
id: 'deser-yaml-load',
|
|
519
|
+
pattern: /yaml\.load\s*\([^)]+\)/g,
|
|
520
|
+
category: 'insecure-deserialization',
|
|
521
|
+
severity: 'high',
|
|
522
|
+
title: 'Unsafe YAML Deserialization',
|
|
523
|
+
description: 'yaml.load() can execute arbitrary code from untrusted YAML',
|
|
524
|
+
owaspId: 'A08:2021',
|
|
525
|
+
cweId: 'CWE-502',
|
|
526
|
+
remediation: 'Use yaml.safeLoad() or schema-constrained loading',
|
|
527
|
+
fixExample: 'yaml.load(content, { schema: yaml.SAFE_SCHEMA })',
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
id: 'deser-serialize-js',
|
|
531
|
+
pattern: /serialize\s*\([^)]+\)|unserialize\s*\([^)]+\)/g,
|
|
532
|
+
category: 'insecure-deserialization',
|
|
533
|
+
severity: 'high',
|
|
534
|
+
title: 'Unsafe Serialization Function',
|
|
535
|
+
description: 'Node serialize/unserialize functions can execute arbitrary code',
|
|
536
|
+
owaspId: 'A08:2021',
|
|
537
|
+
cweId: 'CWE-502',
|
|
538
|
+
remediation: 'Use JSON.parse/stringify for serialization',
|
|
539
|
+
},
|
|
540
|
+
];
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Authentication Weakness Patterns
|
|
544
|
+
* OWASP A07:2021 - Identification and Authentication Failures
|
|
545
|
+
*/
|
|
546
|
+
const AUTH_PATTERNS: SecurityPattern[] = [
|
|
547
|
+
{
|
|
548
|
+
id: 'auth-weak-jwt-secret',
|
|
549
|
+
pattern: /jwt\.sign\s*\([^)]+,\s*['"][a-zA-Z0-9]{1,16}['"]/g,
|
|
550
|
+
category: 'broken-auth',
|
|
551
|
+
severity: 'high',
|
|
552
|
+
title: 'Weak JWT Secret',
|
|
553
|
+
description: 'JWT signed with a weak or short secret key',
|
|
554
|
+
owaspId: 'A07:2021',
|
|
555
|
+
cweId: 'CWE-327',
|
|
556
|
+
remediation: 'Use a strong, randomly generated secret of at least 256 bits',
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
id: 'auth-no-algorithm',
|
|
560
|
+
pattern: /jwt\.verify\s*\([^)]+\)\s*(?!.*algorithm)/g,
|
|
561
|
+
category: 'broken-auth',
|
|
562
|
+
severity: 'medium',
|
|
563
|
+
title: 'JWT Without Algorithm Specification',
|
|
564
|
+
description: 'JWT verification without explicit algorithm can be exploited',
|
|
565
|
+
owaspId: 'A07:2021',
|
|
566
|
+
cweId: 'CWE-347',
|
|
567
|
+
remediation: 'Always specify the expected algorithm in JWT verification',
|
|
568
|
+
fixExample: 'jwt.verify(token, secret, { algorithms: ["HS256"] })',
|
|
569
|
+
},
|
|
570
|
+
];
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* All security patterns combined by category for rule set application
|
|
574
|
+
*/
|
|
575
|
+
const ALL_SECURITY_PATTERNS: SecurityPattern[] = [
|
|
576
|
+
...SQL_INJECTION_PATTERNS,
|
|
577
|
+
...XSS_PATTERNS,
|
|
578
|
+
...SECRET_PATTERNS,
|
|
579
|
+
...PATH_TRAVERSAL_PATTERNS,
|
|
580
|
+
...COMMAND_INJECTION_PATTERNS,
|
|
581
|
+
...MISCONFIGURATION_PATTERNS,
|
|
582
|
+
...DESERIALIZATION_PATTERNS,
|
|
583
|
+
...AUTH_PATTERNS,
|
|
584
|
+
];
|
|
585
|
+
|
|
586
|
+
// ============================================================================
|
|
587
|
+
// Built-in Rule Sets
|
|
588
|
+
// ============================================================================
|
|
589
|
+
|
|
590
|
+
const BUILT_IN_RULE_SETS: RuleSet[] = [
|
|
591
|
+
{
|
|
592
|
+
id: 'owasp-top-10',
|
|
593
|
+
name: 'OWASP Top 10',
|
|
594
|
+
description: 'OWASP Top 10 most critical security risks',
|
|
595
|
+
ruleCount: 45,
|
|
596
|
+
categories: [
|
|
597
|
+
'injection',
|
|
598
|
+
'broken-auth',
|
|
599
|
+
'sensitive-data',
|
|
600
|
+
'xxe',
|
|
601
|
+
'access-control',
|
|
602
|
+
'security-misconfiguration',
|
|
603
|
+
'xss',
|
|
604
|
+
'insecure-deserialization',
|
|
605
|
+
'vulnerable-components',
|
|
606
|
+
'insufficient-logging',
|
|
607
|
+
],
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
id: 'cwe-sans-25',
|
|
611
|
+
name: 'CWE/SANS Top 25',
|
|
612
|
+
description: 'Most dangerous software errors',
|
|
613
|
+
ruleCount: 38,
|
|
614
|
+
categories: [
|
|
615
|
+
'injection',
|
|
616
|
+
'xss',
|
|
617
|
+
'access-control',
|
|
618
|
+
'sensitive-data',
|
|
619
|
+
'broken-auth',
|
|
620
|
+
],
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
id: 'nodejs-security',
|
|
624
|
+
name: 'Node.js Security',
|
|
625
|
+
description: 'Node.js specific security rules',
|
|
626
|
+
ruleCount: 25,
|
|
627
|
+
categories: ['injection', 'xss', 'sensitive-data', 'security-misconfiguration'],
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
id: 'typescript-security',
|
|
631
|
+
name: 'TypeScript Security',
|
|
632
|
+
description: 'TypeScript specific security rules',
|
|
633
|
+
ruleCount: 20,
|
|
634
|
+
categories: ['injection', 'xss', 'sensitive-data'],
|
|
635
|
+
},
|
|
636
|
+
];
|
|
637
|
+
|
|
638
|
+
// ============================================================================
|
|
639
|
+
// Mutable Summary Type for Internal Use
|
|
640
|
+
// ============================================================================
|
|
641
|
+
|
|
642
|
+
interface MutableScanSummary {
|
|
643
|
+
critical: number;
|
|
644
|
+
high: number;
|
|
645
|
+
medium: number;
|
|
646
|
+
low: number;
|
|
647
|
+
informational: number;
|
|
648
|
+
totalFiles: number;
|
|
649
|
+
scanDurationMs: number;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// ============================================================================
|
|
653
|
+
// Security Scanner Service Implementation
|
|
654
|
+
// ============================================================================
|
|
655
|
+
|
|
656
|
+
export class SecurityScannerService implements ISecurityScannerService {
|
|
657
|
+
private readonly config: SecurityScannerConfig;
|
|
658
|
+
private readonly activeScans: Map<string, ScanStatus> = new Map();
|
|
659
|
+
private readonly osvClient: OSVClient;
|
|
660
|
+
|
|
661
|
+
constructor(
|
|
662
|
+
private readonly memory: MemoryBackend,
|
|
663
|
+
config: Partial<SecurityScannerConfig> = {}
|
|
664
|
+
) {
|
|
665
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
666
|
+
this.osvClient = new OSVClient({ enableCache: true });
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// ==========================================================================
|
|
670
|
+
// SAST Methods
|
|
671
|
+
// ==========================================================================
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Scan files for security vulnerabilities using static analysis
|
|
675
|
+
*/
|
|
676
|
+
async scanFiles(files: FilePath[]): Promise<Result<SASTResult>> {
|
|
677
|
+
return this.scanWithRules(files, this.config.defaultRuleSets);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Scan with specific rule sets
|
|
682
|
+
*/
|
|
683
|
+
async scanWithRules(
|
|
684
|
+
files: FilePath[],
|
|
685
|
+
ruleSetIds: string[]
|
|
686
|
+
): Promise<Result<SASTResult>> {
|
|
687
|
+
const scanId = uuidv4();
|
|
688
|
+
|
|
689
|
+
try {
|
|
690
|
+
if (files.length === 0) {
|
|
691
|
+
return err(new Error('No files provided for scanning'));
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
this.activeScans.set(scanId, 'running');
|
|
695
|
+
const startTime = Date.now();
|
|
696
|
+
|
|
697
|
+
// Get applicable rule sets
|
|
698
|
+
const ruleSets = BUILT_IN_RULE_SETS.filter((rs) =>
|
|
699
|
+
ruleSetIds.includes(rs.id)
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
if (ruleSets.length === 0) {
|
|
703
|
+
return err(new Error(`No valid rule sets found: ${ruleSetIds.join(', ')}`));
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Perform static analysis on each file
|
|
707
|
+
const vulnerabilities: Vulnerability[] = [];
|
|
708
|
+
let linesScanned = 0;
|
|
709
|
+
|
|
710
|
+
for (const file of files) {
|
|
711
|
+
const fileVulns = await this.analyzeFile(file, ruleSets);
|
|
712
|
+
vulnerabilities.push(...fileVulns.vulnerabilities);
|
|
713
|
+
linesScanned += fileVulns.linesScanned;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const scanDurationMs = Date.now() - startTime;
|
|
717
|
+
|
|
718
|
+
// Calculate summary
|
|
719
|
+
const summary = this.calculateSummary(
|
|
720
|
+
vulnerabilities,
|
|
721
|
+
files.length,
|
|
722
|
+
scanDurationMs
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
// Calculate coverage
|
|
726
|
+
const coverage: SecurityCoverage = {
|
|
727
|
+
filesScanned: files.length,
|
|
728
|
+
linesScanned,
|
|
729
|
+
rulesApplied: ruleSets.reduce((acc, rs) => acc + rs.ruleCount, 0),
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
// Store scan results in memory
|
|
733
|
+
await this.storeScanResults(scanId, 'sast', vulnerabilities, summary);
|
|
734
|
+
|
|
735
|
+
this.activeScans.set(scanId, 'completed');
|
|
736
|
+
|
|
737
|
+
return ok({
|
|
738
|
+
scanId,
|
|
739
|
+
vulnerabilities,
|
|
740
|
+
summary,
|
|
741
|
+
coverage,
|
|
742
|
+
});
|
|
743
|
+
} catch (error) {
|
|
744
|
+
this.activeScans.set(scanId, 'failed');
|
|
745
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Get available rule sets
|
|
751
|
+
*/
|
|
752
|
+
async getAvailableRuleSets(): Promise<RuleSet[]> {
|
|
753
|
+
// Return built-in rule sets plus any custom ones from memory
|
|
754
|
+
const customRuleSets = await this.memory.get<RuleSet[]>(
|
|
755
|
+
'security:custom-rule-sets'
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
return [...BUILT_IN_RULE_SETS, ...(customRuleSets || [])];
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Check if vulnerability is a false positive
|
|
763
|
+
*/
|
|
764
|
+
async checkFalsePositive(
|
|
765
|
+
vulnerability: Vulnerability
|
|
766
|
+
): Promise<Result<FalsePositiveCheck>> {
|
|
767
|
+
try {
|
|
768
|
+
if (!this.config.enableFalsePositiveDetection) {
|
|
769
|
+
return ok({
|
|
770
|
+
isFalsePositive: false,
|
|
771
|
+
confidence: 0,
|
|
772
|
+
reason: 'False positive detection is disabled',
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// Analyze vulnerability using heuristics-based false positive detection
|
|
777
|
+
const analysis = await this.analyzeFalsePositive(vulnerability);
|
|
778
|
+
|
|
779
|
+
// Store the check result for learning
|
|
780
|
+
await this.memory.set(
|
|
781
|
+
`security:fp-check:${vulnerability.id}`,
|
|
782
|
+
{ vulnerability, analysis },
|
|
783
|
+
{ namespace: 'security-compliance', ttl: 86400 * 30 } // 30 days
|
|
784
|
+
);
|
|
785
|
+
|
|
786
|
+
return ok(analysis);
|
|
787
|
+
} catch (error) {
|
|
788
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// ==========================================================================
|
|
793
|
+
// DAST Methods
|
|
794
|
+
// ==========================================================================
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Scan running application using dynamic analysis
|
|
798
|
+
*/
|
|
799
|
+
async scanUrl(
|
|
800
|
+
targetUrl: string,
|
|
801
|
+
options?: DASTOptions
|
|
802
|
+
): Promise<Result<DASTResult>> {
|
|
803
|
+
const scanId = uuidv4();
|
|
804
|
+
|
|
805
|
+
try {
|
|
806
|
+
this.activeScans.set(scanId, 'running');
|
|
807
|
+
const startTime = Date.now();
|
|
808
|
+
|
|
809
|
+
const mergedOptions: DASTOptions = {
|
|
810
|
+
maxDepth: options?.maxDepth ?? this.config.dastMaxDepth,
|
|
811
|
+
activeScanning: options?.activeScanning ?? this.config.dastActiveScanning,
|
|
812
|
+
timeout: options?.timeout ?? this.config.timeout,
|
|
813
|
+
excludePatterns: options?.excludePatterns ?? [],
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
// Perform dynamic analysis
|
|
817
|
+
const result = await this.performDynamicScan(targetUrl, mergedOptions);
|
|
818
|
+
|
|
819
|
+
const scanDurationMs = Date.now() - startTime;
|
|
820
|
+
|
|
821
|
+
const summary = this.calculateSummary(
|
|
822
|
+
result.vulnerabilities,
|
|
823
|
+
1,
|
|
824
|
+
scanDurationMs
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
// Store results
|
|
828
|
+
await this.storeScanResults(scanId, 'dast', result.vulnerabilities, summary);
|
|
829
|
+
|
|
830
|
+
this.activeScans.set(scanId, 'completed');
|
|
831
|
+
|
|
832
|
+
return ok({
|
|
833
|
+
scanId,
|
|
834
|
+
targetUrl,
|
|
835
|
+
vulnerabilities: result.vulnerabilities,
|
|
836
|
+
summary,
|
|
837
|
+
crawledUrls: result.crawledUrls,
|
|
838
|
+
});
|
|
839
|
+
} catch (error) {
|
|
840
|
+
this.activeScans.set(scanId, 'failed');
|
|
841
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Scan authenticated endpoints
|
|
847
|
+
*/
|
|
848
|
+
async scanAuthenticated(
|
|
849
|
+
targetUrl: string,
|
|
850
|
+
credentials: AuthCredentials,
|
|
851
|
+
options?: DASTOptions
|
|
852
|
+
): Promise<Result<DASTResult>> {
|
|
853
|
+
const scanId = uuidv4();
|
|
854
|
+
|
|
855
|
+
try {
|
|
856
|
+
this.activeScans.set(scanId, 'running');
|
|
857
|
+
const startTime = Date.now();
|
|
858
|
+
|
|
859
|
+
// Validate credentials
|
|
860
|
+
const credValidation = this.validateCredentials(credentials);
|
|
861
|
+
if (!credValidation.valid) {
|
|
862
|
+
return err(new Error(credValidation.reason));
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const mergedOptions: DASTOptions = {
|
|
866
|
+
maxDepth: options?.maxDepth ?? this.config.dastMaxDepth,
|
|
867
|
+
activeScanning: options?.activeScanning ?? this.config.dastActiveScanning,
|
|
868
|
+
timeout: options?.timeout ?? this.config.timeout,
|
|
869
|
+
excludePatterns: options?.excludePatterns ?? [],
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
// Perform authenticated dynamic analysis
|
|
873
|
+
const result = await this.performAuthenticatedScan(
|
|
874
|
+
targetUrl,
|
|
875
|
+
credentials,
|
|
876
|
+
mergedOptions
|
|
877
|
+
);
|
|
878
|
+
|
|
879
|
+
const scanDurationMs = Date.now() - startTime;
|
|
880
|
+
|
|
881
|
+
const summary = this.calculateSummary(
|
|
882
|
+
result.vulnerabilities,
|
|
883
|
+
1,
|
|
884
|
+
scanDurationMs
|
|
885
|
+
);
|
|
886
|
+
|
|
887
|
+
// Store results (without credentials)
|
|
888
|
+
await this.storeScanResults(scanId, 'dast-auth', result.vulnerabilities, summary);
|
|
889
|
+
|
|
890
|
+
this.activeScans.set(scanId, 'completed');
|
|
891
|
+
|
|
892
|
+
return ok({
|
|
893
|
+
scanId,
|
|
894
|
+
targetUrl,
|
|
895
|
+
vulnerabilities: result.vulnerabilities,
|
|
896
|
+
summary,
|
|
897
|
+
crawledUrls: result.crawledUrls,
|
|
898
|
+
});
|
|
899
|
+
} catch (error) {
|
|
900
|
+
this.activeScans.set(scanId, 'failed');
|
|
901
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Get scan status
|
|
907
|
+
*/
|
|
908
|
+
async getScanStatus(scanId: string): Promise<ScanStatus> {
|
|
909
|
+
return this.activeScans.get(scanId) ?? 'pending';
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// ==========================================================================
|
|
913
|
+
// Combined Scanning
|
|
914
|
+
// ==========================================================================
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Run combined SAST and DAST scan
|
|
918
|
+
*/
|
|
919
|
+
async runFullScan(
|
|
920
|
+
files: FilePath[],
|
|
921
|
+
targetUrl?: string,
|
|
922
|
+
options?: DASTOptions
|
|
923
|
+
): Promise<Result<FullScanResult>> {
|
|
924
|
+
try {
|
|
925
|
+
// Run SAST scan
|
|
926
|
+
const sastResult = await this.scanWithRules(files, this.config.defaultRuleSets);
|
|
927
|
+
if (sastResult.success === false) {
|
|
928
|
+
return err(sastResult.error);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// Run DAST scan if target URL provided
|
|
932
|
+
let dastResult: DASTResult | undefined;
|
|
933
|
+
if (targetUrl) {
|
|
934
|
+
const dastScan = await this.scanUrl(targetUrl, options);
|
|
935
|
+
if (dastScan.success) {
|
|
936
|
+
dastResult = dastScan.value;
|
|
937
|
+
}
|
|
938
|
+
// Don't fail the full scan if DAST fails
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// Combine summaries
|
|
942
|
+
const combinedSummary = this.combineSummaries(
|
|
943
|
+
sastResult.value.summary,
|
|
944
|
+
dastResult?.summary
|
|
945
|
+
);
|
|
946
|
+
|
|
947
|
+
return ok({
|
|
948
|
+
sastResult: sastResult.value,
|
|
949
|
+
dastResult,
|
|
950
|
+
combinedSummary,
|
|
951
|
+
});
|
|
952
|
+
} catch (error) {
|
|
953
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// ==========================================================================
|
|
958
|
+
// Private Helper Methods
|
|
959
|
+
// ==========================================================================
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Analyze a file for security vulnerabilities using pattern-based detection
|
|
963
|
+
*/
|
|
964
|
+
private async analyzeFile(
|
|
965
|
+
file: FilePath,
|
|
966
|
+
ruleSets: RuleSet[]
|
|
967
|
+
): Promise<{ vulnerabilities: Vulnerability[]; linesScanned: number }> {
|
|
968
|
+
const vulnerabilities: Vulnerability[] = [];
|
|
969
|
+
const filePath = file.value;
|
|
970
|
+
const extension = file.extension;
|
|
971
|
+
|
|
972
|
+
// Read file content
|
|
973
|
+
let content: string;
|
|
974
|
+
let lines: string[];
|
|
975
|
+
try {
|
|
976
|
+
const fs = await import('fs/promises');
|
|
977
|
+
content = await fs.readFile(filePath, 'utf-8');
|
|
978
|
+
lines = content.split('\n');
|
|
979
|
+
} catch (error) {
|
|
980
|
+
// File not accessible - return empty results
|
|
981
|
+
return { vulnerabilities: [], linesScanned: 0 };
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
const linesScanned = lines.length;
|
|
985
|
+
|
|
986
|
+
// Only scan supported file types
|
|
987
|
+
const supportedExtensions = ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'];
|
|
988
|
+
if (!supportedExtensions.includes(extension)) {
|
|
989
|
+
return { vulnerabilities: [], linesScanned };
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// Get applicable categories from rule sets
|
|
993
|
+
const applicableCategories = new Set(ruleSets.flatMap((rs) => rs.categories));
|
|
994
|
+
|
|
995
|
+
// Filter patterns to only those matching applicable categories
|
|
996
|
+
const applicablePatterns = ALL_SECURITY_PATTERNS.filter((pattern) =>
|
|
997
|
+
applicableCategories.has(pattern.category)
|
|
998
|
+
);
|
|
999
|
+
|
|
1000
|
+
// Scan content for each pattern
|
|
1001
|
+
for (const securityPattern of applicablePatterns) {
|
|
1002
|
+
const matches = this.findPatternMatches(content, lines, securityPattern);
|
|
1003
|
+
for (const match of matches) {
|
|
1004
|
+
// Skip if in comments or string that looks like documentation
|
|
1005
|
+
if (this.isInComment(content, match.index) || this.isInDocumentation(match.snippet)) {
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// Skip nosec annotations
|
|
1010
|
+
if (this.hasNosecAnnotation(lines, match.line)) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
vulnerabilities.push(
|
|
1015
|
+
this.createVulnerabilityFromPattern(securityPattern, filePath, match)
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
return { vulnerabilities, linesScanned };
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
/**
|
|
1024
|
+
* Find all matches of a security pattern in the file content
|
|
1025
|
+
*/
|
|
1026
|
+
private findPatternMatches(
|
|
1027
|
+
content: string,
|
|
1028
|
+
lines: string[],
|
|
1029
|
+
securityPattern: SecurityPattern
|
|
1030
|
+
): Array<{ index: number; line: number; column: number; snippet: string }> {
|
|
1031
|
+
const matches: Array<{ index: number; line: number; column: number; snippet: string }> = [];
|
|
1032
|
+
|
|
1033
|
+
// Reset regex state for global patterns
|
|
1034
|
+
const pattern = new RegExp(securityPattern.pattern.source, securityPattern.pattern.flags);
|
|
1035
|
+
|
|
1036
|
+
let match: RegExpExecArray | null;
|
|
1037
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
1038
|
+
const index = match.index;
|
|
1039
|
+
const { line, column } = this.getLineAndColumn(content, index);
|
|
1040
|
+
|
|
1041
|
+
// Extract snippet with context (the matched line plus surrounding context)
|
|
1042
|
+
const snippetLines: string[] = [];
|
|
1043
|
+
const startLine = Math.max(0, line - 2);
|
|
1044
|
+
const endLine = Math.min(lines.length - 1, line + 1);
|
|
1045
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
1046
|
+
snippetLines.push(lines[i]);
|
|
1047
|
+
}
|
|
1048
|
+
const snippet = snippetLines.join('\n');
|
|
1049
|
+
|
|
1050
|
+
matches.push({ index, line: line + 1, column: column + 1, snippet }); // 1-indexed
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
return matches;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Convert character index to line and column numbers
|
|
1058
|
+
*/
|
|
1059
|
+
private getLineAndColumn(content: string, index: number): { line: number; column: number } {
|
|
1060
|
+
const beforeMatch = content.substring(0, index);
|
|
1061
|
+
const lines = beforeMatch.split('\n');
|
|
1062
|
+
const line = lines.length - 1;
|
|
1063
|
+
const column = lines[lines.length - 1].length;
|
|
1064
|
+
return { line, column };
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* Check if the match is inside a comment
|
|
1069
|
+
*/
|
|
1070
|
+
private isInComment(content: string, index: number): boolean {
|
|
1071
|
+
const beforeMatch = content.substring(0, index);
|
|
1072
|
+
|
|
1073
|
+
// Check for single-line comment
|
|
1074
|
+
const lastNewline = beforeMatch.lastIndexOf('\n');
|
|
1075
|
+
const currentLine = beforeMatch.substring(lastNewline + 1);
|
|
1076
|
+
if (currentLine.includes('//')) {
|
|
1077
|
+
const commentStart = currentLine.indexOf('//');
|
|
1078
|
+
if (index - (beforeMatch.length - currentLine.length) > commentStart) {
|
|
1079
|
+
return true;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Check for multi-line comment
|
|
1084
|
+
const lastBlockCommentStart = beforeMatch.lastIndexOf('/*');
|
|
1085
|
+
const lastBlockCommentEnd = beforeMatch.lastIndexOf('*/');
|
|
1086
|
+
if (lastBlockCommentStart > lastBlockCommentEnd) {
|
|
1087
|
+
return true;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Check if the snippet appears to be in documentation or test code examples
|
|
1095
|
+
*/
|
|
1096
|
+
private isInDocumentation(snippet: string): boolean {
|
|
1097
|
+
const docPatterns = [
|
|
1098
|
+
/\*\s*@example/i,
|
|
1099
|
+
/\*\s*@description/i,
|
|
1100
|
+
/\/\/\s*example:/i,
|
|
1101
|
+
/\/\/\s*e\.g\./i,
|
|
1102
|
+
/```[\s\S]*```/,
|
|
1103
|
+
];
|
|
1104
|
+
return docPatterns.some((pattern) => pattern.test(snippet));
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Check if the line has a nosec annotation
|
|
1109
|
+
*/
|
|
1110
|
+
private hasNosecAnnotation(lines: string[], lineNumber: number): boolean {
|
|
1111
|
+
const lineIndex = lineNumber - 1;
|
|
1112
|
+
if (lineIndex < 0 || lineIndex >= lines.length) {
|
|
1113
|
+
return false;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
const currentLine = lines[lineIndex];
|
|
1117
|
+
const previousLine = lineIndex > 0 ? lines[lineIndex - 1] : '';
|
|
1118
|
+
|
|
1119
|
+
const nosecPatterns = [
|
|
1120
|
+
/\/\/\s*nosec/i,
|
|
1121
|
+
/\/\/\s*security-ignore/i,
|
|
1122
|
+
/\/\*\s*nosec\s*\*\//i,
|
|
1123
|
+
/#\s*nosec/i,
|
|
1124
|
+
];
|
|
1125
|
+
|
|
1126
|
+
return nosecPatterns.some(
|
|
1127
|
+
(pattern) => pattern.test(currentLine) || pattern.test(previousLine)
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* Create a Vulnerability object from a pattern match
|
|
1133
|
+
*/
|
|
1134
|
+
private createVulnerabilityFromPattern(
|
|
1135
|
+
pattern: SecurityPattern,
|
|
1136
|
+
file: string,
|
|
1137
|
+
match: { line: number; column: number; snippet: string }
|
|
1138
|
+
): Vulnerability {
|
|
1139
|
+
const location: VulnerabilityLocation = {
|
|
1140
|
+
file,
|
|
1141
|
+
line: match.line,
|
|
1142
|
+
column: match.column,
|
|
1143
|
+
snippet: match.snippet,
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
const remediation: RemediationAdvice = {
|
|
1147
|
+
description: pattern.remediation,
|
|
1148
|
+
fixExample: pattern.fixExample,
|
|
1149
|
+
estimatedEffort: this.getEffortForSeverity(pattern.severity),
|
|
1150
|
+
automatable: pattern.severity === 'low' || pattern.severity === 'informational',
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1153
|
+
return {
|
|
1154
|
+
id: uuidv4(),
|
|
1155
|
+
cveId: undefined,
|
|
1156
|
+
title: pattern.title,
|
|
1157
|
+
description: `${pattern.description} [${pattern.cweId}]`,
|
|
1158
|
+
severity: pattern.severity,
|
|
1159
|
+
category: pattern.category,
|
|
1160
|
+
location,
|
|
1161
|
+
remediation,
|
|
1162
|
+
references: [
|
|
1163
|
+
`https://owasp.org/Top10/${pattern.owaspId.replace(':', '_')}/`,
|
|
1164
|
+
`https://cwe.mitre.org/data/definitions/${pattern.cweId.replace('CWE-', '')}.html`,
|
|
1165
|
+
],
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
private getEffortForSeverity(
|
|
1170
|
+
severity: VulnerabilitySeverity
|
|
1171
|
+
): RemediationAdvice['estimatedEffort'] {
|
|
1172
|
+
const efforts: Record<VulnerabilitySeverity, RemediationAdvice['estimatedEffort']> = {
|
|
1173
|
+
critical: 'major',
|
|
1174
|
+
high: 'moderate',
|
|
1175
|
+
medium: 'minor',
|
|
1176
|
+
low: 'trivial',
|
|
1177
|
+
informational: 'trivial',
|
|
1178
|
+
};
|
|
1179
|
+
return efforts[severity];
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Perform dynamic (DAST) scanning on a target URL
|
|
1184
|
+
* Makes actual HTTP requests to detect security vulnerabilities
|
|
1185
|
+
*
|
|
1186
|
+
* **Capabilities:**
|
|
1187
|
+
* - Security header analysis (HSTS, CSP, X-Frame-Options, etc.)
|
|
1188
|
+
* - Cookie security (Secure, HttpOnly, SameSite flags)
|
|
1189
|
+
* - CORS misconfiguration detection
|
|
1190
|
+
* - Sensitive file exposure (/.git, /.env, etc.)
|
|
1191
|
+
* - Link crawling with same-origin scope
|
|
1192
|
+
* - XSS reflection testing (GET parameters)
|
|
1193
|
+
* - SQL injection error-based detection (GET parameters)
|
|
1194
|
+
* - Form security analysis (CSRF tokens, autocomplete, action URLs)
|
|
1195
|
+
*
|
|
1196
|
+
* **Limitations:**
|
|
1197
|
+
* - Injection testing: GET parameters only (POST form submission not implemented)
|
|
1198
|
+
* - Crawling: Same-origin only, max 10 links per page, single depth
|
|
1199
|
+
* - Auth flows: Header-based only, no login form automation
|
|
1200
|
+
* - No JavaScript execution (static response analysis only)
|
|
1201
|
+
* - No session management testing beyond cookie attributes
|
|
1202
|
+
*/
|
|
1203
|
+
private async performDynamicScan(
|
|
1204
|
+
targetUrl: string,
|
|
1205
|
+
options: DASTOptions
|
|
1206
|
+
): Promise<{ vulnerabilities: Vulnerability[]; crawledUrls: number }> {
|
|
1207
|
+
const vulnerabilities: Vulnerability[] = [];
|
|
1208
|
+
let crawledUrls = 0;
|
|
1209
|
+
|
|
1210
|
+
try {
|
|
1211
|
+
// Validate and parse URL
|
|
1212
|
+
let parsedUrl: URL;
|
|
1213
|
+
try {
|
|
1214
|
+
parsedUrl = new URL(targetUrl);
|
|
1215
|
+
} catch {
|
|
1216
|
+
// Invalid URL - return informational finding
|
|
1217
|
+
vulnerabilities.push({
|
|
1218
|
+
id: uuidv4(),
|
|
1219
|
+
title: 'Invalid Target URL',
|
|
1220
|
+
description: 'The provided target URL is not valid',
|
|
1221
|
+
severity: 'informational',
|
|
1222
|
+
category: 'security-misconfiguration',
|
|
1223
|
+
location: { file: targetUrl },
|
|
1224
|
+
remediation: { description: 'Provide a valid URL', estimatedEffort: 'trivial', automatable: false },
|
|
1225
|
+
references: [],
|
|
1226
|
+
});
|
|
1227
|
+
return { vulnerabilities, crawledUrls: 0 };
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
const timeout = options.timeout ?? this.config.timeout;
|
|
1231
|
+
const maxDepth = options.maxDepth ?? this.config.dastMaxDepth;
|
|
1232
|
+
|
|
1233
|
+
// Perform main page scan
|
|
1234
|
+
const controller = new AbortController();
|
|
1235
|
+
const timeoutId = setTimeout(() => controller.abort(), Math.min(timeout, 30000));
|
|
1236
|
+
|
|
1237
|
+
try {
|
|
1238
|
+
const response = await fetch(targetUrl, {
|
|
1239
|
+
method: 'GET',
|
|
1240
|
+
headers: {
|
|
1241
|
+
'User-Agent': 'AgenticQE-DAST-Scanner/3.0',
|
|
1242
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
1243
|
+
},
|
|
1244
|
+
signal: controller.signal,
|
|
1245
|
+
redirect: 'follow',
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
clearTimeout(timeoutId);
|
|
1249
|
+
crawledUrls++;
|
|
1250
|
+
|
|
1251
|
+
// Security header analysis
|
|
1252
|
+
const headers = response.headers;
|
|
1253
|
+
|
|
1254
|
+
// Check for missing security headers
|
|
1255
|
+
const headerChecks = [
|
|
1256
|
+
{ header: 'strict-transport-security', title: 'Missing HSTS Header', severity: 'medium' as VulnerabilitySeverity, remediation: 'Add Strict-Transport-Security header' },
|
|
1257
|
+
{ header: 'x-content-type-options', title: 'Missing X-Content-Type-Options', severity: 'low' as VulnerabilitySeverity, remediation: 'Add X-Content-Type-Options: nosniff' },
|
|
1258
|
+
{ header: 'x-frame-options', title: 'Missing X-Frame-Options', severity: 'medium' as VulnerabilitySeverity, remediation: 'Add X-Frame-Options: DENY or SAMEORIGIN' },
|
|
1259
|
+
{ header: 'content-security-policy', title: 'Missing Content-Security-Policy', severity: 'medium' as VulnerabilitySeverity, remediation: 'Implement a Content-Security-Policy' },
|
|
1260
|
+
{ header: 'referrer-policy', title: 'Missing Referrer-Policy', severity: 'low' as VulnerabilitySeverity, remediation: 'Add Referrer-Policy header' },
|
|
1261
|
+
{ header: 'permissions-policy', title: 'Missing Permissions-Policy', severity: 'low' as VulnerabilitySeverity, remediation: 'Add Permissions-Policy header' },
|
|
1262
|
+
];
|
|
1263
|
+
|
|
1264
|
+
for (const check of headerChecks) {
|
|
1265
|
+
if (!headers.get(check.header)) {
|
|
1266
|
+
vulnerabilities.push({
|
|
1267
|
+
id: uuidv4(),
|
|
1268
|
+
title: check.title,
|
|
1269
|
+
description: `Security header ${check.header} is not present in the response`,
|
|
1270
|
+
severity: check.severity,
|
|
1271
|
+
category: 'security-misconfiguration',
|
|
1272
|
+
location: { file: targetUrl, snippet: `Missing: ${check.header}` },
|
|
1273
|
+
remediation: { description: check.remediation, estimatedEffort: 'minor', automatable: true },
|
|
1274
|
+
references: ['https://owasp.org/www-project-secure-headers/'],
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// Check for insecure protocol
|
|
1280
|
+
if (parsedUrl.protocol === 'http:') {
|
|
1281
|
+
vulnerabilities.push({
|
|
1282
|
+
id: uuidv4(),
|
|
1283
|
+
title: 'Insecure HTTP Protocol',
|
|
1284
|
+
description: 'Application is accessible over unencrypted HTTP',
|
|
1285
|
+
severity: 'high',
|
|
1286
|
+
category: 'sensitive-data',
|
|
1287
|
+
location: { file: targetUrl },
|
|
1288
|
+
remediation: { description: 'Redirect all HTTP traffic to HTTPS', estimatedEffort: 'moderate', automatable: false },
|
|
1289
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
// Check for cookie security
|
|
1294
|
+
const setCookie = headers.get('set-cookie');
|
|
1295
|
+
if (setCookie) {
|
|
1296
|
+
const cookieLower = setCookie.toLowerCase();
|
|
1297
|
+
if (!cookieLower.includes('secure')) {
|
|
1298
|
+
vulnerabilities.push({
|
|
1299
|
+
id: uuidv4(),
|
|
1300
|
+
title: 'Cookie Missing Secure Flag',
|
|
1301
|
+
description: 'Cookie is set without the Secure attribute',
|
|
1302
|
+
severity: 'medium',
|
|
1303
|
+
category: 'sensitive-data',
|
|
1304
|
+
location: { file: targetUrl, snippet: `Set-Cookie header without Secure flag` },
|
|
1305
|
+
remediation: { description: 'Add Secure flag to all cookies', estimatedEffort: 'trivial', automatable: true },
|
|
1306
|
+
references: ['https://owasp.org/www-community/controls/SecureCookieAttribute'],
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
if (!cookieLower.includes('httponly')) {
|
|
1310
|
+
vulnerabilities.push({
|
|
1311
|
+
id: uuidv4(),
|
|
1312
|
+
title: 'Cookie Missing HttpOnly Flag',
|
|
1313
|
+
description: 'Cookie is accessible to client-side JavaScript',
|
|
1314
|
+
severity: 'medium',
|
|
1315
|
+
category: 'sensitive-data',
|
|
1316
|
+
location: { file: targetUrl, snippet: `Set-Cookie header without HttpOnly flag` },
|
|
1317
|
+
remediation: { description: 'Add HttpOnly flag to session cookies', estimatedEffort: 'trivial', automatable: true },
|
|
1318
|
+
references: ['https://owasp.org/www-community/HttpOnly'],
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
// Check for server version disclosure
|
|
1324
|
+
const serverHeader = headers.get('server') || headers.get('x-powered-by');
|
|
1325
|
+
if (serverHeader && /\d+\.\d+/.test(serverHeader)) {
|
|
1326
|
+
vulnerabilities.push({
|
|
1327
|
+
id: uuidv4(),
|
|
1328
|
+
title: 'Server Version Disclosure',
|
|
1329
|
+
description: `Server version information exposed: ${serverHeader}`,
|
|
1330
|
+
severity: 'low',
|
|
1331
|
+
category: 'security-misconfiguration',
|
|
1332
|
+
location: { file: targetUrl, snippet: `Server: ${serverHeader}` },
|
|
1333
|
+
remediation: { description: 'Remove or obfuscate server version headers', estimatedEffort: 'trivial', automatable: true },
|
|
1334
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
// Scan for sensitive file exposure (only if active scanning is enabled)
|
|
1339
|
+
if (options.activeScanning ?? this.config.dastActiveScanning) {
|
|
1340
|
+
const sensitiveEndpoints = [
|
|
1341
|
+
{ path: '/.git/config', name: 'Git Configuration' },
|
|
1342
|
+
{ path: '/.env', name: 'Environment File' },
|
|
1343
|
+
{ path: '/robots.txt', name: 'Robots.txt' },
|
|
1344
|
+
{ path: '/sitemap.xml', name: 'Sitemap' },
|
|
1345
|
+
{ path: '/.htaccess', name: 'htaccess File' },
|
|
1346
|
+
{ path: '/web.config', name: 'IIS Configuration' },
|
|
1347
|
+
];
|
|
1348
|
+
|
|
1349
|
+
for (const endpoint of sensitiveEndpoints) {
|
|
1350
|
+
if (crawledUrls >= maxDepth * 10) break; // Limit crawling
|
|
1351
|
+
|
|
1352
|
+
try {
|
|
1353
|
+
const testUrl = new URL(endpoint.path, parsedUrl.origin).toString();
|
|
1354
|
+
const testResponse = await fetch(testUrl, {
|
|
1355
|
+
method: 'GET',
|
|
1356
|
+
signal: AbortSignal.timeout(5000),
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
if (testResponse.ok) {
|
|
1360
|
+
crawledUrls++;
|
|
1361
|
+
const contentType = testResponse.headers.get('content-type') || '';
|
|
1362
|
+
const text = await testResponse.text();
|
|
1363
|
+
|
|
1364
|
+
// Verify it's not a custom 404 page
|
|
1365
|
+
if (text.length > 20 && !text.toLowerCase().includes('not found') && !text.toLowerCase().includes('404')) {
|
|
1366
|
+
// Check for sensitive content markers
|
|
1367
|
+
const isSensitive =
|
|
1368
|
+
endpoint.path.includes('.git') ||
|
|
1369
|
+
endpoint.path.includes('.env') ||
|
|
1370
|
+
endpoint.path.includes('.htaccess') ||
|
|
1371
|
+
endpoint.path.includes('web.config');
|
|
1372
|
+
|
|
1373
|
+
if (isSensitive) {
|
|
1374
|
+
vulnerabilities.push({
|
|
1375
|
+
id: uuidv4(),
|
|
1376
|
+
title: `Sensitive File Exposed: ${endpoint.name}`,
|
|
1377
|
+
description: `${endpoint.name} is publicly accessible`,
|
|
1378
|
+
severity: endpoint.path.includes('.git') || endpoint.path.includes('.env') ? 'high' : 'medium',
|
|
1379
|
+
category: 'sensitive-data',
|
|
1380
|
+
location: { file: testUrl },
|
|
1381
|
+
remediation: { description: `Restrict access to ${endpoint.path}`, estimatedEffort: 'trivial', automatable: true },
|
|
1382
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
} catch {
|
|
1388
|
+
// File not accessible - this is expected/good
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
// CORS analysis
|
|
1394
|
+
try {
|
|
1395
|
+
const corsResponse = await fetch(targetUrl, {
|
|
1396
|
+
method: 'OPTIONS',
|
|
1397
|
+
headers: {
|
|
1398
|
+
'Origin': 'https://evil-attacker.com',
|
|
1399
|
+
'Access-Control-Request-Method': 'GET',
|
|
1400
|
+
},
|
|
1401
|
+
signal: AbortSignal.timeout(5000),
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
const allowOrigin = corsResponse.headers.get('access-control-allow-origin');
|
|
1405
|
+
if (allowOrigin === '*' || allowOrigin === 'https://evil-attacker.com') {
|
|
1406
|
+
vulnerabilities.push({
|
|
1407
|
+
id: uuidv4(),
|
|
1408
|
+
title: 'Overly Permissive CORS Policy',
|
|
1409
|
+
description: allowOrigin === '*' ? 'CORS allows all origins' : 'CORS reflects arbitrary origin',
|
|
1410
|
+
severity: 'medium',
|
|
1411
|
+
category: 'access-control',
|
|
1412
|
+
location: { file: targetUrl, snippet: `Access-Control-Allow-Origin: ${allowOrigin}` },
|
|
1413
|
+
remediation: { description: 'Restrict CORS to specific trusted origins', estimatedEffort: 'minor', automatable: false },
|
|
1414
|
+
references: ['https://owasp.org/www-community/attacks/CORS_OriginHeaderScrutiny'],
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
} catch {
|
|
1418
|
+
// OPTIONS request failed - CORS might be properly restricted
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// ============================================================
|
|
1422
|
+
// ENHANCED DAST: Link crawling, injection testing, form analysis
|
|
1423
|
+
// ============================================================
|
|
1424
|
+
|
|
1425
|
+
if (options.activeScanning ?? this.config.dastActiveScanning) {
|
|
1426
|
+
const responseText = await response.clone().text();
|
|
1427
|
+
|
|
1428
|
+
// 1. LINK CRAWLING - Extract and scan discovered links
|
|
1429
|
+
const discoveredUrls = await this.extractAndCrawlLinks(
|
|
1430
|
+
responseText,
|
|
1431
|
+
parsedUrl,
|
|
1432
|
+
crawledUrls,
|
|
1433
|
+
maxDepth,
|
|
1434
|
+
vulnerabilities
|
|
1435
|
+
);
|
|
1436
|
+
crawledUrls = discoveredUrls;
|
|
1437
|
+
|
|
1438
|
+
// 2. INJECTION TESTING - Test URL parameters for XSS/SQLi
|
|
1439
|
+
if (parsedUrl.search) {
|
|
1440
|
+
await this.testInjectionVulnerabilities(
|
|
1441
|
+
targetUrl,
|
|
1442
|
+
parsedUrl,
|
|
1443
|
+
vulnerabilities
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
// 3. FORM DISCOVERY - Analyze forms for security issues
|
|
1448
|
+
await this.analyzeFormsForSecurityIssues(
|
|
1449
|
+
responseText,
|
|
1450
|
+
targetUrl,
|
|
1451
|
+
vulnerabilities
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
} catch (fetchError) {
|
|
1456
|
+
clearTimeout(timeoutId);
|
|
1457
|
+
const errorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
1458
|
+
|
|
1459
|
+
if (errorMsg.includes('CERT') || errorMsg.includes('SSL') || errorMsg.includes('TLS') || errorMsg.includes('certificate')) {
|
|
1460
|
+
vulnerabilities.push({
|
|
1461
|
+
id: uuidv4(),
|
|
1462
|
+
title: 'TLS Certificate Error',
|
|
1463
|
+
description: `SSL/TLS error: ${errorMsg}`,
|
|
1464
|
+
severity: 'high',
|
|
1465
|
+
category: 'security-misconfiguration',
|
|
1466
|
+
location: { file: targetUrl },
|
|
1467
|
+
remediation: { description: 'Fix TLS certificate configuration', estimatedEffort: 'moderate', automatable: false },
|
|
1468
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
1469
|
+
});
|
|
1470
|
+
} else if (errorMsg.includes('timeout') || errorMsg.includes('abort')) {
|
|
1471
|
+
vulnerabilities.push({
|
|
1472
|
+
id: uuidv4(),
|
|
1473
|
+
title: 'Connection Timeout',
|
|
1474
|
+
description: `Target did not respond within timeout: ${errorMsg}`,
|
|
1475
|
+
severity: 'informational',
|
|
1476
|
+
category: 'security-misconfiguration',
|
|
1477
|
+
location: { file: targetUrl },
|
|
1478
|
+
remediation: { description: 'Verify target is accessible', estimatedEffort: 'trivial', automatable: false },
|
|
1479
|
+
references: [],
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
} catch (error) {
|
|
1485
|
+
console.error('DAST scan error:', error);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
return { vulnerabilities, crawledUrls };
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* Perform authenticated dynamic scanning with credentials
|
|
1493
|
+
* Supports basic auth, bearer token, OAuth, and cookie-based authentication
|
|
1494
|
+
*/
|
|
1495
|
+
private async performAuthenticatedScan(
|
|
1496
|
+
targetUrl: string,
|
|
1497
|
+
credentials: AuthCredentials,
|
|
1498
|
+
options: DASTOptions
|
|
1499
|
+
): Promise<{ vulnerabilities: Vulnerability[]; crawledUrls: number }> {
|
|
1500
|
+
const vulnerabilities: Vulnerability[] = [];
|
|
1501
|
+
let crawledUrls = 0;
|
|
1502
|
+
|
|
1503
|
+
try {
|
|
1504
|
+
// Build authentication headers based on credential type
|
|
1505
|
+
const authHeaders: Record<string, string> = {};
|
|
1506
|
+
|
|
1507
|
+
switch (credentials.type) {
|
|
1508
|
+
case 'basic':
|
|
1509
|
+
if (credentials.username && credentials.password) {
|
|
1510
|
+
const encoded = Buffer.from(`${credentials.username}:${credentials.password}`).toString('base64');
|
|
1511
|
+
authHeaders['Authorization'] = `Basic ${encoded}`;
|
|
1512
|
+
}
|
|
1513
|
+
break;
|
|
1514
|
+
case 'bearer':
|
|
1515
|
+
case 'oauth':
|
|
1516
|
+
if (credentials.token) {
|
|
1517
|
+
authHeaders['Authorization'] = `Bearer ${credentials.token}`;
|
|
1518
|
+
}
|
|
1519
|
+
break;
|
|
1520
|
+
case 'cookie':
|
|
1521
|
+
if (credentials.token) {
|
|
1522
|
+
authHeaders['Cookie'] = credentials.token;
|
|
1523
|
+
}
|
|
1524
|
+
break;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// Validate and parse URL
|
|
1528
|
+
let parsedUrl: URL;
|
|
1529
|
+
try {
|
|
1530
|
+
parsedUrl = new URL(targetUrl);
|
|
1531
|
+
} catch {
|
|
1532
|
+
vulnerabilities.push({
|
|
1533
|
+
id: uuidv4(),
|
|
1534
|
+
title: 'Invalid Target URL',
|
|
1535
|
+
description: 'The provided target URL is not valid',
|
|
1536
|
+
severity: 'informational',
|
|
1537
|
+
category: 'security-misconfiguration',
|
|
1538
|
+
location: { file: targetUrl },
|
|
1539
|
+
remediation: { description: 'Provide a valid URL', estimatedEffort: 'trivial', automatable: false },
|
|
1540
|
+
references: [],
|
|
1541
|
+
});
|
|
1542
|
+
return { vulnerabilities, crawledUrls: 0 };
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
const timeout = options.timeout ?? this.config.timeout;
|
|
1546
|
+
const maxDepth = options.maxDepth ?? this.config.dastMaxDepth;
|
|
1547
|
+
|
|
1548
|
+
// Test authentication by making an authenticated request
|
|
1549
|
+
const controller = new AbortController();
|
|
1550
|
+
const timeoutId = setTimeout(() => controller.abort(), Math.min(timeout, 30000));
|
|
1551
|
+
|
|
1552
|
+
try {
|
|
1553
|
+
const response = await fetch(targetUrl, {
|
|
1554
|
+
method: 'GET',
|
|
1555
|
+
headers: {
|
|
1556
|
+
'User-Agent': 'AgenticQE-DAST-Scanner/3.0',
|
|
1557
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
1558
|
+
...authHeaders,
|
|
1559
|
+
},
|
|
1560
|
+
signal: controller.signal,
|
|
1561
|
+
redirect: 'follow',
|
|
1562
|
+
});
|
|
1563
|
+
|
|
1564
|
+
clearTimeout(timeoutId);
|
|
1565
|
+
crawledUrls++;
|
|
1566
|
+
|
|
1567
|
+
// Check if authentication was successful
|
|
1568
|
+
if (response.status === 401 || response.status === 403) {
|
|
1569
|
+
vulnerabilities.push({
|
|
1570
|
+
id: uuidv4(),
|
|
1571
|
+
title: 'Authentication Failed',
|
|
1572
|
+
description: `Authentication returned ${response.status} status`,
|
|
1573
|
+
severity: 'informational',
|
|
1574
|
+
category: 'broken-auth',
|
|
1575
|
+
location: { file: targetUrl },
|
|
1576
|
+
remediation: { description: 'Verify credentials are correct', estimatedEffort: 'trivial', automatable: false },
|
|
1577
|
+
references: [],
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
// Perform all the standard header checks from unauthenticated scan
|
|
1582
|
+
const headers = response.headers;
|
|
1583
|
+
|
|
1584
|
+
// Security header analysis (same as unauthenticated)
|
|
1585
|
+
const headerChecks = [
|
|
1586
|
+
{ header: 'strict-transport-security', title: 'Missing HSTS Header', severity: 'medium' as VulnerabilitySeverity },
|
|
1587
|
+
{ header: 'x-content-type-options', title: 'Missing X-Content-Type-Options', severity: 'low' as VulnerabilitySeverity },
|
|
1588
|
+
{ header: 'x-frame-options', title: 'Missing X-Frame-Options', severity: 'medium' as VulnerabilitySeverity },
|
|
1589
|
+
{ header: 'content-security-policy', title: 'Missing Content-Security-Policy', severity: 'medium' as VulnerabilitySeverity },
|
|
1590
|
+
];
|
|
1591
|
+
|
|
1592
|
+
for (const check of headerChecks) {
|
|
1593
|
+
if (!headers.get(check.header)) {
|
|
1594
|
+
vulnerabilities.push({
|
|
1595
|
+
id: uuidv4(),
|
|
1596
|
+
title: check.title,
|
|
1597
|
+
description: `Security header ${check.header} is not present`,
|
|
1598
|
+
severity: check.severity,
|
|
1599
|
+
category: 'security-misconfiguration',
|
|
1600
|
+
location: { file: targetUrl, snippet: `Missing: ${check.header}` },
|
|
1601
|
+
remediation: { description: `Add ${check.header} header`, estimatedEffort: 'minor', automatable: true },
|
|
1602
|
+
references: ['https://owasp.org/www-project-secure-headers/'],
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// Check for session token in URL (authenticated-specific)
|
|
1608
|
+
if (parsedUrl.search.includes('token=') || parsedUrl.search.includes('session=') || parsedUrl.search.includes('auth=')) {
|
|
1609
|
+
vulnerabilities.push({
|
|
1610
|
+
id: uuidv4(),
|
|
1611
|
+
title: 'Session Token in URL',
|
|
1612
|
+
description: 'Authentication token appears in URL query string',
|
|
1613
|
+
severity: 'high',
|
|
1614
|
+
category: 'sensitive-data',
|
|
1615
|
+
location: { file: targetUrl, snippet: parsedUrl.search.substring(0, 50) },
|
|
1616
|
+
remediation: { description: 'Send tokens in headers or request body, not URL', estimatedEffort: 'moderate', automatable: false },
|
|
1617
|
+
references: ['https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url'],
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
// Test for authorization bypass on protected endpoints (authenticated-specific)
|
|
1622
|
+
if (options.activeScanning ?? this.config.dastActiveScanning) {
|
|
1623
|
+
const protectedEndpoints = [
|
|
1624
|
+
'/admin',
|
|
1625
|
+
'/dashboard',
|
|
1626
|
+
'/api/users',
|
|
1627
|
+
'/api/admin',
|
|
1628
|
+
'/settings',
|
|
1629
|
+
'/profile',
|
|
1630
|
+
];
|
|
1631
|
+
|
|
1632
|
+
for (const endpoint of protectedEndpoints) {
|
|
1633
|
+
if (crawledUrls >= maxDepth * 15) break;
|
|
1634
|
+
|
|
1635
|
+
try {
|
|
1636
|
+
const testUrl = new URL(endpoint, parsedUrl.origin).toString();
|
|
1637
|
+
|
|
1638
|
+
// First, try with authentication
|
|
1639
|
+
const authResponse = await fetch(testUrl, {
|
|
1640
|
+
method: 'GET',
|
|
1641
|
+
headers: { ...authHeaders },
|
|
1642
|
+
signal: AbortSignal.timeout(5000),
|
|
1643
|
+
});
|
|
1644
|
+
|
|
1645
|
+
if (authResponse.ok) {
|
|
1646
|
+
crawledUrls++;
|
|
1647
|
+
|
|
1648
|
+
// Now try without authentication
|
|
1649
|
+
const unauthResponse = await fetch(testUrl, {
|
|
1650
|
+
method: 'GET',
|
|
1651
|
+
signal: AbortSignal.timeout(5000),
|
|
1652
|
+
});
|
|
1653
|
+
|
|
1654
|
+
// If both succeed, there might be missing authentication
|
|
1655
|
+
if (unauthResponse.ok && unauthResponse.status === 200) {
|
|
1656
|
+
const authText = await authResponse.text();
|
|
1657
|
+
const unauthText = await unauthResponse.text();
|
|
1658
|
+
|
|
1659
|
+
// Check if the responses are similar (both returning actual content)
|
|
1660
|
+
if (authText.length > 100 && unauthText.length > 100 &&
|
|
1661
|
+
Math.abs(authText.length - unauthText.length) < authText.length * 0.1) {
|
|
1662
|
+
vulnerabilities.push({
|
|
1663
|
+
id: uuidv4(),
|
|
1664
|
+
title: 'Missing Authentication on Protected Endpoint',
|
|
1665
|
+
description: `Endpoint ${endpoint} is accessible without authentication`,
|
|
1666
|
+
severity: 'high',
|
|
1667
|
+
category: 'broken-auth',
|
|
1668
|
+
location: { file: testUrl },
|
|
1669
|
+
remediation: { description: 'Implement proper authentication checks', estimatedEffort: 'moderate', automatable: false },
|
|
1670
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
} catch {
|
|
1676
|
+
// Endpoint not accessible - expected
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
// Test for Insecure Direct Object References (IDOR)
|
|
1681
|
+
const idorEndpoints = [
|
|
1682
|
+
'/api/users/1',
|
|
1683
|
+
'/api/users/2',
|
|
1684
|
+
'/api/orders/1',
|
|
1685
|
+
'/profile/1',
|
|
1686
|
+
];
|
|
1687
|
+
|
|
1688
|
+
for (const endpoint of idorEndpoints.slice(0, 2)) {
|
|
1689
|
+
if (crawledUrls >= maxDepth * 15) break;
|
|
1690
|
+
|
|
1691
|
+
try {
|
|
1692
|
+
const testUrl = new URL(endpoint, parsedUrl.origin).toString();
|
|
1693
|
+
const response = await fetch(testUrl, {
|
|
1694
|
+
method: 'GET',
|
|
1695
|
+
headers: { ...authHeaders },
|
|
1696
|
+
signal: AbortSignal.timeout(5000),
|
|
1697
|
+
});
|
|
1698
|
+
|
|
1699
|
+
if (response.ok) {
|
|
1700
|
+
crawledUrls++;
|
|
1701
|
+
const text = await response.text();
|
|
1702
|
+
|
|
1703
|
+
// If we can access other users' data, that's an IDOR
|
|
1704
|
+
if (text.includes('email') || text.includes('password') || text.includes('phone')) {
|
|
1705
|
+
vulnerabilities.push({
|
|
1706
|
+
id: uuidv4(),
|
|
1707
|
+
title: 'Potential Insecure Direct Object Reference (IDOR)',
|
|
1708
|
+
description: `Endpoint ${endpoint} may expose other users' data`,
|
|
1709
|
+
severity: 'high',
|
|
1710
|
+
category: 'access-control',
|
|
1711
|
+
location: { file: testUrl },
|
|
1712
|
+
remediation: { description: 'Implement proper authorization checks for resource access', estimatedEffort: 'moderate', automatable: false },
|
|
1713
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References'],
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
} catch {
|
|
1718
|
+
// Endpoint not accessible
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
// Cookie security checks
|
|
1724
|
+
const setCookie = headers.get('set-cookie');
|
|
1725
|
+
if (setCookie) {
|
|
1726
|
+
const cookieLower = setCookie.toLowerCase();
|
|
1727
|
+
if (!cookieLower.includes('secure')) {
|
|
1728
|
+
vulnerabilities.push({
|
|
1729
|
+
id: uuidv4(),
|
|
1730
|
+
title: 'Session Cookie Missing Secure Flag',
|
|
1731
|
+
description: 'Authenticated session cookie is not marked as Secure',
|
|
1732
|
+
severity: 'high', // Higher severity for authenticated sessions
|
|
1733
|
+
category: 'sensitive-data',
|
|
1734
|
+
location: { file: targetUrl },
|
|
1735
|
+
remediation: { description: 'Add Secure flag to session cookies', estimatedEffort: 'trivial', automatable: true },
|
|
1736
|
+
references: ['https://owasp.org/www-community/controls/SecureCookieAttribute'],
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
if (!cookieLower.includes('httponly')) {
|
|
1740
|
+
vulnerabilities.push({
|
|
1741
|
+
id: uuidv4(),
|
|
1742
|
+
title: 'Session Cookie Missing HttpOnly Flag',
|
|
1743
|
+
description: 'Session cookie is accessible to JavaScript',
|
|
1744
|
+
severity: 'high',
|
|
1745
|
+
category: 'sensitive-data',
|
|
1746
|
+
location: { file: targetUrl },
|
|
1747
|
+
remediation: { description: 'Add HttpOnly flag to session cookies', estimatedEffort: 'trivial', automatable: true },
|
|
1748
|
+
references: ['https://owasp.org/www-community/HttpOnly'],
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
} catch (fetchError) {
|
|
1754
|
+
clearTimeout(timeoutId);
|
|
1755
|
+
const errorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
1756
|
+
|
|
1757
|
+
if (errorMsg.includes('CERT') || errorMsg.includes('SSL') || errorMsg.includes('TLS')) {
|
|
1758
|
+
vulnerabilities.push({
|
|
1759
|
+
id: uuidv4(),
|
|
1760
|
+
title: 'TLS Certificate Error',
|
|
1761
|
+
description: `SSL/TLS error during authenticated scan: ${errorMsg}`,
|
|
1762
|
+
severity: 'high',
|
|
1763
|
+
category: 'security-misconfiguration',
|
|
1764
|
+
location: { file: targetUrl },
|
|
1765
|
+
remediation: { description: 'Fix TLS certificate configuration', estimatedEffort: 'moderate', automatable: false },
|
|
1766
|
+
references: [],
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
} catch (error) {
|
|
1772
|
+
console.error('Authenticated DAST scan error:', error);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
return { vulnerabilities, crawledUrls };
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
private validateCredentials(credentials: AuthCredentials): {
|
|
1779
|
+
valid: boolean;
|
|
1780
|
+
reason?: string;
|
|
1781
|
+
} {
|
|
1782
|
+
switch (credentials.type) {
|
|
1783
|
+
case 'basic':
|
|
1784
|
+
if (!credentials.username || !credentials.password) {
|
|
1785
|
+
return { valid: false, reason: 'Basic auth requires username and password' };
|
|
1786
|
+
}
|
|
1787
|
+
break;
|
|
1788
|
+
case 'bearer':
|
|
1789
|
+
case 'oauth':
|
|
1790
|
+
if (!credentials.token) {
|
|
1791
|
+
return { valid: false, reason: 'Bearer/OAuth auth requires token' };
|
|
1792
|
+
}
|
|
1793
|
+
break;
|
|
1794
|
+
case 'cookie':
|
|
1795
|
+
if (!credentials.token) {
|
|
1796
|
+
return { valid: false, reason: 'Cookie auth requires session cookie' };
|
|
1797
|
+
}
|
|
1798
|
+
break;
|
|
1799
|
+
}
|
|
1800
|
+
return { valid: true };
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* Analyze if a vulnerability detection is a false positive using heuristics
|
|
1805
|
+
* Future enhancement: integrate ML/AI models for improved false positive detection
|
|
1806
|
+
*/
|
|
1807
|
+
private async analyzeFalsePositive(
|
|
1808
|
+
vulnerability: Vulnerability
|
|
1809
|
+
): Promise<FalsePositiveCheck> {
|
|
1810
|
+
let isFalsePositive = false;
|
|
1811
|
+
let confidence = 0.5;
|
|
1812
|
+
let reason = 'Manual review recommended';
|
|
1813
|
+
|
|
1814
|
+
// Check for common false positive patterns
|
|
1815
|
+
if (vulnerability.severity === 'informational') {
|
|
1816
|
+
confidence = 0.3;
|
|
1817
|
+
reason = 'Low severity findings often require manual verification';
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
if (
|
|
1821
|
+
vulnerability.location.snippet?.includes('test') ||
|
|
1822
|
+
vulnerability.location.file.includes('test')
|
|
1823
|
+
) {
|
|
1824
|
+
isFalsePositive = true;
|
|
1825
|
+
confidence = 0.8;
|
|
1826
|
+
reason = 'Vulnerability found in test code';
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
if (vulnerability.location.snippet?.includes('// nosec')) {
|
|
1830
|
+
isFalsePositive = true;
|
|
1831
|
+
confidence = 0.95;
|
|
1832
|
+
reason = 'Explicitly marked as ignored with nosec comment';
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
return { isFalsePositive, confidence, reason };
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
private calculateSummary(
|
|
1839
|
+
vulnerabilities: Vulnerability[],
|
|
1840
|
+
totalFiles: number,
|
|
1841
|
+
scanDurationMs: number
|
|
1842
|
+
): ScanSummary {
|
|
1843
|
+
const summary: MutableScanSummary = {
|
|
1844
|
+
critical: 0,
|
|
1845
|
+
high: 0,
|
|
1846
|
+
medium: 0,
|
|
1847
|
+
low: 0,
|
|
1848
|
+
informational: 0,
|
|
1849
|
+
totalFiles,
|
|
1850
|
+
scanDurationMs,
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
for (const vuln of vulnerabilities) {
|
|
1854
|
+
summary[vuln.severity]++;
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
return summary as ScanSummary;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
private combineSummaries(
|
|
1861
|
+
sast: ScanSummary,
|
|
1862
|
+
dast?: ScanSummary
|
|
1863
|
+
): ScanSummary {
|
|
1864
|
+
if (!dast) return sast;
|
|
1865
|
+
|
|
1866
|
+
return {
|
|
1867
|
+
critical: sast.critical + dast.critical,
|
|
1868
|
+
high: sast.high + dast.high,
|
|
1869
|
+
medium: sast.medium + dast.medium,
|
|
1870
|
+
low: sast.low + dast.low,
|
|
1871
|
+
informational: sast.informational + dast.informational,
|
|
1872
|
+
totalFiles: sast.totalFiles + dast.totalFiles,
|
|
1873
|
+
scanDurationMs: sast.scanDurationMs + dast.scanDurationMs,
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
private async storeScanResults(
|
|
1878
|
+
scanId: string,
|
|
1879
|
+
scanType: string,
|
|
1880
|
+
vulnerabilities: Vulnerability[],
|
|
1881
|
+
summary: ScanSummary
|
|
1882
|
+
): Promise<void> {
|
|
1883
|
+
await this.memory.set(
|
|
1884
|
+
`security:scan:${scanId}`,
|
|
1885
|
+
{
|
|
1886
|
+
scanId,
|
|
1887
|
+
scanType,
|
|
1888
|
+
vulnerabilities,
|
|
1889
|
+
summary,
|
|
1890
|
+
timestamp: new Date().toISOString(),
|
|
1891
|
+
},
|
|
1892
|
+
{ namespace: 'security-compliance', ttl: 86400 * 7 } // 7 days
|
|
1893
|
+
);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
// ==========================================================================
|
|
1897
|
+
// Dependency Scanning Methods (OSV API)
|
|
1898
|
+
// ==========================================================================
|
|
1899
|
+
|
|
1900
|
+
/**
|
|
1901
|
+
* Scan npm dependencies for known vulnerabilities using OSV API
|
|
1902
|
+
*/
|
|
1903
|
+
async scanDependencies(
|
|
1904
|
+
dependencies: Record<string, string>
|
|
1905
|
+
): Promise<Result<DependencyScanResult>> {
|
|
1906
|
+
const scanId = uuidv4();
|
|
1907
|
+
const startTime = Date.now();
|
|
1908
|
+
|
|
1909
|
+
try {
|
|
1910
|
+
if (Object.keys(dependencies).length === 0) {
|
|
1911
|
+
return err(new Error('No dependencies provided for scanning'));
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
this.activeScans.set(scanId, 'running');
|
|
1915
|
+
|
|
1916
|
+
// Query OSV for vulnerabilities
|
|
1917
|
+
const osvVulns = await this.osvClient.scanNpmDependencies(dependencies);
|
|
1918
|
+
|
|
1919
|
+
// Convert OSV vulnerabilities to our format
|
|
1920
|
+
const vulnerabilities = this.convertOSVVulnerabilities(osvVulns);
|
|
1921
|
+
|
|
1922
|
+
const scanDurationMs = Date.now() - startTime;
|
|
1923
|
+
|
|
1924
|
+
// Calculate unique vulnerable packages
|
|
1925
|
+
const vulnerablePackageNames = new Set(
|
|
1926
|
+
osvVulns.map((v) => v.affectedPackage)
|
|
1927
|
+
);
|
|
1928
|
+
|
|
1929
|
+
// Calculate summary
|
|
1930
|
+
const summary = this.calculateSummary(
|
|
1931
|
+
vulnerabilities,
|
|
1932
|
+
Object.keys(dependencies).length,
|
|
1933
|
+
scanDurationMs
|
|
1934
|
+
);
|
|
1935
|
+
|
|
1936
|
+
// Store scan results
|
|
1937
|
+
await this.storeScanResults(scanId, 'dependency', vulnerabilities, summary);
|
|
1938
|
+
this.activeScans.set(scanId, 'completed');
|
|
1939
|
+
|
|
1940
|
+
return ok({
|
|
1941
|
+
scanId,
|
|
1942
|
+
vulnerabilities,
|
|
1943
|
+
packagesScanned: Object.keys(dependencies).length,
|
|
1944
|
+
vulnerablePackages: vulnerablePackageNames.size,
|
|
1945
|
+
summary,
|
|
1946
|
+
scanDurationMs,
|
|
1947
|
+
});
|
|
1948
|
+
} catch (error) {
|
|
1949
|
+
this.activeScans.set(scanId, 'failed');
|
|
1950
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
/**
|
|
1955
|
+
* Scan a package.json file for dependency vulnerabilities
|
|
1956
|
+
*/
|
|
1957
|
+
async scanPackageJson(packageJsonPath: string): Promise<Result<DependencyScanResult>> {
|
|
1958
|
+
try {
|
|
1959
|
+
const fs = await import('fs/promises');
|
|
1960
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
1961
|
+
const packageJson = JSON.parse(content);
|
|
1962
|
+
|
|
1963
|
+
// Combine all dependency types
|
|
1964
|
+
const allDependencies: Record<string, string> = {
|
|
1965
|
+
...(packageJson.dependencies || {}),
|
|
1966
|
+
...(packageJson.devDependencies || {}),
|
|
1967
|
+
...(packageJson.peerDependencies || {}),
|
|
1968
|
+
...(packageJson.optionalDependencies || {}),
|
|
1969
|
+
};
|
|
1970
|
+
|
|
1971
|
+
if (Object.keys(allDependencies).length === 0) {
|
|
1972
|
+
return err(new Error('No dependencies found in package.json'));
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
return this.scanDependencies(allDependencies);
|
|
1976
|
+
} catch (error) {
|
|
1977
|
+
if (error instanceof SyntaxError) {
|
|
1978
|
+
return err(new Error(`Invalid JSON in package.json: ${error.message}`));
|
|
1979
|
+
}
|
|
1980
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
/**
|
|
1985
|
+
* Convert OSV vulnerabilities to our internal format
|
|
1986
|
+
*/
|
|
1987
|
+
private convertOSVVulnerabilities(
|
|
1988
|
+
osvVulns: ParsedVulnerability[]
|
|
1989
|
+
): Vulnerability[] {
|
|
1990
|
+
return osvVulns.map((osv) => {
|
|
1991
|
+
const location: VulnerabilityLocation = {
|
|
1992
|
+
file: 'package.json',
|
|
1993
|
+
line: 1,
|
|
1994
|
+
column: 1,
|
|
1995
|
+
snippet: `"${osv.affectedPackage}": "..."`,
|
|
1996
|
+
};
|
|
1997
|
+
|
|
1998
|
+
const remediation: RemediationAdvice = {
|
|
1999
|
+
description: osv.fixedVersions.length > 0
|
|
2000
|
+
? `Update to version ${osv.fixedVersions[0]} or later`
|
|
2001
|
+
: 'No fixed version available; consider alternative packages',
|
|
2002
|
+
fixExample: osv.fixedVersions.length > 0
|
|
2003
|
+
? `npm install ${osv.affectedPackage}@${osv.fixedVersions[0]}`
|
|
2004
|
+
: undefined,
|
|
2005
|
+
estimatedEffort: 'minor',
|
|
2006
|
+
automatable: true,
|
|
2007
|
+
};
|
|
2008
|
+
|
|
2009
|
+
return {
|
|
2010
|
+
id: uuidv4(),
|
|
2011
|
+
cveId: osv.cveIds[0],
|
|
2012
|
+
title: `${osv.affectedPackage}: ${osv.summary.substring(0, 80)}`,
|
|
2013
|
+
description: osv.details || osv.summary,
|
|
2014
|
+
severity: this.mapOSVSeverity(osv.severity),
|
|
2015
|
+
category: 'dependencies' as VulnerabilityCategory,
|
|
2016
|
+
location,
|
|
2017
|
+
remediation,
|
|
2018
|
+
references: osv.references.slice(0, 5),
|
|
2019
|
+
};
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
/**
|
|
2024
|
+
* Map OSV severity to our severity type
|
|
2025
|
+
*/
|
|
2026
|
+
private mapOSVSeverity(
|
|
2027
|
+
osvSeverity: ParsedVulnerability['severity']
|
|
2028
|
+
): VulnerabilitySeverity {
|
|
2029
|
+
const mapping: Record<ParsedVulnerability['severity'], VulnerabilitySeverity> = {
|
|
2030
|
+
critical: 'critical',
|
|
2031
|
+
high: 'high',
|
|
2032
|
+
medium: 'medium',
|
|
2033
|
+
low: 'low',
|
|
2034
|
+
unknown: 'medium',
|
|
2035
|
+
};
|
|
2036
|
+
return mapping[osvSeverity];
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
// ============================================================
|
|
2040
|
+
// ENHANCED DAST METHODS
|
|
2041
|
+
// ============================================================
|
|
2042
|
+
|
|
2043
|
+
/**
|
|
2044
|
+
* Extract links from HTML and crawl discovered pages
|
|
2045
|
+
* Implements basic web crawling within same origin
|
|
2046
|
+
*/
|
|
2047
|
+
private async extractAndCrawlLinks(
|
|
2048
|
+
html: string,
|
|
2049
|
+
baseUrl: URL,
|
|
2050
|
+
currentCrawled: number,
|
|
2051
|
+
maxDepth: number,
|
|
2052
|
+
vulnerabilities: Vulnerability[]
|
|
2053
|
+
): Promise<number> {
|
|
2054
|
+
let crawledUrls = currentCrawled;
|
|
2055
|
+
const maxCrawl = maxDepth * 5; // Allow more pages based on depth
|
|
2056
|
+
|
|
2057
|
+
// Extract links from HTML using regex (no DOM parser needed)
|
|
2058
|
+
const linkPattern = /href=["']([^"']+)["']/gi;
|
|
2059
|
+
const discoveredLinks = new Set<string>();
|
|
2060
|
+
let match;
|
|
2061
|
+
|
|
2062
|
+
while ((match = linkPattern.exec(html)) !== null) {
|
|
2063
|
+
const href = match[1];
|
|
2064
|
+
// Only follow same-origin links
|
|
2065
|
+
try {
|
|
2066
|
+
const linkUrl = new URL(href, baseUrl.origin);
|
|
2067
|
+
if (linkUrl.origin === baseUrl.origin && !discoveredLinks.has(linkUrl.pathname)) {
|
|
2068
|
+
discoveredLinks.add(linkUrl.pathname);
|
|
2069
|
+
}
|
|
2070
|
+
} catch {
|
|
2071
|
+
// Invalid URL - skip
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
// Crawl discovered links (limited)
|
|
2076
|
+
const linksToCrawl = Array.from(discoveredLinks).slice(0, Math.min(10, maxCrawl - crawledUrls));
|
|
2077
|
+
|
|
2078
|
+
for (const path of linksToCrawl) {
|
|
2079
|
+
if (crawledUrls >= maxCrawl) break;
|
|
2080
|
+
|
|
2081
|
+
try {
|
|
2082
|
+
const crawlUrl = new URL(path, baseUrl.origin).toString();
|
|
2083
|
+
const crawlResponse = await fetch(crawlUrl, {
|
|
2084
|
+
method: 'GET',
|
|
2085
|
+
headers: { 'User-Agent': 'AgenticQE-DAST-Scanner/3.0' },
|
|
2086
|
+
signal: AbortSignal.timeout(5000),
|
|
2087
|
+
redirect: 'follow',
|
|
2088
|
+
});
|
|
2089
|
+
|
|
2090
|
+
crawledUrls++;
|
|
2091
|
+
|
|
2092
|
+
// Check for security issues on crawled pages
|
|
2093
|
+
if (crawlResponse.ok) {
|
|
2094
|
+
// Check for sensitive data exposure in URLs
|
|
2095
|
+
if (path.includes('password') || path.includes('token') || path.includes('api_key')) {
|
|
2096
|
+
vulnerabilities.push({
|
|
2097
|
+
id: uuidv4(),
|
|
2098
|
+
title: 'Sensitive Data in URL Path',
|
|
2099
|
+
description: `URL path may contain sensitive parameter names: ${path}`,
|
|
2100
|
+
severity: 'medium',
|
|
2101
|
+
category: 'sensitive-data',
|
|
2102
|
+
location: { file: crawlUrl },
|
|
2103
|
+
remediation: { description: 'Avoid sensitive data in URL paths', estimatedEffort: 'minor', automatable: false },
|
|
2104
|
+
references: ['https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url'],
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
// Check for directory listing
|
|
2109
|
+
const responseText = await crawlResponse.text();
|
|
2110
|
+
if (responseText.includes('Index of /') || responseText.includes('Directory listing for')) {
|
|
2111
|
+
vulnerabilities.push({
|
|
2112
|
+
id: uuidv4(),
|
|
2113
|
+
title: 'Directory Listing Enabled',
|
|
2114
|
+
description: `Directory listing is enabled at: ${crawlUrl}`,
|
|
2115
|
+
severity: 'medium',
|
|
2116
|
+
category: 'security-misconfiguration',
|
|
2117
|
+
location: { file: crawlUrl },
|
|
2118
|
+
remediation: { description: 'Disable directory listing in server configuration', estimatedEffort: 'trivial', automatable: true },
|
|
2119
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
} catch {
|
|
2124
|
+
// Page not accessible - expected for some links
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
return crawledUrls;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
/**
|
|
2132
|
+
* Test URL parameters for injection vulnerabilities (XSS, SQLi)
|
|
2133
|
+
* Uses safe payloads that reveal vulnerability without exploitation
|
|
2134
|
+
*/
|
|
2135
|
+
private async testInjectionVulnerabilities(
|
|
2136
|
+
targetUrl: string,
|
|
2137
|
+
parsedUrl: URL,
|
|
2138
|
+
vulnerabilities: Vulnerability[]
|
|
2139
|
+
): Promise<void> {
|
|
2140
|
+
const params = new URLSearchParams(parsedUrl.search);
|
|
2141
|
+
const paramNames = Array.from(params.keys());
|
|
2142
|
+
|
|
2143
|
+
// Safe test payloads that reveal vulnerability without harm
|
|
2144
|
+
const xssPayloads = [
|
|
2145
|
+
{ payload: '<script>alert(1)</script>', name: 'Basic XSS' },
|
|
2146
|
+
{ payload: '"><img src=x onerror=alert(1)>', name: 'Attribute Injection' },
|
|
2147
|
+
{ payload: "'-alert(1)-'", name: 'JavaScript Injection' },
|
|
2148
|
+
];
|
|
2149
|
+
|
|
2150
|
+
const sqliPayloads = [
|
|
2151
|
+
{ payload: "' OR '1'='1", name: 'SQL OR Injection' },
|
|
2152
|
+
{ payload: "1; DROP TABLE test--", name: 'SQL Statement Injection' },
|
|
2153
|
+
{ payload: "1' AND '1'='1", name: 'SQL AND Injection' },
|
|
2154
|
+
];
|
|
2155
|
+
|
|
2156
|
+
// Test each parameter with injection payloads
|
|
2157
|
+
for (const paramName of paramNames.slice(0, 3)) { // Limit to first 3 params
|
|
2158
|
+
// Test XSS
|
|
2159
|
+
for (const xss of xssPayloads) {
|
|
2160
|
+
try {
|
|
2161
|
+
const testParams = new URLSearchParams(parsedUrl.search);
|
|
2162
|
+
testParams.set(paramName, xss.payload);
|
|
2163
|
+
const testUrl = `${parsedUrl.origin}${parsedUrl.pathname}?${testParams.toString()}`;
|
|
2164
|
+
|
|
2165
|
+
const response = await fetch(testUrl, {
|
|
2166
|
+
method: 'GET',
|
|
2167
|
+
headers: { 'User-Agent': 'AgenticQE-DAST-Scanner/3.0' },
|
|
2168
|
+
signal: AbortSignal.timeout(5000),
|
|
2169
|
+
});
|
|
2170
|
+
|
|
2171
|
+
if (response.ok) {
|
|
2172
|
+
const text = await response.text();
|
|
2173
|
+
const escapedPayload = xss.payload
|
|
2174
|
+
.replace(/&/g, '&')
|
|
2175
|
+
.replace(/</g, '<')
|
|
2176
|
+
.replace(/>/g, '>')
|
|
2177
|
+
.replace(/"/g, '"')
|
|
2178
|
+
.replace(/'/g, ''');
|
|
2179
|
+
|
|
2180
|
+
// Check for XSS vulnerability:
|
|
2181
|
+
// 1. Payload reflected unescaped (definite XSS)
|
|
2182
|
+
// 2. Payload partially escaped but critical chars remain (potential bypass)
|
|
2183
|
+
const hasUnescapedPayload = text.includes(xss.payload);
|
|
2184
|
+
const hasEscapedPayload = text.includes(escapedPayload);
|
|
2185
|
+
|
|
2186
|
+
// Only flag if payload is reflected AND it's unescaped
|
|
2187
|
+
if (hasUnescapedPayload && !hasEscapedPayload) {
|
|
2188
|
+
vulnerabilities.push({
|
|
2189
|
+
id: uuidv4(),
|
|
2190
|
+
title: `Reflected XSS: ${xss.name}`,
|
|
2191
|
+
description: `Parameter '${paramName}' reflects unsanitized input - payload executed without encoding`,
|
|
2192
|
+
severity: 'critical',
|
|
2193
|
+
category: 'xss',
|
|
2194
|
+
location: { file: targetUrl, snippet: `Parameter: ${paramName}, Payload: ${xss.payload.substring(0, 30)}...` },
|
|
2195
|
+
remediation: { description: 'HTML-encode all user input before rendering. Use framework auto-escaping.', estimatedEffort: 'moderate', automatable: false },
|
|
2196
|
+
references: ['https://owasp.org/www-community/attacks/xss/', 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html'],
|
|
2197
|
+
});
|
|
2198
|
+
break; // One XSS finding per parameter is enough
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// Check for partial escaping (< escaped but not > or vice versa) - potential bypass
|
|
2202
|
+
const hasPartialEscape =
|
|
2203
|
+
(text.includes('<') && text.includes('>') && text.includes(xss.payload.replace(/</g, '<'))) ||
|
|
2204
|
+
(text.includes('<') && text.includes('>') && text.includes(xss.payload.replace(/>/g, '>')));
|
|
2205
|
+
|
|
2206
|
+
if (hasPartialEscape) {
|
|
2207
|
+
vulnerabilities.push({
|
|
2208
|
+
id: uuidv4(),
|
|
2209
|
+
title: `Potential XSS: Inconsistent Encoding`,
|
|
2210
|
+
description: `Parameter '${paramName}' has inconsistent HTML encoding - some characters escaped, others not`,
|
|
2211
|
+
severity: 'medium',
|
|
2212
|
+
category: 'xss',
|
|
2213
|
+
location: { file: targetUrl, snippet: `Parameter: ${paramName}` },
|
|
2214
|
+
remediation: { description: 'Use consistent HTML encoding for all special characters', estimatedEffort: 'minor', automatable: false },
|
|
2215
|
+
references: ['https://owasp.org/www-community/attacks/xss/'],
|
|
2216
|
+
});
|
|
2217
|
+
break;
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
} catch {
|
|
2221
|
+
// Request failed - target may be blocking
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// Test SQLi (look for error-based indicators)
|
|
2226
|
+
for (const sqli of sqliPayloads) {
|
|
2227
|
+
try {
|
|
2228
|
+
const testParams = new URLSearchParams(parsedUrl.search);
|
|
2229
|
+
testParams.set(paramName, sqli.payload);
|
|
2230
|
+
const testUrl = `${parsedUrl.origin}${parsedUrl.pathname}?${testParams.toString()}`;
|
|
2231
|
+
|
|
2232
|
+
const response = await fetch(testUrl, {
|
|
2233
|
+
method: 'GET',
|
|
2234
|
+
headers: { 'User-Agent': 'AgenticQE-DAST-Scanner/3.0' },
|
|
2235
|
+
signal: AbortSignal.timeout(5000),
|
|
2236
|
+
});
|
|
2237
|
+
|
|
2238
|
+
const text = await response.text();
|
|
2239
|
+
// Look for SQL error indicators
|
|
2240
|
+
const sqlErrorPatterns = [
|
|
2241
|
+
/SQL syntax.*MySQL/i,
|
|
2242
|
+
/Warning.*mysql/i,
|
|
2243
|
+
/PostgreSQL.*ERROR/i,
|
|
2244
|
+
/ORA-\d{5}/i,
|
|
2245
|
+
/SQLite.*error/i,
|
|
2246
|
+
/SQLITE_ERROR/i,
|
|
2247
|
+
/unclosed quotation mark/i,
|
|
2248
|
+
/quoted string not properly terminated/i,
|
|
2249
|
+
];
|
|
2250
|
+
|
|
2251
|
+
for (const pattern of sqlErrorPatterns) {
|
|
2252
|
+
if (pattern.test(text)) {
|
|
2253
|
+
vulnerabilities.push({
|
|
2254
|
+
id: uuidv4(),
|
|
2255
|
+
title: `SQL Injection: ${sqli.name}`,
|
|
2256
|
+
description: `Parameter '${paramName}' appears vulnerable to SQL injection - database error message exposed`,
|
|
2257
|
+
severity: 'critical',
|
|
2258
|
+
category: 'injection',
|
|
2259
|
+
location: { file: targetUrl, snippet: `Parameter: ${paramName}` },
|
|
2260
|
+
remediation: { description: 'Use parameterized queries or prepared statements', estimatedEffort: 'moderate', automatable: false },
|
|
2261
|
+
references: ['https://owasp.org/www-community/attacks/SQL_Injection'],
|
|
2262
|
+
});
|
|
2263
|
+
break;
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
} catch {
|
|
2267
|
+
// Request failed
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
/**
|
|
2274
|
+
* Analyze HTML forms for security issues
|
|
2275
|
+
* Checks for CSRF protection, autocomplete settings, and action targets
|
|
2276
|
+
*/
|
|
2277
|
+
private async analyzeFormsForSecurityIssues(
|
|
2278
|
+
html: string,
|
|
2279
|
+
baseUrl: string,
|
|
2280
|
+
vulnerabilities: Vulnerability[]
|
|
2281
|
+
): Promise<void> {
|
|
2282
|
+
// Extract forms using regex
|
|
2283
|
+
const formPattern = /<form[^>]*>([\s\S]*?)<\/form>/gi;
|
|
2284
|
+
let formMatch;
|
|
2285
|
+
let formIndex = 0;
|
|
2286
|
+
|
|
2287
|
+
while ((formMatch = formPattern.exec(html)) !== null && formIndex < 10) {
|
|
2288
|
+
formIndex++;
|
|
2289
|
+
const formHtml = formMatch[0];
|
|
2290
|
+
const formContent = formMatch[1];
|
|
2291
|
+
|
|
2292
|
+
// Check for CSRF token
|
|
2293
|
+
const hasCsrfToken =
|
|
2294
|
+
/name=["']?csrf/i.test(formContent) ||
|
|
2295
|
+
/name=["']?_token/i.test(formContent) ||
|
|
2296
|
+
/name=["']?authenticity_token/i.test(formContent) ||
|
|
2297
|
+
/name=["']?__RequestVerificationToken/i.test(formContent);
|
|
2298
|
+
|
|
2299
|
+
// Check form method
|
|
2300
|
+
const isPostForm = /method=["']?post/i.test(formHtml);
|
|
2301
|
+
|
|
2302
|
+
if (isPostForm && !hasCsrfToken) {
|
|
2303
|
+
vulnerabilities.push({
|
|
2304
|
+
id: uuidv4(),
|
|
2305
|
+
title: 'Missing CSRF Token',
|
|
2306
|
+
description: `POST form #${formIndex} does not appear to have CSRF protection`,
|
|
2307
|
+
severity: 'medium',
|
|
2308
|
+
category: 'broken-auth',
|
|
2309
|
+
location: { file: baseUrl, snippet: `Form #${formIndex}` },
|
|
2310
|
+
remediation: { description: 'Add CSRF token to all state-changing forms', estimatedEffort: 'minor', automatable: false },
|
|
2311
|
+
references: ['https://owasp.org/www-community/attacks/csrf'],
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
// Check for password fields without autocomplete=off
|
|
2316
|
+
if (/type=["']?password/i.test(formContent)) {
|
|
2317
|
+
const hasAutocompleteOff =
|
|
2318
|
+
/autocomplete=["']?(off|new-password)/i.test(formContent) ||
|
|
2319
|
+
/autocomplete=["']?(off|new-password)/i.test(formHtml);
|
|
2320
|
+
|
|
2321
|
+
if (!hasAutocompleteOff) {
|
|
2322
|
+
vulnerabilities.push({
|
|
2323
|
+
id: uuidv4(),
|
|
2324
|
+
title: 'Password Field Allows Autocomplete',
|
|
2325
|
+
description: `Form #${formIndex} has password field that may be cached by browser`,
|
|
2326
|
+
severity: 'low',
|
|
2327
|
+
category: 'sensitive-data',
|
|
2328
|
+
location: { file: baseUrl, snippet: `Form #${formIndex}` },
|
|
2329
|
+
remediation: { description: 'Add autocomplete="new-password" to password fields', estimatedEffort: 'trivial', automatable: true },
|
|
2330
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
2331
|
+
});
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
// Check for insecure form action
|
|
2336
|
+
const actionMatch = /action=["']?([^"'\s>]+)/i.exec(formHtml);
|
|
2337
|
+
if (actionMatch) {
|
|
2338
|
+
const action = actionMatch[1];
|
|
2339
|
+
if (action.startsWith('http://') && !action.includes('localhost') && !action.includes('127.0.0.1')) {
|
|
2340
|
+
vulnerabilities.push({
|
|
2341
|
+
id: uuidv4(),
|
|
2342
|
+
title: 'Form Submits to Insecure HTTP',
|
|
2343
|
+
description: `Form #${formIndex} submits data over insecure HTTP: ${action}`,
|
|
2344
|
+
severity: 'high',
|
|
2345
|
+
category: 'sensitive-data',
|
|
2346
|
+
location: { file: baseUrl, snippet: `Action: ${action}` },
|
|
2347
|
+
remediation: { description: 'Change form action to use HTTPS', estimatedEffort: 'trivial', automatable: true },
|
|
2348
|
+
references: ['https://owasp.org/www-project-web-security-testing-guide/'],
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
}
|