@vk.amogh/trace 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -0
- package/bin/trace.js +112 -0
- package/package.json +46 -0
- package/pyproject.toml +39 -0
- package/src/trace_engine/__init__.py +8 -0
- package/src/trace_engine/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/__pycache__/cli.cpython-311.pyc +0 -0
- package/src/trace_engine/__pycache__/doctor.cpython-311.pyc +0 -0
- package/src/trace_engine/__pycache__/interactive.cpython-311.pyc +0 -0
- package/src/trace_engine/__pycache__/verify.cpython-311.pyc +0 -0
- package/src/trace_engine/ai/__init__.py +7 -0
- package/src/trace_engine/ai/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/ai/__pycache__/base.cpython-311.pyc +0 -0
- package/src/trace_engine/ai/__pycache__/ollama.cpython-311.pyc +0 -0
- package/src/trace_engine/ai/__pycache__/planner.cpython-311.pyc +0 -0
- package/src/trace_engine/ai/base.py +23 -0
- package/src/trace_engine/ai/ollama.py +50 -0
- package/src/trace_engine/ai/planner.py +40 -0
- package/src/trace_engine/apm/__init__.py +18 -0
- package/src/trace_engine/apm/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/__pycache__/builder.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/__pycache__/edges.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/__pycache__/model.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/__pycache__/nodes.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/__pycache__/serialization.cpython-311.pyc +0 -0
- package/src/trace_engine/apm/builder.py +208 -0
- package/src/trace_engine/apm/edges.py +25 -0
- package/src/trace_engine/apm/model.py +107 -0
- package/src/trace_engine/apm/nodes.py +27 -0
- package/src/trace_engine/apm/serialization.py +105 -0
- package/src/trace_engine/benchmark/__init__.py +5 -0
- package/src/trace_engine/benchmark/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/benchmark/__pycache__/owasp.cpython-311.pyc +0 -0
- package/src/trace_engine/benchmark/owasp.py +183 -0
- package/src/trace_engine/cli.py +1184 -0
- package/src/trace_engine/config/__init__.py +35 -0
- package/src/trace_engine/config/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/config/__pycache__/defaults.cpython-311.pyc +0 -0
- package/src/trace_engine/config/__pycache__/loader.cpython-311.pyc +0 -0
- package/src/trace_engine/config/__pycache__/settings.cpython-311.pyc +0 -0
- package/src/trace_engine/config/defaults.py +48 -0
- package/src/trace_engine/config/loader.py +64 -0
- package/src/trace_engine/config/settings.py +72 -0
- package/src/trace_engine/doctor.py +250 -0
- package/src/trace_engine/findings/__init__.py +15 -0
- package/src/trace_engine/findings/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/findings/__pycache__/correlate.cpython-311.pyc +0 -0
- package/src/trace_engine/findings/__pycache__/model.cpython-311.pyc +0 -0
- package/src/trace_engine/findings/__pycache__/recommendations.cpython-311.pyc +0 -0
- package/src/trace_engine/findings/__pycache__/store.cpython-311.pyc +0 -0
- package/src/trace_engine/findings/correlate.py +103 -0
- package/src/trace_engine/findings/model.py +40 -0
- package/src/trace_engine/findings/recommendations.py +35 -0
- package/src/trace_engine/findings/store.py +39 -0
- package/src/trace_engine/framework/__init__.py +58 -0
- package/src/trace_engine/framework/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/base.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/csharp.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/dart.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/django.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/express.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/fastapi.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/flask.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/go.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/nextjs.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/php.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/react_router.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/ruby.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/rust.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/__pycache__/springboot.cpython-311.pyc +0 -0
- package/src/trace_engine/framework/base.py +49 -0
- package/src/trace_engine/framework/csharp.py +111 -0
- package/src/trace_engine/framework/dart.py +152 -0
- package/src/trace_engine/framework/django.py +188 -0
- package/src/trace_engine/framework/express.py +82 -0
- package/src/trace_engine/framework/fastapi.py +135 -0
- package/src/trace_engine/framework/flask.py +108 -0
- package/src/trace_engine/framework/go.py +94 -0
- package/src/trace_engine/framework/nextjs.py +200 -0
- package/src/trace_engine/framework/php.py +98 -0
- package/src/trace_engine/framework/react_router.py +331 -0
- package/src/trace_engine/framework/ruby.py +69 -0
- package/src/trace_engine/framework/rust.py +101 -0
- package/src/trace_engine/framework/springboot.py +145 -0
- package/src/trace_engine/harness/__init__.py +19 -0
- package/src/trace_engine/harness/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/__pycache__/benchmark.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/__pycache__/context.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/__pycache__/engine.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/__pycache__/patcher.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/__pycache__/remediators.cpython-311.pyc +0 -0
- package/src/trace_engine/harness/benchmark.py +55 -0
- package/src/trace_engine/harness/context.py +49 -0
- package/src/trace_engine/harness/engine.py +187 -0
- package/src/trace_engine/harness/patcher.py +143 -0
- package/src/trace_engine/harness/remediators.py +307 -0
- package/src/trace_engine/ingest/__init__.py +15 -0
- package/src/trace_engine/ingest/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/ingest/__pycache__/files.cpython-311.pyc +0 -0
- package/src/trace_engine/ingest/__pycache__/hashing.cpython-311.pyc +0 -0
- package/src/trace_engine/ingest/__pycache__/ignore.cpython-311.pyc +0 -0
- package/src/trace_engine/ingest/__pycache__/repository.cpython-311.pyc +0 -0
- package/src/trace_engine/ingest/files.py +60 -0
- package/src/trace_engine/ingest/hashing.py +21 -0
- package/src/trace_engine/ingest/ignore.py +108 -0
- package/src/trace_engine/ingest/repository.py +50 -0
- package/src/trace_engine/intelligence/__init__.py +15 -0
- package/src/trace_engine/intelligence/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/__pycache__/evaluation.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/__pycache__/orchestrator.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/__pycache__/tracebench.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/evaluation.py +828 -0
- package/src/trace_engine/intelligence/laya/__init__.py +19 -0
- package/src/trace_engine/intelligence/laya/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/__pycache__/prompts.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/__pycache__/router.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/__pycache__/schemas.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/__pycache__/telemetry.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/__pycache__/thresholds.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/laya/prompts.py +67 -0
- package/src/trace_engine/intelligence/laya/router.py +352 -0
- package/src/trace_engine/intelligence/laya/schemas.py +56 -0
- package/src/trace_engine/intelligence/laya/telemetry.py +48 -0
- package/src/trace_engine/intelligence/laya/thresholds.py +12 -0
- package/src/trace_engine/intelligence/orchestrator.py +130 -0
- package/src/trace_engine/intelligence/securebert/__init__.py +6 -0
- package/src/trace_engine/intelligence/securebert/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/securebert/__pycache__/cache.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/securebert/__pycache__/classifier.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/securebert/cache.py +37 -0
- package/src/trace_engine/intelligence/securebert/classifier.py +240 -0
- package/src/trace_engine/intelligence/tracebench.py +61 -0
- package/src/trace_engine/intelligence/training/__init__.py +21 -0
- package/src/trace_engine/intelligence/training/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/dataset.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/dataset_importers.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/laya_trainer.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/lora_system2.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/morefixes_pipeline.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/slicer.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/train_all.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/__pycache__/trainer.cpython-311.pyc +0 -0
- package/src/trace_engine/intelligence/training/dataset.py +320 -0
- package/src/trace_engine/intelligence/training/dataset_importers.py +349 -0
- package/src/trace_engine/intelligence/training/laya_trainer.py +678 -0
- package/src/trace_engine/intelligence/training/lora_system2.py +162 -0
- package/src/trace_engine/intelligence/training/morefixes_pipeline.py +463 -0
- package/src/trace_engine/intelligence/training/slicer.py +129 -0
- package/src/trace_engine/intelligence/training/train_all.py +1009 -0
- package/src/trace_engine/intelligence/training/trainer.py +321 -0
- package/src/trace_engine/interactive.py +623 -0
- package/src/trace_engine/mcp/__init__.py +6 -0
- package/src/trace_engine/mcp/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/mcp/__pycache__/config.cpython-311.pyc +0 -0
- package/src/trace_engine/mcp/__pycache__/server.cpython-311.pyc +0 -0
- package/src/trace_engine/mcp/config.py +42 -0
- package/src/trace_engine/mcp/server.py +398 -0
- package/src/trace_engine/output/__init__.py +28 -0
- package/src/trace_engine/output/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/output/__pycache__/html.cpython-311.pyc +0 -0
- package/src/trace_engine/output/__pycache__/markdown.cpython-311.pyc +0 -0
- package/src/trace_engine/output/__pycache__/sarif.cpython-311.pyc +0 -0
- package/src/trace_engine/output/__pycache__/terminal.cpython-311.pyc +0 -0
- package/src/trace_engine/output/html.py +142 -0
- package/src/trace_engine/output/markdown.py +65 -0
- package/src/trace_engine/output/sarif.py +180 -0
- package/src/trace_engine/output/terminal.py +537 -0
- package/src/trace_engine/parsing/__init__.py +26 -0
- package/src/trace_engine/parsing/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/__pycache__/calls.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/__pycache__/language.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/__pycache__/locations.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/__pycache__/parser.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/__pycache__/symbols.cpython-311.pyc +0 -0
- package/src/trace_engine/parsing/calls.py +14 -0
- package/src/trace_engine/parsing/language.py +24 -0
- package/src/trace_engine/parsing/locations.py +17 -0
- package/src/trace_engine/parsing/parser.py +465 -0
- package/src/trace_engine/parsing/symbols.py +45 -0
- package/src/trace_engine/plugin/__init__.py +157 -0
- package/src/trace_engine/plugin/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/plugin/__pycache__/evaluator.cpython-311.pyc +0 -0
- package/src/trace_engine/plugin/__pycache__/swebench_adapter.cpython-311.pyc +0 -0
- package/src/trace_engine/plugin/__pycache__/task.cpython-311.pyc +0 -0
- package/src/trace_engine/plugin/bundle/hooks.json +24 -0
- package/src/trace_engine/plugin/bundle/mcp_config.json +11 -0
- package/src/trace_engine/plugin/bundle/plugin.json +20 -0
- package/src/trace_engine/plugin/bundle/rules/security_remediation.md +40 -0
- package/src/trace_engine/plugin/bundle/skills/trace-security-harness/SKILL.md +118 -0
- package/src/trace_engine/plugin/evaluator.py +105 -0
- package/src/trace_engine/plugin/swebench_adapter.py +96 -0
- package/src/trace_engine/plugin/task.py +48 -0
- package/src/trace_engine/policy/__init__.py +5 -0
- package/src/trace_engine/policy/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/policy/__pycache__/scope.cpython-311.pyc +0 -0
- package/src/trace_engine/policy/scope.py +80 -0
- package/src/trace_engine/runtime/__init__.py +7 -0
- package/src/trace_engine/runtime/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/runtime/__pycache__/client.cpython-311.pyc +0 -0
- package/src/trace_engine/runtime/__pycache__/observations.cpython-311.pyc +0 -0
- package/src/trace_engine/runtime/__pycache__/target.cpython-311.pyc +0 -0
- package/src/trace_engine/runtime/client.py +81 -0
- package/src/trace_engine/runtime/observations.py +18 -0
- package/src/trace_engine/runtime/target.py +23 -0
- package/src/trace_engine/security/__init__.py +16 -0
- package/src/trace_engine/security/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/security/__pycache__/fusion.cpython-311.pyc +0 -0
- package/src/trace_engine/security/__pycache__/hypotheses.cpython-311.pyc +0 -0
- package/src/trace_engine/security/__pycache__/signals.cpython-311.pyc +0 -0
- package/src/trace_engine/security/__pycache__/timing.cpython-311.pyc +0 -0
- package/src/trace_engine/security/fusion.py +126 -0
- package/src/trace_engine/security/hypotheses.py +251 -0
- package/src/trace_engine/security/signals.py +28 -0
- package/src/trace_engine/security/timing.py +132 -0
- package/src/trace_engine/testpacks/__init__.py +18 -0
- package/src/trace_engine/testpacks/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/authentication.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/base.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/bfla.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/bola.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/cors.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/deserialization.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/injection.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/mass_assignment.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/path_traversal.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/registry.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/ssrf.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/__pycache__/ssti.cpython-311.pyc +0 -0
- package/src/trace_engine/testpacks/authentication.py +60 -0
- package/src/trace_engine/testpacks/base.py +63 -0
- package/src/trace_engine/testpacks/bfla.py +70 -0
- package/src/trace_engine/testpacks/bola.py +94 -0
- package/src/trace_engine/testpacks/cors.py +85 -0
- package/src/trace_engine/testpacks/deserialization.py +86 -0
- package/src/trace_engine/testpacks/injection.py +179 -0
- package/src/trace_engine/testpacks/mass_assignment.py +70 -0
- package/src/trace_engine/testpacks/path_traversal.py +117 -0
- package/src/trace_engine/testpacks/registry.py +44 -0
- package/src/trace_engine/testpacks/ssrf.py +85 -0
- package/src/trace_engine/testpacks/ssti.py +96 -0
- package/src/trace_engine/tools/__init__.py +6 -0
- package/src/trace_engine/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/trace_engine/tools/__pycache__/adapters.cpython-311.pyc +0 -0
- package/src/trace_engine/tools/__pycache__/base.cpython-311.pyc +0 -0
- package/src/trace_engine/tools/__pycache__/registry.cpython-311.pyc +0 -0
- package/src/trace_engine/tools/adapters.py +111 -0
- package/src/trace_engine/tools/base.py +68 -0
- package/src/trace_engine/tools/registry.py +36 -0
- package/src/trace_engine/verify.py +156 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""TRACE Verification Engine (Section 58) for validating remediations by coding agents."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from trace_engine.findings.store import FindingStore
|
|
9
|
+
from trace_engine.findings.model import Finding
|
|
10
|
+
from trace_engine.ingest.repository import RepositoryScanner
|
|
11
|
+
from trace_engine.parsing.parser import CodeParser
|
|
12
|
+
from trace_engine.framework import get_adapters
|
|
13
|
+
from trace_engine.apm.builder import APMBuilder
|
|
14
|
+
from trace_engine.policy.scope import ScopeGuard
|
|
15
|
+
from trace_engine.runtime.client import ScopedHttpClient
|
|
16
|
+
from trace_engine.testpacks.registry import default_registry
|
|
17
|
+
from trace_engine.testpacks.base import TestContext
|
|
18
|
+
from trace_engine.security.hypotheses import HypothesisEngine
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class VerificationStatus(str, Enum):
|
|
22
|
+
FIXED = "FIXED"
|
|
23
|
+
STILL_PRESENT = "STILL_PRESENT"
|
|
24
|
+
INCONCLUSIVE = "INCONCLUSIVE"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VerificationResult(BaseModel):
|
|
28
|
+
finding_id: str
|
|
29
|
+
endpoint: str
|
|
30
|
+
status: VerificationStatus
|
|
31
|
+
summary: str
|
|
32
|
+
static_signals_after: List[str] = Field(default_factory=list)
|
|
33
|
+
runtime_status_after: Optional[int] = None
|
|
34
|
+
differential_analysis: str
|
|
35
|
+
remediation_verified: bool
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class VerificationEngine:
|
|
39
|
+
"""Verifies whether a source code modification actually resolved a finding."""
|
|
40
|
+
|
|
41
|
+
def __init__(self, repo_path: Path, target_url: str = "http://127.0.0.1:18080"):
|
|
42
|
+
self.repo_path = repo_path.resolve()
|
|
43
|
+
self.target_url = target_url
|
|
44
|
+
|
|
45
|
+
def verify(self, finding_id: str) -> VerificationResult:
|
|
46
|
+
store = FindingStore(self.repo_path / ".trace")
|
|
47
|
+
finding = store.get_finding_by_id(finding_id)
|
|
48
|
+
if not finding:
|
|
49
|
+
return VerificationResult(
|
|
50
|
+
finding_id=finding_id,
|
|
51
|
+
endpoint="unknown",
|
|
52
|
+
status=VerificationStatus.INCONCLUSIVE,
|
|
53
|
+
summary=f"Finding '{finding_id}' not found in .trace/findings.json",
|
|
54
|
+
differential_analysis="Cannot verify non-existent finding.",
|
|
55
|
+
remediation_verified=False,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# 1. Re-index and parse
|
|
59
|
+
scanner = RepositoryScanner(self.repo_path)
|
|
60
|
+
source_files = scanner.scan()
|
|
61
|
+
parser = CodeParser()
|
|
62
|
+
adapters = get_adapters()
|
|
63
|
+
|
|
64
|
+
parsed_files = []
|
|
65
|
+
discovered_endpoints = []
|
|
66
|
+
for sf in source_files:
|
|
67
|
+
content = Path(sf.absolute_path).read_text(encoding="utf-8", errors="replace")
|
|
68
|
+
pf = parser.parse(sf.path, content, sf.language, absolute_path=sf.absolute_path)
|
|
69
|
+
parsed_files.append(pf)
|
|
70
|
+
for adapter in adapters:
|
|
71
|
+
if adapter.can_handle(pf):
|
|
72
|
+
discovered_endpoints.extend(adapter.extract_endpoints(pf, content))
|
|
73
|
+
|
|
74
|
+
# 2. Re-build APM
|
|
75
|
+
builder = APMBuilder(project_name=self.repo_path.name)
|
|
76
|
+
apm = builder.build(self.repo_path, source_files, parsed_files, discovered_endpoints)
|
|
77
|
+
|
|
78
|
+
# 3. Re-evaluate hypotheses
|
|
79
|
+
engine = HypothesisEngine()
|
|
80
|
+
new_hypotheses = engine.derive_hypotheses(apm, discovered_endpoints)
|
|
81
|
+
|
|
82
|
+
# Check if the specific hypothesis still triggers statically
|
|
83
|
+
hyp_still_present = any(
|
|
84
|
+
h.category.value == finding.category and h.endpoint_display == finding.endpoint
|
|
85
|
+
for h in new_hypotheses
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# 4. Replay test pack against runtime
|
|
89
|
+
scope_guard = ScopeGuard()
|
|
90
|
+
scope_guard.allow_target(self.target_url)
|
|
91
|
+
client = ScopedHttpClient(scope_guard=scope_guard)
|
|
92
|
+
context = TestContext(
|
|
93
|
+
target_base_url=self.target_url,
|
|
94
|
+
active_tokens={"user-a": "user-a", "user-b": "user-b", "admin": "admin"},
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
pack = default_registry.get(finding.category.lower())
|
|
98
|
+
runtime_confirmed = False
|
|
99
|
+
runtime_status = None
|
|
100
|
+
test_summary = "Test pack could not run."
|
|
101
|
+
|
|
102
|
+
if pack:
|
|
103
|
+
# Create a synthetic hypothesis from finding to re-test
|
|
104
|
+
from trace_engine.security.hypotheses import SecurityHypothesis, VulnerabilityCategory
|
|
105
|
+
cat_enum = getattr(VulnerabilityCategory, finding.category.upper(), VulnerabilityCategory.BOLA)
|
|
106
|
+
dummy_hyp = SecurityHypothesis(
|
|
107
|
+
id=finding.id.replace("TR-", "HYP-"),
|
|
108
|
+
category=cat_enum,
|
|
109
|
+
endpoint_id="verify_ep",
|
|
110
|
+
endpoint_display=finding.endpoint,
|
|
111
|
+
title=finding.title,
|
|
112
|
+
description=finding.title,
|
|
113
|
+
recommended_test_pack=finding.category.lower(),
|
|
114
|
+
)
|
|
115
|
+
try:
|
|
116
|
+
res = pack.execute(dummy_hyp, client, context)
|
|
117
|
+
runtime_confirmed = res.confirmed
|
|
118
|
+
test_summary = res.summary
|
|
119
|
+
if res.observations:
|
|
120
|
+
runtime_status = res.observations[0].response_status
|
|
121
|
+
except Exception as e:
|
|
122
|
+
return VerificationResult(
|
|
123
|
+
finding_id=finding_id,
|
|
124
|
+
endpoint=finding.endpoint,
|
|
125
|
+
status=VerificationStatus.INCONCLUSIVE,
|
|
126
|
+
summary=f"Runtime target connection failed: {e}",
|
|
127
|
+
differential_analysis="Target unreachable during verification probe.",
|
|
128
|
+
remediation_verified=False,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# 5. Formulate verification status
|
|
132
|
+
if not runtime_confirmed:
|
|
133
|
+
status = VerificationStatus.FIXED
|
|
134
|
+
differential = (
|
|
135
|
+
f"Remediation confirmed: Runtime test no longer reproduces exploit. "
|
|
136
|
+
f"Observation summary: {test_summary}."
|
|
137
|
+
)
|
|
138
|
+
remediation_ok = True
|
|
139
|
+
else:
|
|
140
|
+
status = VerificationStatus.STILL_PRESENT
|
|
141
|
+
differential = (
|
|
142
|
+
f"Remediation incomplete: Exploit still succeeds at runtime. "
|
|
143
|
+
f"Observation summary: {test_summary}."
|
|
144
|
+
)
|
|
145
|
+
remediation_ok = False
|
|
146
|
+
|
|
147
|
+
return VerificationResult(
|
|
148
|
+
finding_id=finding_id,
|
|
149
|
+
endpoint=finding.endpoint,
|
|
150
|
+
status=status,
|
|
151
|
+
summary=test_summary,
|
|
152
|
+
static_signals_after=[h.title for h in new_hypotheses if h.endpoint_display == finding.endpoint],
|
|
153
|
+
runtime_status_after=runtime_status,
|
|
154
|
+
differential_analysis=differential,
|
|
155
|
+
remediation_verified=remediation_ok,
|
|
156
|
+
)
|