在MySQL中插入文本字段时,何时需要转义双引号和/或特殊字符?
假设您有一个文本字段,其中包含具有双引号和/或&符号的说明或文章,是否有必要在将它们写入数据库表之前对其进行转义?
答案 0 :(得分:4)
MySQL(非标准)允许您使用双引号作为字符串文字的分隔符:
SELECT * FROM Accounts WHERE first_name = "Mel"
如果将内容插入到SQL字符串文字中,并且您的内容包含双引号,则会遇到麻烦:
SELECT * FROM Articles WHERE description = "She said, "Murder"!"
这可能是一个简单的事故,这可能只会导致语法错误。但攻击者也可以巧妙地利用这一点来让你的查询做你不想要的事情。
UPDATE Accounts SET PASSWORD = "..." WHERE account_name = "Mel" OR "X"="X"
如果攻击者声称他们的帐户名为Mel" OR "X"="X
,这可能会发生,这称为SQL注入。
但如果你逃避内容中的双引号,你可以打败他们的恶作剧:
UPDATE Accounts SET PASSWORD = "..." WHERE account_name = "Mel\" OR \"X\"=\"X"
但是,使用查询参数更简单,因此确保内容与SQL代码分开,并且永远不会导致意外的表达式:
UPDATE Accounts SET PASSWORD = ? WHERE account_name = ?
参数允许您使用占位符准备查询,然后在执行时为每个占位符提供动态内容。例如在PHP中使用PDO:
$sql = "UPDATE Accounts SET PASSWORD = ? WHERE account_name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute( array("...", "Mel") );
有关更多信息,请参阅我的演示文稿SQL Injection Myths and Fallacies。
答案 1 :(得分:1)
在将数据存储到数据库之前,您无需转义它们,但如果您正在编写代码来处理用户输入确保,您会阅读并完全理解{{3}的风险或者你是为了一个受伤的世界。
答案 2 :(得分:1)
如果要将字符串添加到由双引号限定的字符串文字中,则只需编码双引号。但是,你不应该使用双引号字符串文字,因为它们是其他数据库不支持的奇怪的非标准MySQL语法。
相反,使用单引号字符串文字(例如name='Mel'
),它们是ANSI标准SQL并且可以在任何地方使用。当然,你需要在值中转义单引号,而不是双引号。
在MySQL字符串文字中需要转义的另一个主要字符是\
,因为MySQL将其用作转义字符。这是非标准行为,非常烦人。
大多数webdev环境都会为您提供一个SQL-string-literal转义函数,因此您不必担心哪些确切的字符需要转义才能包含在查询中。例如,PHP中的mysql_real_escape_string
。但是,正如Bill所说,最好在可用的情况下使用参数化查询,因此您根本不必担心SQL转义。您的文本将作为原始字符串直接跳转到数据库中,而不会进行任何中间转义 - 转义步骤。
对于&符号,它们在SQL字符串文字中并不特殊,并且在从字符串创建查询时应该不进行转义。它们在HTML中很特殊,但您不希望数据库中包含HTML编码的数据。相反,在将字符串插入HTML内容时,使用HTML转义函数(如PHP中的htmlspecialchars
),而不是之前。
在表单提交或SQL构建阶段尝试从输入阶段对HTML内容进行HTML转义或“清理”内容是一种常见错误。但这是一个HTML输出阶段问题,只能在模板阶段解决。