DEV Community

Log Audit
Log Audit

Posted on • Originally published at log-audit.com

How to Detect SQL Injection Attempts in Your Nginx Logs

How to Detect SQL Injection Attempts in Your Nginx Logs

Your nginx access logs are a goldmine of security intelligence — if you know what to look for. SQL injection attempts leave clear fingerprints in your logs, and catching them early lets you block attackers before they find a vulnerable endpoint.

Here's how to find them.

What SQL Injection Looks Like in Logs

A typical nginx access log entry looks like this:

192.168.1.1 - - [19/Mar/2026:12:00:00 +0000] "GET /api/users?id=1 HTTP/1.1" 200 512
Enter fullscreen mode Exit fullscreen mode

A SQL injection attempt looks like this:

185.220.101.45 - - [19/Mar/2026:12:01:23 +0000] "GET /api/users?id=1'+OR+'1'='1 HTTP/1.1" 200 512
185.220.101.45 - - [19/Mar/2026:12:01:24 +0000] "GET /api/users?id=1+UNION+SELECT+null,username,password+FROM+users-- HTTP/1.1" 500 128
185.220.101.45 - - [19/Mar/2026:12:01:25 +0000] "GET /api/users?id=1;DROP+TABLE+users;-- HTTP/1.1" 500 128
Enter fullscreen mode Exit fullscreen mode

Key things to spot:

  • URL-encoded quotes: %27 or '
  • SQL keywords in query strings: UNION, SELECT, DROP, INSERT, OR 1=1
  • Double dashes -- (SQL comment syntax)
  • Semicolons followed by SQL keywords

Manual Detection with grep

The quickest way to check if you're being probed:

# Check for common SQL injection patterns
grep -iE "(union|select|insert|drop|delete|update).*(from|into|table|where)" /var/log/nginx/access.log

# Check for URL-encoded quotes
grep -E "%27|%22|\\x27" /var/log/nginx/access.log

# Check for OR 1=1 patterns
grep -iE "or.*(1=1|'1'='1'|true)" /var/log/nginx/access.log

# Find IPs making suspicious requests
grep -iE "(union|select|drop)" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
Enter fullscreen mode Exit fullscreen mode

Count Attacks Per IP

Once you've identified attack patterns, find the top offenders:

awk '
  /(%27|UNION|SELECT|DROP|OR 1=1)/{
    count[$1]++
  }
  END {
    for (ip in count) print count[ip], ip
  }
' /var/log/nginx/access.log | sort -rn | head -20
Enter fullscreen mode Exit fullscreen mode

Block Attackers with fail2ban

Once you've identified attack patterns, automate blocking with fail2ban.

Create /etc/fail2ban/filter.d/nginx-sqli.conf:

[Definition]
failregex = ^<HOST> .* "(GET|POST) .*(%27|%22|UNION|SELECT|DROP|INSERT|OR 1=1|\x27).* HTTP
gneregex = .*\.js|.*\.css|.*\.png|.*\.jpg
Enter fullscreen mode Exit fullscreen mode

Add to /etc/fail2ban/jail.local:

[nginx-sqli]
enabled  = true
port     = http,https
filter   = nginx-sqli
logpath  = /var/log/nginx/access.log
maxretry = 3
bantime  = 86400
findtime = 600
Enter fullscreen mode Exit fullscreen mode

Restart fail2ban:

systemctl restart fail2ban
fail2ban-client status nginx-sqli
Enter fullscreen mode Exit fullscreen mode

What to Do When You Find Attacks

Step 1: Don't panic. Automated SQL injection scanners hit every public IP constantly. Finding these in your logs is normal — it doesn't mean you've been breached.

Step 2: Check your response codes. The real danger signal is a 200 response to a SQL injection attempt. If your app is returning 200 for requests like id=1'+OR+'1'='1, you may have a vulnerability.

Step 3: Check for successful exploitation. Look for unusual data sizes in responses, or 200s followed by large response bodies to suspicious queries.

Step 4: Block repeat offenders. Use fail2ban (above) or Cloudflare's firewall rules to block IPs making repeated SQLi attempts.

Beyond grep: Continuous Log Monitoring

Manually grepping works for spot checks, but production systems need continuous monitoring. You want to be alerted when a new attack campaign starts — not find out days later.

For automated scanning, tools like LogAudit continuously parse your nginx logs and flag SQL injection patterns (along with 12 other security and compliance rules) in real time. It's a lightweight alternative to standing up a full ELK stack when you just need security visibility without the operational overhead.

Summary

SQL injection attempts in nginx logs follow predictable patterns. With a few grep commands you can identify whether you're being probed, and with fail2ban you can automatically block persistent attackers.

The most important number to watch: how many 200 responses are you sending to SQLi attempts? Zero is what you want. Anything else needs immediate investigation.


LogAudit automatically detects SQL injection patterns, PII exposure, API key leaks, and 10 other security issues in your nginx/apache logs. Free tier available.

Top comments (0)