Review an intentionally vulnerable plugin in WordPress
SQL injection Vulnerability
This vulnerability can be exploited by an attacker to modify your database queries, read some sensitive info from the database or even execute some commands on the database server. If the plugin allows an input from an untrusted user then attacker can use that as an advantage and add some malicious code as an input and alter some queries.
Let’s look at the first SQL injection vulnerability.
SQL injection vulnerability is caused by the incorrect usage of the wpdb::prepare() method on line 42:
//vulnerable usage $wpdb->query( $wpdb->prepare( "INSERT INTO login_audit (login, pass, ip, time) VALUES ('$login', '$pass', '$ip', '$time')" ) );
From WordPress 3.5, you need to pass two arguments in your prepare() method. When you use $wpdb->prepare(), use placeholders, such as %s and %d, as your query string’s first argument. %d is used for decimal/integer values and %s is used for string values.
The actual variables are passed in a separate argument and escaped before actually creating the query.
SQL injection Vulnerability Fix
This is how you can fix it:
//correct usage $wpdb->query( $wpdb->prepare( "INSERT INTO login_audit (login, pass, ip, time) VALUES (%s, %s, %s, %s)", $login, $pass, $ip, $time ) );
Refer to this vulnerable.php file on Github. On lines 102 and 127, you’ll find more SQL injection vulnerabilities. Those are caused by incorrectly escaping user input.
If you want to use the esc_sql() function escape the user input then it should be used within quotes. In those queries, the user input is not used in a quoted context of an SQL query. Those queries are using inputs from users as a numeric arguments without enclosing in quotes!
Credit goes to Jon Cave’s post: How to fix the intentionally vulnerable plugin