PHP URL安全问题

PHP URL安全问题,php,mysql,htmlpurifier,Php,Mysql,Htmlpurifier,我想让用户在我的数据库中存储url我正在使用php mysql和htmlpurifier我想知道在我将坏数据存储到数据库中之前,下面的代码是否是过滤坏数据的好方法 下面是部分PHP代码 $url = mysqli_real_escape_string($mysqli, $purifier->purify(htmlspecialchars(strip_tags($_POST['url']))); 如果您担心SQL注入,这将清理它并防止它。否则,就不能确切地知道你在问什么。如果你担心SQL注

我想让用户在我的数据库中存储url我正在使用php mysql和htmlpurifier我想知道在我将坏数据存储到数据库中之前,下面的代码是否是过滤坏数据的好方法

下面是部分PHP代码

$url = mysqli_real_escape_string($mysqli, $purifier->purify(htmlspecialchars(strip_tags($_POST['url'])));

如果您担心SQL注入,这将清理它并防止它。否则,就不能确切地知道你在问什么。

如果你担心SQL注入,这将清理它并防止它。否则,你就不能确切地知道你在问什么。

你不需要调用
htmlspecialchars()
和数据上的
HTMLPurifier
——你这里实际上只有一个问题,那就是确保URL不包含SQL注入-
mysqli\u real\u escape\u string()
将对其进行排序

或者,如果要将数据输出到页面/HTML(而不是将其用作HTTP重定向头),则需要使用
htmlentities()
在输出数据时防止数据上出现XSS。黄金法则是上下文感知:

HTML实体编码对于 您将不受信任的数据放入 HTML文档的主体,例如 在标签里面。甚至有点 适用于不受信任的数据 转换为属性,特别是如果 你对使用引号很虔诚 围绕你的属性。但是HTML 如果您是 将不受信任的数据放入 标记任何位置或事件 处理程序属性,如onmouseover,或 在CSS内部或URL中。所以即使 您可以使用HTML实体编码方法 在任何地方,你仍然是最有可能的 易受XSS攻击。你必须使用 HTML部分的转义语法 文档您正在放置不受信任的数据 进入

要深入了解XSS预防,请查看

最好在使用数据之前对数据进行编码(针对相关攻击)(例如,MySQL转义字符串用于输入数据库以防止SQLi,HTML转义字符串用于输出到屏幕以防止XSS,而不是同时使用两者)。这允许您跟踪通过应用程序的数据流,并且您知道数据库中的所有数据都已准备好用于任何目的。例如,如果在将数据放入数据库之前对其进行HTML编码,则必须在将其用作HTTP头之前对其进行反编码

如果必须在数据进入数据库之前对其进行编码,请确保列名反映了这一点,以供将来的开发人员/维护人员使用

编辑:

根据VolkerK的评论,防止URL输出中出现XSS的最佳方法是检查协议-如果它与您允许的协议(可能是http/https)不匹配,请拒绝它:

$url = 'http://hostname/path?arg=value#anchor';

$parsedUrl = parse_url( $url );

if( $parsedUrl['scheme'] != 'http' ) {
    // reject URL
} else {
    $url = mysqli_real_escape_string( $mysqli, $url );
    $sql = "INSERT INTO table (url) VALUES ('$url')";
    // insert query
}

这样做的好处是在
情况下防止
javascript:alert('xss')
攻击。在
javascript:alert('xss')
上运行
htmlentities()
不会产生任何影响(因为
等有限的字符子集不会被转义),因此恶意用户可以在您的域上执行JS。

您不需要调用
htmlspecialchars()
和数据上的
HTMLPurifier
-这里实际上只有一个问题,那就是确保URL不包含SQL注入-
mysqli\u real\u escape\u string()
将对其进行排序

或者,如果要将数据输出到页面/HTML(而不是将其用作HTTP重定向头),则需要使用
htmlentities()
在输出数据时防止数据上出现XSS。黄金法则是上下文感知:

HTML实体编码对于 您将不受信任的数据放入 HTML文档的主体,例如 在标签里面。甚至有点 适用于不受信任的数据 转换为属性,特别是如果 你对使用引号很虔诚 围绕你的属性。但是HTML 如果您是 将不受信任的数据放入 标记任何位置或事件 处理程序属性,如onmouseover,或 在CSS内部或URL中。所以即使 您可以使用HTML实体编码方法 在任何地方,你仍然是最有可能的 易受XSS攻击。你必须使用 HTML部分的转义语法 文档您正在放置不受信任的数据 进入

要深入了解XSS预防,请查看

最好在使用数据之前对数据进行编码(针对相关攻击)(例如,MySQL转义字符串用于输入数据库以防止SQLi,HTML转义字符串用于输出到屏幕以防止XSS,而不是同时使用两者)。这允许您跟踪通过应用程序的数据流,并且您知道数据库中的所有数据都已准备好用于任何目的。例如,如果在将数据放入数据库之前对其进行HTML编码,则必须在将其用作HTTP头之前对其进行反编码

如果必须在数据进入数据库之前对其进行编码,请确保列名反映了这一点,以供将来的开发人员/维护人员使用

编辑:

根据VolkerK的评论,防止URL输出中出现XSS的最佳方法是检查协议-如果它与您允许的协议(可能是http/https)不匹配,请拒绝它:

$url = 'http://hostname/path?arg=value#anchor';

$parsedUrl = parse_url( $url );

if( $parsedUrl['scheme'] != 'http' ) {
    // reject URL
} else {
    $url = mysqli_real_escape_string( $mysqli, $url );
    $sql = "INSERT INTO table (url) VALUES ('$url')";
    // insert query
}

这样做的好处是在
情况下防止
javascript:alert('xss')
攻击。在
javascript:alert('xss')
上运行
htmlentities()
不会产生任何影响(因为
等有限的字符子集不会被转义),因此恶意用户可以在您的域上执行JS。

mysqli\u real\u escape\u string()
在将值放入数据库之前是必需的

为了防止XSS,应在显示时(以HTML格式),而不是在存储之前,对显示的所有数据调用
htmlspecialchars()

设想有一天您可能需要以HTML以外的格式输出数据;那么您将后悔调用了
htmlspecialchars()$fixed = $_POST;
$fixed = array_map('strip_tags', $fixed);
$fixed = array_map('mysqli_real_escape_string', $fixed);