Web Application Attack
Web application attack response encompasses the detection, containment, and remediation of attacks targeting application-layer vulnerabilities and availability. This playbook applies when web application firewall alerts indicate active exploitation, when monitoring detects anomalous request patterns, when defacement or data extraction is discovered, or when application availability degrades under volumetric attack. The procedures differentiate between exploitation attacks requiring forensic investigation and availability attacks requiring traffic engineering.
Activation criteria
Invoke this playbook when any of the following conditions exist:
| Indicator | Activation threshold |
|---|---|
| WAF block rate | Exceeds 1,000 blocks per minute from coordinated sources |
| SQL injection signatures | Any confirmed SQLi attempt reaching the database layer |
| Authentication failures | Exceeds 500 failures per hour against single application endpoint |
| Response time degradation | P95 latency exceeds 5x baseline for more than 10 minutes |
| Error rate spike | 5xx errors exceed 10% of requests for more than 5 minutes |
| Data extraction indicators | Unusual query patterns returning large result sets |
| Defacement detection | Integrity monitoring detects unauthorised content changes |
| Session anomalies | Single session accessing more than 1,000 unique resources in one hour |
| External notification | Security researcher, CERT, or hosting provider reports active attack |
Attack classification
Distinguish between exploitation attacks (SQLi, XSS, authentication bypass) and availability attacks (DDoS). Exploitation attacks prioritise evidence preservation; availability attacks prioritise service restoration. Mixed attacks require parallel response tracks.
Roles
| Role | Responsibility | Typical assignee | Backup |
|---|---|---|---|
| Incident commander | Overall coordination, escalation decisions, stakeholder communication | IT Manager or Security Lead | Senior Developer |
| Technical lead | Attack analysis, containment implementation, remediation | Senior Developer or DevOps Engineer | Application Developer |
| Infrastructure lead | WAF configuration, network controls, traffic analysis | Systems Administrator | Cloud Engineer |
| Communications lead | User notification, status page updates, external communications | Communications Officer | IT Manager |
| Database administrator | Query analysis, integrity verification, backup validation | DBA or Developer with DB access | Systems Administrator |
For organisations without dedicated security staff, the IT manager or senior technical staff member assumes both incident commander and technical lead responsibilities. The key requirement is a single decision-maker with authority to take applications offline.
Phase 1: Immediate response
Objective: Stop active exploitation and preserve evidence before attacker can cover tracks or expand access.
Timeframe: 0-30 minutes from activation.
- Confirm attack classification by reviewing the triggering alert. Access WAF logs to determine attack type:
# For AWS WAF - retrieve last 1000 blocked requests aws wafv2 get-sampled-requests \ --web-acl-arn arn:aws:wafv2:eu-west-1:ACCOUNT:regional/webacl/NAME/ID \ --rule-metric-name AllBlockedRequests \ --scope REGIONAL \ --time-window StartTime=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ),EndTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ --max-items 1000
# For ModSecurity - check recent blocks grep -E "id \"9[0-9]{5}\"" /var/log/modsec_audit.log | tail -100Classify as: SQLi/NoSQLi, XSS, authentication bypass, path traversal, command injection, or DDoS. Mixed attacks require parallel tracks.
- Enable enhanced logging before taking containment actions. Increase log verbosity to capture full request bodies and response codes:
# Nginx - add to affected server block temporarily log_format detailed '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time ' '"$request_body"'; access_log /var/log/nginx/attack_detailed.log detailed;For cloud platforms, enable request-level logging in the load balancer or API gateway.
Implement initial containment based on attack type:
For exploitation attacks (SQLi, XSS, authentication bypass):
Block attacking IP addresses at the WAF level while preserving ability to analyse traffic:
# AWS WAF - add IP to block list aws wafv2 update-ip-set \ --name BlockedAttackers \ --scope REGIONAL \ --id IP_SET_ID \ --addresses "192.0.2.100/32" "198.51.100.0/24" \ --lock-token LOCK_TOKEN
# Cloudflare - block IP curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/firewall/access_rules/rules" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"mode":"block","configuration":{"target":"ip","value":"192.0.2.100"},"notes":"Attack response"}'For DDoS attacks:
Enable rate limiting and challenge modes:
# Cloudflare - enable Under Attack mode curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/security_level" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"value":"under_attack"}'Assess whether to take the application offline. Take offline immediately if any of these conditions exist:
- Active data exfiltration confirmed (database queries returning large datasets to external destinations)
- Defacement visible to users
- Authentication bypass allowing unauthorised access to sensitive functions
- Command injection achieving code execution
To take application offline while preserving the environment:
# Redirect all traffic to maintenance page at load balancer # AWS ALB - modify listener rule to return fixed response aws elbv2 modify-rule \ --rule-arn RULE_ARN \ --conditions Field=path-pattern,Values='/*' \ --actions Type=fixed-response,FixedResponseConfig='{StatusCode=503,ContentType=text/html,MessageBody="<html><body><h1>Maintenance in progress</h1></body></html>"}'Do not terminate application processes; preserve memory state for investigation.
- Notify the incident commander and communications lead. Provide initial classification: attack type, affected application, current containment status, and estimated user impact.
Decision point: If attack is DDoS only with no exploitation indicators, proceed to Phase 3 (DDoS track). If exploitation is confirmed or suspected, proceed to Phase 2.
Checkpoint: Attacking traffic is blocked or rate-limited. Enhanced logging is active. Application is either contained (offline) or under active monitoring. Incident commander is aware.
Phase 2: Investigation
Objective: Determine attack vector, scope of compromise, and data accessed or modified.
Timeframe: 30 minutes to 4 hours depending on complexity.
- Identify the specific vulnerability being exploited. Review blocked requests to extract attack payloads:
# Extract SQLi payloads from WAF logs grep -i "select\|union\|insert\|update\|delete\|drop\|--\|'" /var/log/waf/blocked.log | \ awk '{print $7}' | urldecode | sort | uniq -c | sort -rn | head -50
# Look for path traversal attempts grep -E "\.\./|\.\.%2f|%2e%2e" /var/log/nginx/access.log
# Identify XSS payloads grep -Ei "<script|javascript:|onerror=|onload=" /var/log/nginx/access.logMap payloads to specific CVEs or OWASP categories to guide remediation.
- Determine which requests bypassed the WAF and reached the application. Compare WAF block logs against application server access logs:
# Extract all requests from attacking IPs that reached application grep "192.0.2.100\|198.51.100" /var/log/nginx/access.log | \ grep -v " 403 \| 429 " | \ awk '{print $1, $4, $7, $9}'Any request that returned 200, 301, 302, or 500 reached the application logic.
- For SQL injection attacks, analyse database query logs to determine if injection succeeded:
-- PostgreSQL: Review recent queries for injection patterns SELECT query, calls, mean_time FROM pg_stat_statements WHERE query LIKE '%UNION%' OR query LIKE '%SELECT%FROM%information_schema%' OR query LIKE '%--%' ORDER BY calls DESC LIMIT 100;
-- MySQL: Check general query log (must be enabled) SELECT event_time, argument FROM mysql.general_log WHERE argument REGEXP 'UNION|information_schema|--' AND event_time > NOW() - INTERVAL 24 HOUR;Successful injection produces queries containing attacker-controlled strings that would not appear in legitimate application queries.
- Assess data exposure by identifying what the attacker could have accessed. If injection reached the database:
-- Identify tables queried during attack window -- PostgreSQL audit log analysis SELECT DISTINCT regexp_matches(query, 'FROM\s+([a-zA-Z_][a-zA-Z0-9_]*)', 'gi') as tables_accessed FROM pg_stat_statements WHERE query_start > NOW() - INTERVAL '4 hours';For authentication bypass, review access logs for resources accessed by compromised sessions:
# Find all resources accessed by session ID grep "session_id=COMPROMISED_SESSION" /var/log/application/access.log | \ awk '{print $7}' | sort | uniq- Verify database integrity for destructive attacks. Compare current row counts against recent backup:
-- Generate table statistics SELECT schemaname, relname, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC;Compare against baseline. Significant discrepancies indicate data modification or deletion.
- For XSS attacks, determine if stored payloads exist in the database. Search for script content in user-controllable fields:
-- Search for stored XSS payloads SELECT id, created_at, content_field FROM user_content WHERE content_field ~* '<script|javascript:|onerror|onload' AND created_at > NOW() - INTERVAL '7 days';Document all locations where malicious content is stored.
Create attack timeline correlating WAF logs, application logs, and database logs. Include:
- First observed attack attempt
- First successful exploitation (if any)
- Data accessed or exfiltrated
- Any lateral movement or privilege escalation
- Attacker IP addresses and user agents
Decision point: If data breach is confirmed (sensitive data accessed by attacker), invoke Data Breach Response in parallel. If protection data was accessed, invoke Protection Data Breach Response.
Checkpoint: Attack vector identified. Scope of access determined. Data exposure assessed. Timeline documented.
Phase 3: Containment and remediation
Objective: Eliminate the vulnerability, remove attacker access, and restore secure operation.
Timeframe: 2-24 hours depending on vulnerability complexity.
Exploitation attack track
- Implement emergency patch or mitigating control for the exploited vulnerability. If a code fix is possible:
# Emergency deployment workflow git checkout -b hotfix/sqli-vuln-CVE-2024-XXXX # Apply fix git commit -m "SECURITY: Parameterise query in user_search endpoint" git push origin hotfix/sqli-vuln-CVE-2024-XXXX
# Deploy to staging, validate fix blocks attack payload curl -X POST "https://staging.example.org/api/search" \ -d "query=test' OR '1'='1" \ -w "%{http_code}" # Expected: 400 (input validation) or 200 with empty results (parameterised query)
# Deploy to production after validationIf code fix requires more time, implement WAF rules to block the specific attack pattern:
# AWS WAF - add custom rule for specific SQLi pattern aws wafv2 update-web-acl \ --name ProductionWAF \ --scope REGIONAL \ --id WEBACL_ID \ --rules '[{ "Name": "BlockSQLiInSearchParam", "Priority": 1, "Statement": { "ByteMatchStatement": { "SearchString": "SELECT", "FieldToMatch": {"Body": {}}, "TextTransformations": [{"Priority": 0, "Type": "URL_DECODE"}], "PositionalConstraint": "CONTAINS" } }, "Action": {"Block": {}}, "VisibilityConfig": {"SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "BlockSQLiSearch"} }]' \ --lock-token LOCK_TOKEN- Invalidate all active sessions to force re-authentication. This removes any attacker sessions established during the compromise:
# Redis session store - flush all sessions redis-cli FLUSHDB
# Database session store psql -c "TRUNCATE TABLE user_sessions;"
# JWT tokens - if using blacklist approach # Add all tokens issued before current time to blacklist psql -c "INSERT INTO token_blacklist (issued_before) VALUES (NOW());"Warn users that they will need to log in again. Coordinate timing with communications lead.
- Remove stored XSS payloads from the database:
-- Sanitise stored XSS in user content UPDATE user_content SET content_field = regexp_replace( content_field, '<script[^>]*>.*?</script>', '', 'gi' ) WHERE content_field ~* '<script';
-- Log affected rows for notification SELECT id, user_id FROM user_content WHERE content_field ~* '<script|javascript:|onerror';- Reset credentials for any accounts showing compromise indicators:
-- Force password reset for accounts accessed during attack window UPDATE users SET password_reset_required = true, password_reset_token = gen_random_uuid(), password_reset_expires = NOW() + INTERVAL '24 hours' WHERE id IN ( SELECT DISTINCT user_id FROM access_log WHERE ip_address IN ('192.0.2.100', '198.51.100.50') AND timestamp > NOW() - INTERVAL '24 hours' );- If database modification occurred, restore affected tables from backup:
# PostgreSQL - restore specific tables from backup pg_restore --data-only --table=affected_table \ -d production_db backup_before_attack.dump
# Verify row counts match expected psql -c "SELECT COUNT(*) FROM affected_table;"Document all data restoration for audit trail.
DDoS attack track
- Analyse traffic patterns to distinguish attack traffic from legitimate users:
# Identify top source IPs awk '{print $1}' /var/log/nginx/access.log | \ sort | uniq -c | sort -rn | head -100
# Identify request patterns awk '{print $7}' /var/log/nginx/access.log | \ sort | uniq -c | sort -rn | head -50
# Check user agent distribution awk -F'"' '{print $6}' /var/log/nginx/access.log | \ sort | uniq -c | sort -rn | head -50Attack traffic typically shows: high concentration from specific IP ranges, identical user agents, requests to specific endpoints, or unusual geographic distribution.
- Implement rate limiting at the WAF layer:
# AWS WAF - add rate-based rule aws wafv2 update-web-acl \ --name ProductionWAF \ --scope REGIONAL \ --id WEBACL_ID \ --rules '[{ "Name": "RateLimitByIP", "Priority": 0, "Statement": { "RateBasedStatement": { "Limit": 2000, "AggregateKeyType": "IP" } }, "Action": {"Block": {}}, "VisibilityConfig": {"SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "RateLimit"} }]' \ --lock-token LOCK_TOKENStart with conservative limits (2000 requests per 5 minutes per IP) and adjust based on legitimate traffic patterns.
- Enable geographic blocking if attack originates from regions without legitimate users:
# Cloudflare - block by country curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/firewall/access_rules/rules" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"mode":"block","configuration":{"target":"country","value":"XX"},"notes":"DDoS response"}'Document blocked countries for post-incident review.
If attack exceeds WAF capacity, escalate to upstream provider:
For cloud-hosted applications, enable DDoS protection services:
# AWS Shield Advanced - already enabled, verify protection aws shield describe-protection --resource-arn APPLICATION_ARN
# Request AWS Shield Response Team engagement for active attack aws shield create-protection-group \ --protection-group-id "ActiveDDoS" \ --aggregation "SUM" \ --pattern "ALL"For ISP-level mitigation, contact provider NOC with traffic analysis showing attack patterns.
- Implement application-layer mitigations for application-layer DDoS (layer 7):
# Nginx - connection limiting limit_conn_zone $binary_remote_addr zone=addr:10m; limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
server { limit_conn addr 10; limit_req zone=req burst=20 nodelay;
# Return 429 instead of 503 for rate limits limit_conn_status 429; limit_req_status 429; }Test configuration before applying to production.
Checkpoint: Vulnerability patched or mitigated. Attacker access removed. Sessions invalidated. DDoS traffic blocked or absorbed. Application ready for recovery.
Phase 4: Recovery
Objective: Restore normal service with confidence that the attack has been fully contained.
Timeframe: 1-4 hours.
- Validate the fix by replaying attack payloads against the patched application in a staging environment:
# Replay captured attack payloads while read payload; do response=$(curl -s -o /dev/null -w "%{http_code}" \ -X POST "https://staging.example.org/api/search" \ -d "query=$payload") echo "$payload -> $response" done < attack_payloads.txt
# All responses should be 400 (validation) or 200 with safe resultsDo not proceed if any payload produces successful exploitation.
- Restore application to service incrementally. If application was taken offline:
# AWS ALB - restore normal routing aws elbv2 modify-rule \ --rule-arn RULE_ARN \ --conditions Field=path-pattern,Values='/*' \ --actions Type=forward,TargetGroupArn=PRODUCTION_TARGET_GROUPMonitor error rates and response times for the first 15 minutes.
- Reduce WAF sensitivity from attack-response levels to normal operation:
# Cloudflare - reduce security level curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/security_level" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"value":"medium"}'Keep emergency IP blocks in place; review after 72 hours.
- Communicate service restoration to users. Update status page:
[RESOLVED] Web application attack mitigated
The security incident affecting [application name] has been resolved. Service is restored. As a precaution, all users have been logged out and will need to sign in again.
No action is required unless you receive a password reset notification.- Continue enhanced monitoring for 48 hours:
# Set up alert for attack pattern recurrence # Example: CloudWatch alarm for WAF block rate aws cloudwatch put-metric-alarm \ --alarm-name "AttackPatternRecurrence" \ --metric-name BlockedRequests \ --namespace AWS/WAFV2 \ --statistic Sum \ --period 300 \ --threshold 500 \ --comparison-operator GreaterThanThreshold \ --evaluation-periods 1 \ --alarm-actions SNS_TOPIC_ARNCheckpoint: Application serving traffic normally. Enhanced monitoring active. Users notified.
Phase 5: Post-incident
Objective: Document the incident, identify improvements, and prevent recurrence.
Timeframe: Within 5 business days of resolution.
- Preserve evidence for potential legal or regulatory requirements. Copy logs to secure, immutable storage:
# Archive logs to write-once storage tar -czf incident_$(date +%Y%m%d)_webapp.tar.gz \ /var/log/nginx/ \ /var/log/waf/ \ /var/log/application/
aws s3 cp incident_$(date +%Y%m%d)_webapp.tar.gz \ s3://security-evidence-bucket/ \ --storage-class GLACIER_IRRetain for minimum 12 months or as required by data protection regulations.
Complete incident report using the template from Evidence Collection. Include:
- Timeline of attack and response
- Attack vectors exploited
- Data accessed or exfiltrated
- Root cause analysis
- Remediation actions taken
- Recommendations for prevention
Conduct vulnerability assessment of the affected application. Schedule penetration test if attack exploited previously unknown vulnerability:
# Run OWASP ZAP baseline scan docker run -t owasp/zap2docker-stable zap-baseline.py \ -t https://example.org \ -r zap_report.html- Update WAF rules based on attack patterns observed:
# Document new rule requirements cat << EOF > waf_rule_update.md ## New WAF Rules Required
1. Block requests containing [specific payload pattern] 2. Rate limit endpoint /api/search to 100 requests/minute/IP 3. Require CAPTCHA challenge for requests from [ASN] EOFReview and update monitoring thresholds based on incident learnings. Adjust alert thresholds that were too high (missed attack) or too low (excessive alerts).
Schedule post-incident review meeting within 10 business days. Include: technical staff involved in response, application owners, and security lead. Focus on process improvements rather than blame.
Communications
| Stakeholder | Timing | Channel | Message owner | Template |
|---|---|---|---|---|
| IT leadership | Within 30 minutes | Direct call or message | Incident commander | Initial notification |
| Executive team | Within 2 hours | Incident commander | Situation report | |
| Affected users | When service impacted | Status page and email | Communications lead | Service status |
| External parties | As required by regulation | Email with legal review | Executive sponsor | Breach notification |
| Security contacts | Within 24 hours | Email to cert@example.org | Technical lead | Technical report |
Communication templates
Initial notification (30 minutes):
Subject: [SECURITY INCIDENT] Web application attack in progress - [Application Name]
Status: Active responseClassification: [SQLi / XSS / DDoS / Authentication Bypass]Affected system: [Application name and URL]Current impact: [Service degraded / Service offline / No user impact]
Response actions:- Attack traffic blocked at WAF- Enhanced logging enabled- Investigation in progress
Next update: [Time, within 2 hours]Incident commander: [Name, contact]Service status update:
[INVESTIGATING] Elevated error rates on [Application Name]
We are investigating elevated error rates affecting [application].Some users may experience slow responses or temporary errors.Our team is actively working to resolve this issue.
Updates will be posted here as we learn more.Resolution notification:
[RESOLVED] Security incident on [Application Name]
A security incident affecting [Application Name] has been resolved.The application is operating normally.
Impact summary:- Duration: [Start time] to [End time]- Affected users: [Number or description]- Data impact: [None confirmed / Under investigation / Details]
As a precautionary measure, all active sessions have been terminated.Users will need to log in again.
If you notice any unusual activity in your account, contact [support].Evidence preservation
Preserve the following evidence before any system changes:
| Evidence type | Collection method | Retention location | Retention period |
|---|---|---|---|
| WAF logs | Export from WAF console or API | Security evidence bucket | 12 months minimum |
| Web server access logs | Copy from /var/log/nginx/ | Security evidence bucket | 12 months minimum |
| Application logs | Export from logging platform | Security evidence bucket | 12 months minimum |
| Database query logs | Export from database audit log | Security evidence bucket | 12 months minimum |
| Network flow data | Export from cloud provider or network monitoring | Security evidence bucket | 12 months minimum |
| Malicious payloads | Extract from logs, store decoded | Incident documentation | Duration of incident record |
| Screenshots of defacement | Browser screenshot with timestamp | Incident documentation | Duration of incident record |
| Memory dump (if available) | gcore process dump | Security evidence bucket | 6 months |
+------------------------------------------------------------------+| EVIDENCE COLLECTION FLOW |+------------------------------------------------------------------+| || +----------------+ || | Attack | || | Detected | || +-------+-------+ || | || v || +-------+-------+ +------------------+ || | Enable | | Existing logs | || | enhanced +---->| (preserve | || | logging | | immediately) | || +-------+-------+ +--------+---------+ || | | || v v || +-------+-------+ +--------+---------+ || | Collect | | Copy to | || | new evidence +---->| immutable | || | during | | storage | || | investigation | +--------+---------+ || +-------+-------+ | || | v || | +--------+---------+ || +------------>| Hash and | || | document | || | chain of custody | || +--------+---------+ || | || v || +--------+---------+ || | Retain per | || | policy | || | (12 months min) | || +------------------+ || |+------------------------------------------------------------------+Figure 1: Evidence collection and preservation flow
Hash all evidence files immediately after collection:
sha256sum incident_$(date +%Y%m%d)_webapp.tar.gz > evidence_hashes.txtDocument chain of custody: who collected the evidence, when, from which system, using which method.
Attack response decision tree
+------------------------------------------------------------------+| ATTACK TYPE CLASSIFICATION |+------------------------------------------------------------------+| || +------------------+ || | Web app alert | || | triggered | || +--------+---------+ || | || +--------v---------+ || | Service | || | available? | || +--------+---------+ || | || +--------------+--------------+ || | | || | No | Yes || v v || +--------+-------+ +---------+--------+ || | DDoS or | | Exploitation | || | infrastructure | | indicators? | || | failure? | +---------+--------+ || +--------+-------+ | || | +----------+----------+ || +--------+--------+ | | || | | | Yes | No || | DDoS Infra | v v || v v | +------+------+ +-------+------+ || +---+----+ +-+----+ | | Data | | False | || | DDoS | | Not | | | accessed? | | positive or | || | track | | this | | +------+------+ | probe only | || +--------+ | PB | | | +-------+------+ || +------+ | +------+------+ | || | | | v || | | Yes | No +------+-------+ || | v v | Monitor and | || | +-----+ +-----+----+ | tune WAF | || | |Invoke| |Continue | +------+-------+ || | |Data | |exploit | | || | |Breach| |track | v || | |PB | +---------+ +------+-------+ || | +------+ | Close or | || | | downgrade | || | +--------------+ |+------------------------------------------------------------------+Figure 2: Attack classification and response routing decision tree
See also
- Application Security for web application security concepts
- Vulnerability Remediation for patching procedures
- Evidence Collection for forensic procedures
- Major Service Outage if service becomes unavailable
- Data Breach Response if data exposure is confirmed
- Incident Triage Matrix for severity classification