我正在使用php,mysql和smarty进行开发,并且有用户可以进行评论等操作的地方。在将数据插入数据库之前,我已经对字符进行了转义以防止SQL注入。还需要做什么呢?
我正在使用php,mysql和smarty进行开发,并且有用户可以进行评论等操作的地方。在将数据插入数据库之前,我已经对字符进行了转义以防止SQL注入。还需要做什么呢?
XSS主要是关于HTML转义(*). 无论从数据库、直接从用户输入、从文件还是从其他地方获得的纯文本字符串,只要将其放入HTML页面中,就需要对其进行转义。
最小化的HTML转义是将所有的&
符号转换为&
,所有的<
符号转换为<
。当您将某些内容放入属性值时,还需要对用于分隔属性的引号字符进行转义,通常使用的是"
变为"
。总是转义双引号("
)和单引号撇号('
)不会有任何问题,有些人还会将>
转义为>
,虽然这仅在XHTML的一个角落案例中才是必需的。
任何一个好的面向Web的语言都应该提供一个函数来完成这个任务。例如,在PHP中它是htmlspecialchars()
:
<p> Hello, <?php htmlspecialchars($name); ?>! </p>
在Smarty模板中,它是escape
修饰符:
<p> Hello, {$name|escape:'html'}! </p>
通常情况下,95%的情况都需要HTML转义(相对于允许原始HTML标记的情况比较罕见),所以这应该是默认设置。新一代的模板语言已经认识到,将HTML转义设为选择性开启会导致无尽的XSS漏洞,因此默认情况下进行HTML转义。
您可以通过更改默认修饰符为html
来使Smarty表现得像这样。(除非你真的知道自己在做什么,否则不要使用他们建议的htmlall
,否则会破坏所有非ASCII字符。)
无论如何,千万不要陷入常见的PHP错误中,即在处理输入之前或将其放入数据库之前对其进行HTML转义或“净化”以供HTML使用。这是执行输出阶段编码的错误位置,会引发各种问题。如果要验证输入以确保它符合特定应用程序的要求,则可以这样做,但在此阶段清除或转义“特殊”字符是不适当的。
*:其他XSS方面的问题出现在以下情况:(a)实际上您想允许用户发布HTML,在这种情况下,您需要将其削减到可接受的元素和属性,这是一个复杂的过程,通常由HTML Purifier之类的库完成,即使如此,也可能会出现漏洞。替代方案可能会更简单。 (b)当您允许用户上传文件时,这是非常难以保证安全的。
您需要确保人们无法在评论中发布JavaScript代码或可怕的HTML。我建议您禁止除非非常基本的标记之外的任何内容。
如果评论不应包含任何标记,则执行
echo htmlspecialchars($commentText);
这应该足够了,但它非常粗糙。更好的方法是在将其放入数据库之前对所有输入进行清理。PHP strip_tags() 函数可以帮助您入手。
如果您想允许 HTML 注释,但又要保证安全,可以尝试使用 HTML Purifier。
在将数据放入数据库之前,您不应修改用户输入的数据。修改应在输出到网站时进行。您不想丢失原始数据。
在将其输出到网站时,您需要使用类似于htmlspecialchars("my output & stuff", ENT_QUOTES, 'UTF-8')
的东西将特殊字符转义为HTML代码--确保指定您正在使用的字符集。这个字符串将被翻译成my output & stuff
供浏览器阅读。
防止 SQL 注入的最佳方法就是不要使用接受用户输入的动态 SQL。相反,将输入作为参数传递;这样它将被强类型化,无法注入代码。