- name
- retest-vuln
- description
- Verify vulnerability fixes, validate remediation effectiveness, and perform regression testing. Use when a fix has been deployed, patch verification is needed, or confirming vulnerability closure for bug bounty programs.
- tags
- ["security","retest","verification","remediation","regression"]
- triggers
- ["retest vulnerability","verify fix","remediation check","regression test vulnerability"]
# retest-vuln
## When to Use
- A vulnerability fix has been deployed and needs verification
- Bug bounty program requests retest before closing ticket
- Patch has been released and remediation must be confirmed
- Regression testing needed after application updates
- Verifying WAF/security control effectiveness
- Confirming all attack vectors for a vulnerability are addressed
- Closing out vulnerability reports with proof of fix
- Validating hotfix deployment in production
## Quick Start
Minimal retest workflow:
```bash
# 1. Confirm environment is patched version
curl -s https://target.com/version | grep -i version
# 2. Replay original proof-of-concept
curl -s "https://target.com/vuln?param=<script>alert(1)</script>"
# 3. Compare response - look for sanitization/blocking
# Before: <script>alert(1)</script> reflected
# After: <script>alert(1)</script> encoded
```
## Core Concepts
### Retest vs Original Test
| Aspect | Original Test | Retest Verification |
| -------- | -------------------- | ----------------------- |
| Goal | Find vulnerability | Confirm fix works |
| Approach | Exploratory | Targeted replay |
| Evidence | PoC showing impact | Before/after comparison |
| Output | Vulnerability report | Fix verification report |
### Verification Outcomes
| Result | Meaning | Action |
| ------------- | ----------------------------------- | ---------------------------- |
| **FIXED** | Vulnerability no longer exploitable | Close ticket, document proof |
| **PARTIAL** | Some vectors fixed, others open | Report remaining issues |
| **NOT FIXED** | Original attack still works | Escalate, provide details |
| **REGRESSED** | Was fixed, now vulnerable again | Alert immediately |
| **BYPASS** | Fix circumventable with variation | Document bypass technique |
## Step-by-Step Process
### Phase 1: Environment Verification
**CRITICAL**: Ensure you're testing the patched version.
```bash
# Check application version
curl -sI https://target.com | grep -i "x-version\|x-app-version\|server"
# Check for version in page source
curl -s https://target.com | grep -iE "version|build|release"
# Compare response headers with pre-fix baseline
diff <(curl -sI https://target.com) baseline_headers.txt
# Verify DNS resolves to correct IP (not cached)
nslookup target.com
dig target.com +short
```
**Environment Checklist**:
- [ ] Confirmed patched version deployed
- [ ] Cleared local browser cache
- [ ] Not using cached proxy responses
- [ ] Testing correct environment (prod vs staging)
- [ ] Fresh session/authentication state
### Phase 2: Baseline Capture
Save the original vulnerable behavior for comparison:
```bash
# Store original vulnerable request/response
cat > original_vuln.txt << 'EOF'
=== ORIGINAL VULNERABILITY ===
Date: 2024-01-15
Target: https://target.com/api/user?id=123
Method: GET
Payload: id=123' OR '1'='1
Response: 200 OK
Evidence: Returned all user records (SQL injection)
EOF
# Capture original response (if still available in archives)
curl -s "https://web.archive.org/web/*/target.com/api/user*"
```
### Phase 3: Direct Replay Test
Execute the exact original proof-of-concept:
```bash
# Replay original payload EXACTLY as documented
# Example: XSS vulnerability
curl -s "https://target.com/search?q=<script>alert('XSS')</script>" \
-H "Cookie: session=YOUR_SESSION" \
-o retest_response.html
# Check if payload is reflected/executed
grep -i "script>alert" retest_response.html
# Example: SQL Injection
curl -s "https://target.com/api/user?id=1' OR '1'='1" \
-H "Authorization: Bearer TOKEN" \
-o retest_sqli.json
# Check response for injection indicators
cat retest_sqli.json | jq '.users | length'
```
### Phase 4: Response Comparison
Analyze before vs after behavior:
```bash
# HTTP Status Code Comparison
echo "=== Status Code Check ==="
ORIGINAL_STATUS=200
RETEST_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
"https://target.com/vuln?payload=test")
if [ "$RETEST_STATUS" != "$ORIGINAL_STATUS" ]; then
echo "Status changed: $ORIGINAL_STATUS -> $RETEST_STATUS"
fi
# Response Body Comparison
echo "=== Response Body Diff ==="
diff original_response.txt retest_response.txt
# Response Size Comparison
ORIG_SIZE=$(wc -c < original_response.txt)
NEW_SIZE=$(wc -c < retest_response.txt)
echo "Size change: $ORIG_SIZE -> $NEW_SIZE bytes"
# Header Comparison
diff <(curl -sI "https://target.com/endpoint") original_headers.txt
```
**Fix Indicators to Look For**:
| Vulnerability | Original Behavior | Fixed Behavior |
| ------------- | ------------------- | --------------------- |
| XSS | Script executed | HTML encoded, blocked |
| SQLi | Data returned | Error, empty, 403 |
| IDOR | Other user's data | 403 Forbidden |
| LFI | File contents shown | Path blocked, 400 |
| RCE | Command output | Sanitized, no exec |
| SSRF | Internal response | Blocked, timeout |
### Phase 5: Bypass Verification
Test if fix can be circumvented with payload variations:
```bash
# XSS Bypass Attempts
PAYLOADS=(
"<script>alert(1)</script>" # Original
"<ScRiPt>alert(1)</ScRiPt>" # Case variation
"<script >alert(1)</script>" # Space injection
"<scr<script>ipt>alert(1)</script>" # Nested tags
"javascript:alert(1)" # Protocol handler
"<img src=x onerror=alert(1)>" # Event handler
"<svg onload=alert(1)>" # SVG event
"{{constructor.constructor('alert(1)')()}}" # Template injection
)
for payload in "${PAYLOADS[@]}"; do
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$payload'))")
response=$(curl -s "https://target.com/search?q=$encoded")
if echo "$response" | grep -qi "alert"; then
echo "BYPASS FOUND: $payload"
fi
done
# SQLi Bypass Attempts
SQLI_PAYLOADS=(
"' OR '1'='1" # Original
"' OR '1'='1'--" # Comment
"' OR 1=1#" # MySQL comment
"'\tOR\t'1'='1" # Tab injection
"' OR ''='" # Empty string
"admin'--" # Login bypass
"1; DROP TABLE users--" # Stacked queries
)
for payload in "${SQLI_PAYLOADS[@]}"; do
curl -s "https://target.com/api/user?id=$payload" -o /dev/null -w "%{http_code}\n"
done
```
### Phase 6: Regression Testing
Check related functionality for similar issues:
```bash
# Test related endpoints
echo "=== Regression Check - Related Endpoints ==="
ENDPOINTS=(
"/api/user"
"/api/admin/user"
"/api/v2/user"
"/user/profile"
"/admin/users"
)
for endpoint in "${ENDPOINTS[@]}"; do
status=$(curl -s -o /dev/null -w "%{http_code}" \
"https://target.com${endpoint}?id=1' OR '1'='1")
echo "$endpoint: $status"
done
# Test same vulnerability type in other parameters
PARAMS=("id" "user_id" "userId" "uid" "account" "profile_id")
for param in "${PARAMS[@]}"; do
response=$(curl -s "https://target.com/api/data?${param}=1' OR '1'='1")
echo "Testing $param parameter..."
done
```
### Phase 7: Documentation
Create comprehensive fix verification report:
```markdown
# Vulnerability Retest Report
## Summary
| Field | Value |
| ------------------ | ------------- |
| Original Report ID | #12345 |
| Vulnerability Type | SQL Injection |
| Retest Date | 2024-01-20 |
| Retest Result | FIXED |
| Tester | agent_name |
## Environment Verification
- Application Version: 2.1.5 (patched)
- Test Environment: Production
- IP Verified: 203.0.113.50
## Original Vulnerability
- Endpoint: /api/user
- Parameter: id
- Payload: `' OR '1'='1`
- Original Response: 200 OK, returned 500 records
## Retest Results
### Direct Replay
- Payload: `' OR '1'='1`
- Response: 400 Bad Request
- Body: "Invalid parameter format"
- Result: **BLOCKED**
### Bypass Attempts
| Payload | Result |
| ------------- | ----------- |
| `' OR '1'='1` | 400 Blocked |
| `' OR 1=1--` | 400 Blocked |
| `admin'--` | 400 Blocked |
### Regression Testing
| Endpoint | Status |
| --------------- | ------ |
| /api/user | Fixed |
| /api/admin/user | Fixed |
| /api/v2/user | Fixed |
## Conclusion
Vulnerability confirmed FIXED. Input validation implemented
correctly. All tested bypass attempts blocked.
## Evidence
[Screenshot: retest_evidence.png]
[HTTP Capture: retest_burp.xml]
```
## Examples
### Example 1: XSS Retest (Fixed)
**Scenario**: Reflected XSS was reported in search parameter
**Original Vulnerability**:
```http
GET /search?q=<script>alert('XSS')</script> HTTP/1.1
Host: target.com
Response:
<div>Results for: <script>alert('XSS')</script></div>
```
**Retest Commands**:
```bash
# Direct replay
curl -s "https://target.com/search?q=<script>alert('XSS')</script>"
# Output:
<div>Results for: <script>alert('XSS')</script></div>
```
**Analysis**:
```bash
# Check encoding
echo "Original: <script>alert('XSS')</script>"
echo "Now: <script>alert('XSS')</script>"
echo "Result: HTML entities encoded - FIXED"
```
**Verification Result**: FIXED - Input is properly HTML encoded.
---
### Example 2: SQL Injection Retest (Partial Fix)
**Scenario**: SQLi in user lookup endpoint
**Original Vulnerability**:
```http
GET /api/user?id=1' OR '1'='1 HTTP/1.1
Response: 200 OK
{"users": [{"id":1,"name":"admin"}, {"id":2,"name":"user2"}, ...]}
```
**Retest Commands**:
View on GitHub