Security Testing
A Security Test Case turns one template request into a batch of attack instances — each a fully materialized, mutated request with its own verdict assertion. Running the case sends every attack and scores the responses against deterministic vulnerability signals, producing a findings report grouped by attack category and severity.
Security testing is an Enterprise feature. Creating, reconfiguring, and running a security test case require an Enterprise license; otherwise Aethrix shows "Security testing requires an Enterprise license." Loading and viewing an existing scan is always allowed. In a developer build the license gate is relaxed to a reminder.
When to Use
- Scanning an HTTP API (or any HTTP message shape) for injection, tampering, authorization, and misconfiguration classes before release
- Verifying that a newly added validation layer actually rejects malformed input
- Generating a reproducible security regression suite that runs in CI alongside your functional tests
The engine is deterministic and AI-free: the same template and scan profile produce the same attack instances (only GUIDs differ), so results are stable across CI runs until you explicitly regenerate.
How It Differs from a Manual Test
Your normal test case uses the object model: fields keep their declared types and the serializer produces a valid request. Security testing deliberately breaks that contract — a string is injected into an int, int.MaxValue + 1 is written past a type limit, a JSON body is truncated. Those values cannot exist in the typed object model.
For that reason every generated attack is stored as a fully materialized HTTP frame and sent verbatim (raw-frame path), with no deserialize → re-serialize round-trip. What is saved is exactly what goes on the wire.
Creating a Security Test Case
Security test cases follow the same insert, then configure flow as other automation items.
- From a test suite — right-click the suite in the project tree and choose Add Security Test Case.... This inserts an empty security test case and selects it. The case panel then shows a highlighted Configure... button.
- From a Send Request step — right-click a plain (non-security) Send Request step and choose Create Security Test Case.... The wizard opens pre-filled from that step's URL, request text, and operation.
Empty case, no wizard: Add Security Test Case... intentionally does not open the wizard. You configure it from the panel (see Reviewing a Security Scan).
The Wizard
Open the wizard with Configure... (empty case), Reconfigure... (existing case), or Create Security Test Case... (from a step). It has three steps, or four when you enable a stateful-chain category (see Stateful Attack Chains).
Step 1 — Template request
The unmutated baseline that every attack instance is derived from. It is edited with the embedded request editor: pick an imported operation with the editor's Select service button, or edit the request directly. No service definition is required — the generic HTTP mode accepts any verb, URL, headers, and body.
Next is enabled once the request text is present and either an operation is bound or a URL is set.
Step 2 — Attack dimensions
Choose which attack dimensions to generate. They are grouped into two lists:
- Object-model (body fields) — mutate discovered body fields (the editor's object model is used to discover fields when an operation is bound; otherwise fields are read from the request body text).
- Message-level (verb / URL / headers / body) — tamper with the request frame.
| Group | Dimensions |
|---|---|
| Object-model (body fields) | SQL Injection, XSS Injection, Path Traversal, Boundary Overflow, Type Mismatch, Null / Empty, Format Violation, Enum Confusion, XXE Injection, Oversized Payload, SSRF (Server-Side Request Forgery) |
| Message-level (verb / URL / headers / body) | Auth Removal, Auth Tampering, HTTP Verb Tampering, Content-Type Confusion, Header Injection, URL Path Manipulation, CRLF Injection, Malformed Body, Cookie Tampering, JWT Attack, CORS Misconfiguration, GraphQL Abuse, Mass Assignment, Broken Authorization (BOLA/BFLA), Rate Limit Probe, Stored XSS (Stateful Chain), Business Flow Abuse (Replay) |
A sensible default set is pre-checked. XXE, Oversized Payload, CRLF, Cookie Tampering, and the newer dimensions are off by default to limit noisy or high-risk scans.
Two limits control the batch size:
| Limit | Description | Default |
|---|---|---|
| Max vectors per field | Maximum attack vectors generated per field, per dimension | 10 |
| Max instances per category | Global cap on instances generated for one dimension | 100 |
Next is enabled once at least one dimension is checked.
Step 3 — Attack Chains (only when a chain category is enabled)
Appears only when Stored XSS (Stateful Chain) or Business Flow Abuse (Replay) is selected. Leave the chain list empty for fully automatic behavior, or add explicit chains. See Stateful Attack Chains.
Final step — Review & generate
The review step shows the mode (create or reconfigure), the number of fields discovered in the template body, the number of enabled dimensions, and the configured chains. Click Generate to build the case and materialize every attack instance.
What Gets Created
The wizard fills the security test case. Attack instances are not shown as tree children — the tree keeps the case node only, and the case panel is the surface for the instances (see Reviewing a Security Scan).
- The first step is the template (baseline).
- Every following step is one fully materialized attack instance with its own Security Verdict assertion. Instances are read-only: they cannot be renamed, duplicated, or deleted individually.
A discreet badge on the case shows how many attack instances it contains.
Running & Verdicts
When a security test case runs, the baseline template runs first.
- If the unmutated request fails, the API is not in a usable state: every attack instance is marked BaselineFailed and the case fails with an explanatory message. Nothing is reported as "secure" in that situation.
- Otherwise every attack instance runs. Each is scored by its Security Verdict assertion through multiple deterministic signals:
| Signal | Meaning |
|---|---|
| Crash / unhandled error status | HTTP 500/502/503 → vulnerable |
| Sensitive information leak | Response matches sensitive patterns (SQL errors, exception types, file content, cloud metadata, CORS echo, sensitive field names, GraphQL introspection) |
| Payload reflection | Attack payload echoed back unescaped (XSS / stored echo) |
| Undeclared field echo | A 2xx response echoes an injected mass-assignment field name → vulnerable |
| Time-based blind injection | Response time exceeds the threshold when a sleep payload was used |
| Rejection status | Attack properly rejected (per-category rejection codes, e.g. 400/401/403/405/415/422) |
| Category rules | e.g. a 2xx response to removed/tampered auth, to an unexpected HTTP verb, or a replayed business request → vulnerable |
Server banners, stack traces, database versions, and debug flags are configuration fingerprints: they are surfaced as NeedsReview, never as vulnerabilities, and they never mask a real finding (a response that also reflects a payload is still Vulnerable).
Each instance ends in one of these verdicts:
| Verdict | Meaning |
|---|---|
| Secure | The attack was properly rejected — no vulnerability signal triggered |
| Vulnerable | At least one vulnerability signal triggered |
| NeedsReview | Ambiguous outcome — inspect the response and decide (does not fail the step) |
| BaselineFailed | The template baseline failed, so this instance was not assessed |
| NotRun | Not executed yet |
Managing a Security Test Case
Either from the tree context menu or the case panel:
| Action | Where | Effect |
|---|---|---|
| Reconfigure... | Panel / tree | Re-open the wizard with every setting pre-filled to edit the scan |
| Regenerate / Regenerate Attack Instances | Panel / tree | Rebuild all instances from the current template request and the stored profile (confirms first) |
| Clear / Clear Security Scan | Panel / tree | Remove the template and every instance, returning the case to its unconfigured state |
| Run all | Panel | Execute the whole scan |
| Run (per row) | Panel | Execute a single instance again |
| View (per row) | Panel | Open the request/response detail for that instance |
Generated instances persist in the project and stay stable across CI runs until you regenerate. Editing the template and regenerating is the intended way to rebuild a scan against a changed API.
Regenerate after editing the template. Instances are materialized snapshots; changing the template request does not change existing instances until you regenerate. The panel flags a template that changed since the last generation.
Reports
After a run, the case report contains an aggregated security scan summary (verdict counts, findings with severity and standard identifiers, and remediation). See Reviewing a Security Scan for the panel and the exported report formats.