Custom Rules¶
Escape's built-in tests cover application and API vulnerabilities. Custom rules let you encode the security checks specific to your product: business-logic violations, internal naming conventions, deprecated routes, environment isolation: using a deterministic YAML DSL.
There are two flavors:
- API custom rules (
type: API) target REST and GraphQL APIs. They can seed requests, replay them through transformations, run matchers on the request and response, and extract values for re-injection. - WebApp custom rules (
type: WEBAPP) drive a real Playwright-controlled browser against your web application. They can perform browser actions (navigate, fill, click, complete TOTP / magic-link MFA), then assert against the rendered DOM, cookies, storage, and dialog popups.
What You Can Express on Each Surface¶
| Block | API (type: API) |
WebApp (type: WEBAPP) |
|---|---|---|
alert |
yes | yes |
seed |
REST, HTTP raw, curl | browser actions |
transform |
yes | no |
detect |
HTTP and schema data | browser state |
extractors |
transformed rules without seed |
no |
Where Custom Rules Run¶
Custom rules are attached to a scan through the Escape platform and then picked up by whichever scanner executes your scan. Which rules actually fire depends on three things:
-
The scan kind (DAST, AI Pentesting, ASM: and what target type it runs against: API vs WebApp).
-
The rule type you authored (
type: APIortype: WEBAPP). -
For API rules, the shape of the rule: rules are classified at runtime into one of three execution subtypes:
API rule shape Subtype Behavior Has seed:SEED Sends the seeded request, then runs detectHas transform:COMPLEX Replays mutated requests, then runs detectNeither (detector-only) FILTER_ONLY Matches passively on observed traffic
If an API rule has both seed: and transform:, the seeded path takes
precedence: transformations and extractors don't run. Extractors and
use_extraction variables work only in the COMPLEX path (transform:
without seed:). Extraction runs on the original exchange before mutation,
then on each replayed exchange before detection.
WebApp rules (type: WEBAPP) always run the same way: the browser
executes the seed: actions and then evaluates detect.
The matrix below summarises, per scan kind, which rule types and subtypes actually execute today.
| Scan kind | API custom rules | WebApp custom rules |
|---|---|---|
| DAST: API | Yes: SEED + FILTER_ONLY + COMPLEX | No |
| DAST: WebApp | Yes: SEED + FILTER_ONLY + COMPLEX | Yes |
| AI Pentesting: API | Yes: SEED + FILTER_ONLY + COMPLEX | No |
| AI Pentesting: WebApp | Yes: SEED + FILTER_ONLY + COMPLEX | Yes |
| ASM: API surface | Partial: SEED only | No |
| ASM: WebApp surface | Partial: SEED only | Yes |
| All other ASM kinds | No | No |
Custom asset discovery
Custom asset discovery from custom rules isn't supported today.
How a Rule Flows¶
flowchart LR
Author[YAML rule] --> Surface{type}
Surface -->|API: seeded| ApiSeed["seed -> detect -> alert"]
Surface -->|API: transformed| ApiPipeline["extract -> transform -> replay -> extract -> detect -> alert"]
Surface -->|API: detector-only| ApiFilter["observed traffic -> detect -> alert"]
Surface -->|WebApp| WebPipeline["seed (browser actions) -> detect -> alert"]
ApiPipeline --> Alert[Find vulnerability]
ApiSeed --> Alert
ApiFilter --> Alert
WebPipeline --> Alert
Where to Look Next¶
Reference, in the order you usually need it when authoring a rule:
- Seeders: inject requests (API) or drive the browser (WebApp).
- Mutators: replay matched API requests with field-level changes.
- Extractors: capture values from API responses for later re-injection.
- Detectors: match conditions on requests, responses, or the rendered page.
- Alerting: name, severity, context, category.
For real-world examples:
- Examples for APIs: every shipped API example, grouped by vulnerability.
- Examples for WebApps: every shipped WebApp example, grouped by vulnerability.
For the JSON Schema Custom Rules Reference (consumed by IDE tooling and the Escape platform).
Featured Examples¶
A short tour to get you started. Each link jumps to the full prose + YAML on the matching examples page.
API¶
- Anonymous mutation succeeded
- BOLA via user swap with fingerprint comparison
- Mass assignment via privileged JSON field injection
- Header reinjection with extractor