TL;DR - A default ModSecurity rule on my server is generating a 500 Internal Server Error when trying to submit a PHP form field that contains the word “from”, since it’s seeing it as a possible SQL injection, even though I’m using PDO prepared statements. Not sure of the best way to fix this.
When trying to submit a form that has a textarea that contains “changed email from x to x” I’m getting a 500 Internal Server error, and I’ve narrowed it down the word “from” being the culprit. Based on what I’m seeing in the logs it appears as though the form submission is being seen as a possible SQL injection. I disabled this particular rule (300016) as a test and the form started working properly.
From Apache error log:
[:error] [pid 39495] [client x.x.x.x] ModSecurity: Access denied with code 500 (phase 2). Pattern match "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\\\\(.*from)" at ARGS:notes. [file "/etc/apache2/conf.d/modsec/modsec2.user.conf"] [line "247"] [id "300016"] [rev "2"] [msg "Generic SQL injection protection"] [severity "CRITICAL"] [hostname "xxxxxxxxxx.com"] [uri "/path/to/page/with/form.php"] [unique_id "WiGVQoP7XCbNIjL9nZzrKAAAAAo"]
From ModSecurity audit log:
Message: Access denied with code 500 (phase 2). Pattern match "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\\(.*from)" at ARGS:notes. [file "/etc/apache2/conf.d/modsec/modsec2.user.conf"] [line "247"] [id "300016"] [rev "2"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]
Action: Intercepted (phase 2)
Stopwatch: 1512150338540293 2147 (- - -)
Stopwatch2: 1512150338540293 2147; combined=549, p1=96, p2=449, p3=0, p4=0, p5=3, sr=32, sw=1, l=0, gc=0
Producer: ModSecurity for Apache/2.9.0 (http://www.modsecurity.org/).
Server: Apache
Engine-Mode: "ENABLED"
ModSecurity rule:
#Generic SQL sigs
SecRule REQUEST_URI "!(/node/[0-9]+/edit|/forum/posting\.php|/admins/wnedit\.php|/alt_doc\.php\?returnUrl=.*edit|/admin/categories\.php\?cPath=.*|modules\.php\?name=Forums&;file=posting&;mode=.*)" "chain,id:300016,t:lowercase,rev:2,severity:2,msg:'Generic SQL injection protection'"
SecRule ARGS "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\(.*from)"
- The ModSecurity rule seems a bit restrictive, however I would prefer to not disable it entirely because it definitely has some value (I believe this rule was automatically implemented when my WHM/cPanel was upgraded recently)
- One of the solutions I’ve seen is to disable this particular rule for the file (or folder) I’m trying to access, but that only solves the problem for this one section of one domain, and other users on my server could still run into this issue
- The form that’s generating the error is using PDO prepared statements
I’m not very experienced with ModSecurity and I’m really not sure what the best way to solve this would be, so I figured I would see if anyone here has any suggestions.
PS - Since the form works when the ModSecurity rule is disabled I don’t think the form itself is the issue, but just in case…
Form:
<form method="post">
<textarea class="form-control" placeholder="Notes" name="notes" cols="40" rows="10" wrap="VIRTUAL">
<input class="form-control" type="submit" name="Submit" value="Save Changes">
</form>
Form Processing:
$notes = $_POST['notes'];
$stmt = $pdo->prepare("
UPDATE links
SET notes = :notes
WHERE id = :link_id");
$stmt->bindValue('notes', $notes, PDO::PARAM_LOB);
$stmt->bindValue('link_id', $link_id, PDO::PARAM_INT);
$stmt->execute();