Article Author: hl0reyIn this article, we discuss PDO SQL injection and its implications. PDO (PHP Data Objects) provides a secure way to execute
“Use PDO to prevent SQL injection.” Anyone who has studied PHP has likely heard this phrase. Does merely including PDO in the code suffice? The answer is definitely no. Next, I will introduce some situations where using PDO still does not prevent SQL injection.
First Situation
As Yan Zishuang, a senior, once said:
For code auditing, encountering PDO precompilation basically means saying goodbye to injection vulnerabilities. We are justified in believing that a website mostly using PDO precompilation throughout will not employ string concatenation to execute SQL statements at critical points, thus such a vulnerability might have been purposefully left by the author. — As per a senior’s words
When PDO executes SQL statements directly using query or exec without precompilation, it does not prevent injection.
1. Using query:
Code language: javascriptCopy
"; die();}?>
Test Process
1. Open Wireshark in the virtual machine where the database resides, set filter condition to MySQL
2. Execute normally, search for user with username hl0rey
3. Then, check the packet capture; two query requests can be seen.
The first request sets the encoding for communication with the MySQL server, namely set names gbk
The second query request pertains to our search for the user named hl0rey
4. Input a single quote and query again. As expected, the response is blank.
5. Inspect the packets captured; the same two query requests are still observed.
Focus on the second packet. PHP merely adds a backslash to the single quote and submits it for execution in MySQL, hence no results for the user are found.
Thus far, it is clear that PHP performs a local emulation of escape, analogous to applying mysqli_real_escape_string filter on user input variables.
6. Add %df
before the single quote, query again. Still no response.
Observe the captured packets, showing two query requests and an error.
First, review this error.
An extra single quote leads to an error in the statement.
Now, review the SQL statement in the second query request.
Manually test further by inputting %df' or 1 --
, revealing all information in the database.
This confirms the presence of SQL injection.
Conclusion
1. To avoid such issues, configure PHP to not perform local emulation precompilation. By uncommenting the fourth line in the code, PHP will strive not to conduct local emulation precompilation.
2. Testing shows that this issue exists across all PHP versions (default configuration). Any local simulation of SQL precompilation will present this problem. Notably, PHP 5.2.17 still exhibits wide-byte injection even when local emulation precompilation is set to false, implying continued reliance on simulated precompilation. I speculate this might be due to low PHP version and high MySQL version. If anyone knows the real reason, I would appreciate guidance.