14 KiB
14 KiB
Adversarial Testing Protocol (Breaker Agent)
Break it before users do. Systematic protocols for stress-testing AI-generated code.
Related: TESTING_VALIDATION.md | AGENT_REVIEW_PROTOCOL.md
Overview
This document defines the "Breaker Agent" protocol - a systematic approach to adversarial testing that attempts to crash, exploit, or break AI-generated code before deployment. The goal is not to confirm code works; it is to prove it can't be broken.
Philosophy: "If you don't actively try to break your code, your users will do it for you."
THE BREAKER AGENT PERSONA
Agent Configuration
When running adversarial tests, configure the agent with this persona:
PERSONA: Senior QA Security Engineer
MISSION: Find every way to crash, exploit, or misbehave this code.
MINDSET:
- Assume the code is broken until proven otherwise
- Think like a malicious user, not a happy-path user
- Every input is a potential attack vector
- Every edge case is a potential crash
GOAL: Produce a comprehensive failure report, not a success confirmation.
Breaker vs Builder Separation
BUILDER AGENT:
- Creates features
- Writes "happy path" tests
- Assumes good faith input
- Optimizes for functionality
BREAKER AGENT:
- Destroys features (in testing)
- Writes "sad path" tests
- Assumes malicious input
- Optimizes for finding failures
RULE: The same agent should NOT build and break.
Use separate sessions or separate agents.
ATTACK VECTOR CATEGORIES
1. Input Validation Attacks
String Attacks
| Attack Type | Test Input | Expected Behavior |
|---|---|---|
| Empty string | "" |
Graceful error, not crash |
| Whitespace only | " " |
Rejected or trimmed |
| Very long string | 10,000+ characters | Rejected with limit error |
| Unicode edge cases | "café", "日本語", "🔥🎉" |
Handled correctly |
| Null bytes | "hello\x00world" |
Sanitized or rejected |
| Newlines | "line1\nline2" |
Handled per requirements |
| Control characters | "\t\r\n\b" |
Sanitized |
XSS (Cross-Site Scripting) Attacks
// Test these inputs against any user-facing text field:
const xssPayloads = [
'<script>alert("XSS")</script>',
'<img src="x" onerror="alert(1)">',
'<svg onload="alert(1)">',
'javascript:alert(1)',
'<iframe src="javascript:alert(1)">',
'"><script>alert(1)</script>',
"'-alert(1)-'",
'<body onload="alert(1)">',
];
// EXPECTED: All should be escaped or rejected
// FAILURE: Any script execution = CRITICAL vulnerability
SQL Injection Attacks
// Test these against any database-connected input:
const sqlPayloads = [
"'; DROP TABLE users; --",
"' OR '1'='1",
"1; SELECT * FROM users",
"admin'--",
"' UNION SELECT * FROM passwords --",
"1 AND 1=1",
"1' AND '1'='1",
];
// EXPECTED: All should be parameterized/escaped
// FAILURE: Any SQL execution = CRITICAL vulnerability
Number Attacks
| Attack Type | Test Input | Expected Behavior |
|---|---|---|
| Zero | 0 |
Handled (no division errors) |
| Negative | -1, -999999 |
Rejected or handled |
| Float precision | 0.1 + 0.2 |
Handled correctly |
| Very large | Number.MAX_SAFE_INTEGER + 1 |
Rejected or BigInt |
| NaN | NaN |
Rejected or handled |
| Infinity | Infinity, -Infinity |
Rejected |
| String as number | "123abc" |
Rejected |
2. Boundary Condition Attacks
Array/Collection Attacks
const boundaryTests = [
[], // Empty array
[null], // Array with null
[undefined], // Array with undefined
Array(10000).fill(1), // Very large array
[1, [2, [3, [4]]]], // Deeply nested
new Array(1000000), // Sparse array
];
Object Attacks
const objectTests = [
{}, // Empty object
{ __proto__: { admin: true } }, // Prototype pollution
{ constructor: { } }, // Constructor pollution
null, // Null object
Object.create(null), // No prototype
{ [Symbol()]: 'hidden' }, // Symbol keys
];
3. State-Based Attacks
Race Conditions
// Test concurrent operations:
async function raceConditionTest() {
// Submit same form 100 times simultaneously
const promises = Array(100).fill().map(() =>
submitPayment({ amount: 100 })
);
const results = await Promise.all(promises);
// EXPECTED: Only 1 payment processed
// FAILURE: Multiple payments = race condition bug
}
Session Attacks
const sessionTests = [
{ token: '' }, // Empty token
{ token: 'expired_token' }, // Expired token
{ token: 'malformed' }, // Invalid format
{ token: null }, // Null token
{ /* no token */ }, // Missing token
{ token: 'other_user_token' }, // Token from different user
];
4. Resource Exhaustion Attacks
Memory Exhaustion
// Test inputs that could exhaust memory:
const memoryTests = [
'a'.repeat(1000000000), // 1GB string
JSON.parse('{"a":'.repeat(100000) + '1' + '}'.repeat(100000)), // Deep JSON
new Array(100000000), // Huge array allocation
];
// EXPECTED: Rejection before allocation
// FAILURE: Out of memory crash
CPU Exhaustion (ReDoS)
// Regular expressions vulnerable to catastrophic backtracking:
const redosPayloads = [
'a'.repeat(30) + '!', // For regex like /^(a+)+$/
'aaaaaaaaaaaaaaaaaaaaaaaaaaaa!', // Exponential backtracking
];
// EXPECTED: Timeout or rejection
// FAILURE: CPU hang
FUZZ TESTING PROTOCOL
Automated Fuzzing Setup
// fuzzer.js - Generic input fuzzer
const FUZZ_ITERATIONS = 1000;
function generateFuzzInput() {
const generators = [
() => '', // Empty
() => null, // Null
() => undefined, // Undefined
() => Math.random().toString(36), // Random string
() => Math.floor(Math.random() * 1000000), // Random number
() => Array(Math.floor(Math.random() * 100)).fill(Math.random()), // Random array
() => ({ [Math.random()]: Math.random() }), // Random object
() => '<script>alert(1)</script>', // XSS
() => "'; DROP TABLE users; --", // SQL injection
() => 'a'.repeat(10000), // Long string
() => -Math.floor(Math.random() * 1000000), // Negative number
() => NaN, // NaN
() => Infinity, // Infinity
];
return generators[Math.floor(Math.random() * generators.length)]();
}
async function fuzzEndpoint(endpoint, method = 'POST') {
const results = { passed: 0, failed: 0, errors: [] };
for (let i = 0; i < FUZZ_ITERATIONS; i++) {
const input = generateFuzzInput();
try {
const response = await fetch(endpoint, {
method,
body: JSON.stringify({ data: input }),
headers: { 'Content-Type': 'application/json' },
});
// Success = 2xx or 4xx (handled error)
// Failure = 5xx (unhandled error)
if (response.status >= 500) {
results.failed++;
results.errors.push({ input, status: response.status });
} else {
results.passed++;
}
} catch (error) {
results.failed++;
results.errors.push({ input, error: error.message });
}
}
return results;
}
Fuzz Test Directive
FUZZ TESTING PROTOCOL:
Target: [endpoint or function]
Iterations: 1000 minimum
Input Types: All categories above
PASS CRITERIA:
- Zero 5xx errors
- Zero unhandled exceptions
- Zero crashes
- All 4xx errors have meaningful messages
FAILURE CRITERIA:
- Any 5xx error → CRITICAL
- Any unhandled exception → CRITICAL
- Any crash → CRITICAL
- Timeout without rejection → HIGH
COMPONENT-SPECIFIC ATTACK CHECKLISTS
Form Component Attacks
ATTACK CHECKLIST: Form Component
[ ] Submit empty form
[ ] Submit with all fields empty strings
[ ] Submit with XSS in each text field
[ ] Submit with SQL injection in each text field
[ ] Submit with 10,000 character strings
[ ] Submit with emoji-only strings
[ ] Submit with unicode edge cases
[ ] Submit same form 100 times rapidly
[ ] Submit with JavaScript disabled
[ ] Submit with modified hidden fields
[ ] Submit bypassing client validation
API Endpoint Attacks
ATTACK CHECKLIST: API Endpoint
[ ] Call without authentication
[ ] Call with expired token
[ ] Call with malformed token
[ ] Call with other user's token
[ ] Send malformed JSON
[ ] Send wrong Content-Type
[ ] Send empty body
[ ] Send body > 10MB
[ ] Send deeply nested JSON (100 levels)
[ ] Call 1000 times in 1 second (rate limit)
[ ] Call with HTTP method not allowed
File Upload Attacks
ATTACK CHECKLIST: File Upload
[ ] Upload empty file
[ ] Upload file > max size
[ ] Upload file with wrong extension
[ ] Upload .exe renamed to .jpg
[ ] Upload file with null bytes in name
[ ] Upload file with path traversal (../../../etc/passwd)
[ ] Upload SVG with embedded JavaScript
[ ] Upload zip bomb (compressed 1MB → 1GB)
[ ] Upload same file 100 times rapidly
[ ] Upload with modified Content-Type header
Authentication Attacks
ATTACK CHECKLIST: Authentication
[ ] Login with empty credentials
[ ] Login with SQL injection
[ ] Login 100 times with wrong password (lockout)
[ ] Login with valid user, no password
[ ] Login with case-modified username
[ ] Password reset with non-existent email
[ ] Password reset token replay
[ ] Session fixation attempt
[ ] CSRF token bypass attempt
[ ] Remember-me token theft simulation
BREAKER AGENT PROMPT TEMPLATE
Use this prompt to configure a "Breaker Agent" session:
BREAKER AGENT SESSION
PERSONA: You are a Senior Security QA Engineer specializing in
breaking software. Your job is to find bugs, not confirm success.
TARGET: [Component/Endpoint Name]
OBJECTIVE: Systematically attempt to crash, exploit, or cause
unexpected behavior in the target.
ATTACK CATEGORIES TO USE:
1. Input validation attacks (XSS, SQLi, boundary values)
2. State-based attacks (race conditions, session manipulation)
3. Resource exhaustion attacks (memory, CPU, network)
4. Authentication/authorization bypass attempts
REPORT FORMAT:
For each attack attempted, report:
- Attack type
- Input used
- Expected behavior
- Actual behavior
- Severity (CRITICAL / HIGH / MEDIUM / LOW)
- Reproduction steps
CONSTRAINTS:
- Do NOT attack production systems
- Do NOT use attacks that could cause data loss
- Do NOT attempt actual credential theft
- Stay within test environment boundaries
BEGIN ATTACK SEQUENCE:
INTEGRATION WITH CI/CD
Automated Adversarial Tests
# .github/workflows/adversarial-tests.yml
name: Adversarial Testing
on:
pull_request:
branches: [main]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run OWASP ZAP scan
uses: zaproxy/action-full-scan@v0.8.0
with:
target: 'http://localhost:3000'
- name: Run SQLMap
run: |
sqlmap -u "http://localhost:3000/api/search?q=test" --batch --level=5
- name: Run Fuzz Tests
run: npm run test:fuzz
- name: Check results
run: |
if [ -f "fuzz-failures.json" ]; then
echo "Fuzz tests found failures!"
cat fuzz-failures.json
exit 1
fi
Blocking Gate
ADVERSARIAL TEST GATE:
BLOCKING (Must Pass):
[ ] Zero XSS vulnerabilities detected
[ ] Zero SQL injection vulnerabilities detected
[ ] Zero authentication bypasses
[ ] Fuzz tests: < 1% failure rate
[ ] Rate limiting verified functional
NON-BLOCKING (Should Pass):
[ ] All edge cases handled gracefully
[ ] Error messages are user-friendly
[ ] Timeouts configured appropriately
QUICK REFERENCE
+------------------------------------------------------------------+
| ADVERSARIAL TESTING QUICK REFERENCE |
+------------------------------------------------------------------+
| ATTACK CATEGORIES: |
| 1. Input Validation (XSS, SQLi, boundaries) |
| 2. State-Based (race conditions, sessions) |
| 3. Resource Exhaustion (memory, CPU) |
| 4. Auth/AuthZ Bypass |
+------------------------------------------------------------------+
| KEY PAYLOADS: |
| XSS: <script>alert(1)</script> |
| SQLi: ' OR '1'='1 |
| Long: 'a'.repeat(10000) |
| Empty: '', null, undefined |
+------------------------------------------------------------------+
| FUZZ TESTING: |
| Iterations: 1000 minimum |
| Pass: Zero 5xx errors |
| Fail: Any unhandled exception |
+------------------------------------------------------------------+
| RULE: Builder agent ≠ Breaker agent |
| Separate sessions for building and breaking |
+------------------------------------------------------------------+
Authored by: TheArchitectit Document Owner: Project Maintainers Last Updated: 2026-01-21 Line Count: ~400