SQL Injection Attempt Blocked – 3 Causes and Fixes
SQL injection block warnings appear when input contains malicious patterns. Most often it's a legitimate query misinterpreted. Here's what to check.
1. WAF False Positive (Most Common)
You're running a legitimate query—maybe a search with SELECT * FROM products WHERE name LIKE '%widget%'—and suddenly the app returns a 406 or a blank page. Your logs show "SQL injection attempt blocked." What's actually happening here is that your Web Application Firewall (WAF)—like Cloudflare, AWS WAF, or mod_security—sees the SQL keyword pattern in the request body or URL and thinks it's an attack.
WAFs use regex patterns that trigger on words like SELECT, INSERT, UNION, or single quotes in query strings. If your application sends these in legitimate form data or API calls, you'll get blocked.
Fix: Whitelist the specific URL or parameter
- Identify the exact endpoint that triggers the block. Check your WAF logs for the rule ID and matched data.
- Create a whitelist rule in your WAF for that specific path and parameter pattern. For example, in Cloudflare, go to Security > WAF > Custom Rules and add a rule that skips the SQL injection check for
http.request.uri.path eq "/api/search" and http.request.method eq "POST". - If you're using Apache mod_security, open your
modsecurity.conffile and add:
SecRuleRemoveById 942100 # Replace 942100 with the actual rule ID from your logs - Test the request again with a typical query. Don't just disable the rule globally—scope it to the specific endpoint or user agent. Otherwise you're leaving the door open for actual attacks on other pages.
Why this works: WAFs are great at catching known attack patterns, but they lack context. By whitelisting the exact URL and parameter, you tell the WAF "this is safe here" without compromising other routes.
2. Application Sending Unsanitized Input to Database (Legit Vulnerability)
Sometimes the WAF is right—your code is actually vulnerable. You might be building SQL queries by concatenating user input like this:
// Bad code that triggers WAF
$query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "'";
If a user enters ' OR '1'='1, the WAF sees the single quote and SQL operator and blocks it before it even reaches the database. The reason the WAF blocks this is that it's a textbook SQL injection—and you should fix the code, not the WAF.
Fix: Use parameterized queries everywhere
- Rewrite all database queries using prepared statements. In PHP with MySQLi:
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?"); $stmt->bind_param("s", $_POST['username']); $stmt->execute(); $result = $stmt->get_result(); - For Python with SQLite:
cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) - For Java with JDBC:
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?"); stmt.setString(1, username); ResultSet rs = stmt.executeQuery(); - Remove all string concatenation from database queries. Even if you think input is "safe" because it comes from an internal API—don't. Use prepared statements everywhere, every time.
Why this works: Parameterized queries separate SQL code from data. The database engine treats the input as a literal value, not executable code. The WAF will still see the same HTTP request, but now the input doesn't contain raw SQL—it's just a string parameter. The WAF stops flagging it because it no longer sees ' OR '1'='1 as executable SQL—it sees a harmless string like john. This is the real fix.
3. Incorrect Character Encoding or Escaping
Less common, but I've seen this one on legacy systems running PHP 5.x or MySQL with SET NAMES instead of proper connection encoding. Here's the scenario: you're using a prepared statement but still seeing false positives. The issue is that your application or database connection uses a character encoding that doesn't handle special characters correctly. For example, if you send a query with % as part of a LIKE search, and the WAF interprets that as part of a SQL injection pattern.
Fix: Set consistent UTF-8 encoding
- Set your database connection to UTF-8 explicitly. In PHP with MySQLi:
$conn->set_charset("utf8mb4"); - Ensure your HTML pages declare UTF-8 in the
<head>:
<meta charset="UTF-8"> - If you're on MySQL or MariaDB, check the table collation matches:
utf8mb4_unicode_ciis a good default. - For any input that includes special characters (like quotes, backslashes, or percent signs), make sure you're not double-escaping them. Some frameworks auto-escape inputs; if you also manually escape with
mysql_real_escape_string, you'll get escaped backslashes in your data. That can confuse the WAF too.
Why this works: When the encoding is mismatched, the WAF may interpret multi-byte characters as two separate characters—one of which could be a single quote. This triggers the SQL injection rule even though the actual intent is benign. Proper UTF-8 encoding prevents this misinterpretation.
Quick Reference Table
| Cause | Signs | Fix |
|---|---|---|
| WAF false positive | Blocked on legitimate queries with SQL keywords; WAF logs show rule match | Whitelist specific endpoint/parameter in WAF |
| Unsanitized input in queries | Code uses string concatenation for SQL; user input contains quotes | Replace with parameterized queries (prepared statements) |
| Character encoding issue | Blocks on special characters like %, even with prepared statements | Set connection to UTF-8, verify collation, avoid double-escaping |
Was this solution helpful?