Skip to content

Safety Rules

All engagements must comply with these safety rules. Violations risk legal liability, data loss, and service disruption. These rules are enforced at every level: skill boilerplate, scope checking, and the /pentest orchestrator.


Authorization Requirement

Mandatory Before ANY Testing

Before executing any test, confirm all three of the following:

  1. Written authorization -- a signed contract, active bug bounty program, or proof of self-ownership
  2. Defined scope -- explicit list of in-scope URLs, domains, and IP ranges (documented in scope.txt)
  3. Agreed rules of engagement -- rate limits, testing windows, excluded endpoints, escalation contacts

Testing without authorization is illegal under most jurisdictions (CFAA, CMA, etc.).


13 Critical Safety Rules

These rules are absolute and apply to every phase, every skill, and every request.

Rule 1: Never Perform Destructive Actions

No DELETE, DROP, TRUNCATE, or any data-modifying operation on the target. All SQL injection payloads must be SELECT-only. Never alter, remove, or corrupt production data.

Rule 2: Never Cause Denial of Service

No flood attacks, resource exhaustion, zip bombs, billion-laughs XML, or recursive payloads. All testing must leave the target operational.

Rule 3: Never Exfiltrate Real Data

Document one example of data exposure and stop. Never download full databases, user lists, or PII dumps. A single row proving the vulnerability is sufficient evidence.

Rule 4: Never Modify Production Data

SQL injection: SELECT and SLEEP()/BENCHMARK() only. XSS: alert(document.domain) or console.log() only. Never insert, update, or delete records.

Rule 5: Always Confirm Scope

Only test URLs and domains explicitly listed in scope.txt. Scope enforcement is implemented at the tool level via scope_curl() -- every outbound request is validated against the scope file. Redirects are followed only if each hop remains in scope.

# scope.txt format
*.example.com          # In scope (wildcard subdomain)
api.example.com        # In scope (exact domain)
!admin.example.com     # Out of scope (exclusion)

Rule 6: Always Warn Before Risky Actions

Prompt the user for explicit confirmation before any action that could write data, send emails, lock accounts, or trigger side effects on the target.

Rule 7: Enforce Rate Limits

Activity Maximum Rate
Scanning (nuclei, nikto) 10 req/sec
Fuzzing (ffuf, wordlists) 50 req/sec
Authentication testing 1 req/sec

In stealth mode (default), rates are further reduced. See Stealth Mode for per-tool configurations.

Rule 8: Stop on WAF Detection

Immediately halt the current test phase if any of the following are received:

  • HTTP 429 Too Many Requests
  • HTTP 503 Service Unavailable
  • WAF ban page or CAPTCHA challenge

The stealth_curl() function implements automatic backoff on 429 responses, scaled by JITTER_MULT.

Rule 9: Log Everything

Every request, response, and finding must be logged. Structured logging writes to logs/pentest-timeline.jsonl using log_event() and log_finding() from the shared boilerplate. This creates an auditable trail of all testing activity.

Rule 10: Verify Before Reporting

Every finding requires a working, reproducible exploit plus real evidence. If an exploit attempt fails, the finding is not reported. The /verify phase re-executes all PoCs to eliminate false positives.

For pentests, HTTP-backed findings require the full raw HTTP request and the full raw HTTP response, including status line, complete headers, and complete body. The same material must survive all downstream outputs: FINDING-NNN.md, HedgeDoc/Outline notes, and generated .docx reports. Summary-only evidence or truncated responses are not acceptable as the default report standard.

For bug bounty submissions, use the fastest reproducible PoC, preferably curl, and collect representative screenshots when the issue is visual. A working-PoC video is mandatory for bug bounty findings.

Rule 11: Never Use Past Engagement Data During Active Testing

Historical results in evals/labs/*/history/ and gap-analysis.md exist only for retrospective analysis. During /pentest, every engagement starts fresh with standard discovery, recon, and testing. Zero influence from past targets.

Rule 12: Never Read Files Outside the Project Root

During /pentest, all information about the target must come from:

  • (a) The target itself via HTTP requests
  • (b) lab-config.json in evals/labs/
  • (c) The user providing it

Never read READMEs, source code, or config files from the target's local directory (e.g., ../vulnhr/README.md). This violates black-box testing methodology and invalidates results.

Rule 13: Always Fix Problems Before Proceeding

If a tool fails (wrong flags, broken pipe, missing dependency), diagnose and fix the root cause before continuing to the next step. Document the fix in CLAUDE.md. Never skip a failed step and move on.


Non-Destructive Verification Techniques

All verification must use safe, non-destructive methods:

Vulnerability Safe Verification Method
SQL Injection SELECT, SLEEP(), BENCHMARK() only
XSS alert(document.domain) or console.log() only
SSRF OOB via collaborator / webhook.site -- never attack internal services
Command Injection whoami, id, hostname, sleep only
File Upload Benign test files only
Race Conditions 2-3 parallel requests maximum
Authentication Use provided test credentials -- never brute force

Stored Payload Cleanup

Mandatory for Persistent Payloads

After confirming a stored/persistent vulnerability and collecting all evidence (full HTTP request+response, representative screenshot when relevant), clean up the injected payload using cleanup_stored_payload(). Verify cleanup succeeded. This applies to: stored XSS, stored SSTI, stored CRLF, persistent comment/profile injection, Mermaid injection, and any payload that renders for other users.

Findings must include cleanup_status set to cleaned or not_applicable.


Mandatory User Confirmation

The following actions require explicit user confirmation before execution, as they may have irreversible effects on production systems:

  • Cache poisoning
  • Request smuggling
  • Race conditions
  • Business logic testing (cart/payment manipulation)
  • Port scanning (via naabu)
  • sqlmap execution
  • Mass assignment testing
  • Password reset with Host header injection

Never Run

Account lockout testing is never permitted. It causes denial of service to legitimate users and is explicitly prohibited.


Scope Enforcement Architecture

Scope is enforced at the tool level, not just by policy. The scope-check.md helper provides:

  1. load_scope() -- parses scope.txt into include/exclude arrays at skill startup
  2. is_in_scope(url) -- validates any URL against the scope, supporting wildcards (*.example.com) and path-based patterns
  3. scope_curl() -- drop-in replacement for curl that blocks out-of-scope requests
  4. scope_curl_follow() -- follows redirects while validating each hop stays in scope
# Example: scope-enforced request
scope_curl "https://target.example.com/api/users" --max-time 10

# Example: redirect-safe request (validates each 3xx hop)
scope_curl_follow "https://target.example.com/login" -H "Accept: text/html"

Out-of-scope requests are blocked and logged to logs/scope-blocks.log.


Kill Switches

Every test skill enforces hard limits via the shared boilerplate:

Limit Default Override
Execution timeout 45 minutes SKILL_TIMEOUT env var (60 min for test-injection)
Request count 500 per skill MAX_REQUESTS env var
Request warning At 400 requests --
Rate limit (429) 3 consecutive = stop Logged via log_event()

Functions check_timeout() and count_request() are called before every request. When limits are hit, the skill saves progress and exits gracefully.