Every web server generates logs. Most teams ignore them until something breaks. But your access logs are a goldmine of security intelligence — if you know what to look for.
After analyzing millions of log lines across production systems, here are 5 attack patterns that show up consistently. Each one is easy to detect, and catching them early can save you from a breach.
1. Path Traversal Attempts
What it looks like:
192.168.1.105 - - [24/Mar/2026:03:14:22 +0000] "GET /images/../../etc/passwd HTTP/1.1" 400 0
10.0.0.33 - - [24/Mar/2026:03:14:45 +0000] "GET /static/%2e%2e/%2e%2e/etc/shadow HTTP/1.1" 403 0
203.0.113.50 - - [24/Mar/2026:03:15:01 +0000] "GET /download?file=../../../proc/self/environ HTTP/1.1" 200 1245
Why it matters: Attackers use ../ sequences (or URL-encoded variants like %2e%2e) to escape the web root and read system files. The third example is the scariest — it returned a 200, meaning the server actually served the file.
What to scan for:
- Requests containing
..or%2e%2ein the URI - Any 200 responses to paths referencing
/etc/,/proc/, or system directories
grep -iE "(\.\\./|%2e%2e|%252e)" /var/log/nginx/access.log
2. Brute Force Detection (Repeated 401s)
What it looks like:
198.51.100.14 - admin [24/Mar/2026:04:00:01 +0000] "POST /admin/login HTTP/1.1" 401 112
198.51.100.14 - admin [24/Mar/2026:04:00:01 +0000] "POST /admin/login HTTP/1.1" 401 112
198.51.100.14 - admin [24/Mar/2026:04:00:02 +0000] "POST /admin/login HTTP/1.1" 401 112
198.51.100.14 - admin [24/Mar/2026:04:00:03 +0000] "POST /admin/login HTTP/1.1" 200 3842
Why it matters: A burst of 401 responses from the same IP followed by a 200 is the textbook signature of a successful brute force attack.
What to scan for:
- More than 5-10 failed auth attempts (401/403) from a single IP within a short window
- A 200 response after a series of failures (indicates successful compromise)
awk \ == 401 {print \} /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
3. XSS Attempts in Query Strings
What it looks like:
10.0.0.88 - - [24/Mar/2026:05:22:10 +0000] "GET /search?q=<script>alert(document.cookie)</script> HTTP/1.1" 200 4521
172.16.0.5 - - [24/Mar/2026:05:22:33 +0000] "GET /profile?name=%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E HTTP/1.1" 200 3200
Why it matters: XSS payloads in URLs mean someone is actively testing whether your application sanitizes input. If those requests return 200, your app may be vulnerable.
What to scan for:
-
<script>,<svg,<imgtags in query parameters - Event handlers like
onerror=,onload= - URL-encoded versions of the above
grep -iE "(<script|%3Cscript|onerror=|onload=|javascript:)" /var/log/nginx/access.log
4. Sensitive File Access (.env, .git, wp-admin probing)
What it looks like:
45.33.32.156 - - [24/Mar/2026:06:10:05 +0000] "GET /.env HTTP/1.1" 200 890
45.33.32.156 - - [24/Mar/2026:06:10:06 +0000] "GET /.git/config HTTP/1.1" 200 234
45.33.32.156 - - [24/Mar/2026:06:10:07 +0000] "GET /wp-admin/ HTTP/1.1" 302 0
45.33.32.156 - - [24/Mar/2026:06:10:08 +0000] "GET /phpinfo.php HTTP/1.1" 200 52314
Why it matters: This is an automated scanner probing for exposed config files. A .env file returning 200 is a critical incident — it likely contains database credentials, API keys, and secrets.
What to scan for:
- Requests for dotfiles:
.env,.git/,.htaccess,.aws/credentials - Admin panel probing:
/wp-admin,/phpmyadmin,/adminer - Any of the above returning a 200 status code
grep -iE "(\.env|\.git|wp-admin|phpinfo|\.aws|server-status)" /var/log/nginx/access.log
5. API Keys and Tokens Leaked in URLs
What it looks like:
10.0.0.22 - - [24/Mar/2026:07:30:15 +0000] "GET /api/data?api_key=sk_live_4eC39HqLyjWDarjtT1zdp7dc HTTP/1.1" 200 1580
10.0.0.22 - - [24/Mar/2026:07:30:16 +0000] "GET /webhook?token=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HTTP/1.1" 200 40
Why it matters: This is not an external attack — it is your own application leaking secrets. API keys passed as query parameters get logged in plain text in access logs, browser history, and analytics tools.
What to scan for:
- Query parameters named
api_key,token,access_token,secret - Known key patterns:
sk_live_,ghp_,AKIA(AWS),xoxb-(Slack)
grep -iE "(api_key=|token=|access_token=|secret=|sk_live_|ghp_|AKIA)" /var/log/nginx/access.log
Immediate action: If you find leaked keys, rotate them immediately.
Automate It
Scanning for these patterns manually works, but it does not scale. You have to check every log rotation, across every server, every day.
I built LogAudit to automate exactly this — it scans your nginx/Apache logs against these patterns (and more), flags issues by severity, and gives you a compliance score. Free tier available if you want to try it.
But regardless of what tools you use — start scanning. These patterns are hitting your servers right now.
Top comments (0)