Skip to main content

Vulnerability Chaining & Choke Points

๐Ÿ” Enterprise Tier ยท Cross-rule attack-path composition

Individual findings rarely tell the whole story. SquireX's chaining engine (ComposeChains) composes multiple graph-anchored findings into a single attack path, escalates its severity, and names the one node that โ€” if remediated โ€” breaks the most chains: the choke point.

This is the difference between "here are 12 medium findings" and "these 3 findings form one critical, reachable path โ€” fix this one node to collapse it."


How a chain is composedโ€‹

A set of findings is promoted to a chain only when all gates pass โ€” chains are never speculative:

  1. Graph-anchored โ€” every constituent finding is anchored to a Semantic Graph node (Violation.nodeId).
  2. Reachable โ€” a path exists from an attacker-controllable agent entry point to a sink (reachability-gated BFS).
  3. Crosses a trust boundary โ€” the path traverses โ‰ฅ1 trust-boundary edge (e.g. agent โ†’ tool, agent โ†’ external callout). Findings that never cross a boundary are not chained.

If any gate fails (unreachable, or no trust-boundary crossing), the findings remain standalone โ€” no false attack path.

Severity escalationโ€‹

A reachable, boundary-crossing chain is more dangerous than its parts. Severity escalates one level per additional constituent, capped at critical:

Constituent findingsComposed severity
3 ร— medium on one reachable pathcritical
2 ร— mediumhigh
2 ร— lowmedium

Escalation is deterministic โ€” the same graph always produces the same chain and severity.

The choke pointโ€‹

For every chain, the engine computes a global choke-point frequency: the anchored node that appears across the most chains. Remediating the choke point collapses the largest number of attack paths for the least work โ€” SquireX surfaces it explicitly so you fix the root, not the symptoms.

graph LR
ENTRY["Agent entry\n(attacker-reachable)"]
A["Finding A\n(medium)"]
CHOKE["โ›” Choke point\n(shared node)"]
B["Finding B\n(medium)"]
SINK["Sink\n(external callout / DML)"]

ENTRY --> A --> CHOKE
CHOKE --> B --> SINK
CHOKE -.->|"breaks the most chains if fixed"| CHOKE

In the SARIF outputโ€‹

Each constituent finding is kept as its own result (nothing is hidden), and a synthesized chain result is added with:

  • relatedLocations โ€” every constituent finding's location, so the path is navigable in GitHub Advanced Security and the VS Code viewer
  • properties.chain โ€” the ordered node path
  • properties.chokePoint โ€” the node to remediate first
  • properties.constituentRuleIds โ€” the rule IDs that composed the chain

The CI-Native Agent reads chokePoint to target the highest-leverage fix first. See SARIF Output.


Why it mattersโ€‹

This is the paid differentiator: SquireX doesn't just list issues, it reasons about how they combine into a reachable, trust-boundary-crossing exploit โ€” and tells you the single highest-leverage place to break it.