为 PDOStatement::execute() 方法准备要实行的SQL语句,SQL语句可以包含零个或多个命名(:name)或问号(?)参数标志,参数在SQL实行时会被替换。这样就没法粉碎sql语句的结构,不是拼接。
举例:
prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
你以为sql语句是
SELECT first_name, last_name FROM users WHERE user_id = id LIMIT 1;
于是使用 1 or 1=1#作为payload,以为下面的sql语句会被实行
SELECT first_name, last_name FROM users WHERE user_id = 1 or 1=1#
但实际上实行的是
SELECT first_name, last_name FROM users WHERE user_id = 1 or 1=1# LIMIT 1;
或者说 直接判断 1 or 1=1# 是不是数字型参数,不是的话根本就不会去实行,也就安全了。