是否存在一种万能函数,可以很好地为SQL注入和XSS攻击清除用户输入,同时仍然允许某些类型的HTML标记?


当前回答

有一个技巧可以帮助您在特定情况下使用/mypage?id=53,在WHERE子句中使用id是为了确保id确实是一个整数,如下所示:

if (isset($_GET['id'])) {
  $id = $_GET['id'];
  settype($id, 'integer');
  $result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
  # now use the result
}

但当然,这只排除了一个特定的攻击,所以阅读所有其他的答案。(是的,我知道上面的代码不是很好,但它显示了具体的防御。)

其他回答

用PHP清除用户输入的方法:

Use Modern Versions of MySQL and PHP. Set charset explicitly: $mysqli->set_charset("utf8");manual $pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);manual $pdo->exec("set names utf8");manual $pdo = new PDO( "mysql:host=$host;dbname=$db", $user, $pass, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" ) );manual mysql_set_charset('utf8') [deprecated in PHP 5.5.0, removed in PHP 7.0.0]. Use secure charsets: Select utf8, latin1, ascii.., dont use vulnerable charsets big5, cp932, gb2312, gbk, sjis. Use spatialized function: MySQLi prepared statements: $stmt = $mysqli->prepare('SELECT * FROM test WHERE name = ? LIMIT 1'); $param = "' OR 1=1 /*";$stmt->bind_param('s', $param);$stmt->execute(); PDO::quote() - places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver:$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);explicit set the character set$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);disable emulating prepared statements to prevent fallback to emulating statements that MySQL can't prepare natively (to prevent injection)$var = $pdo->quote("' OR 1=1 /*");not only escapes the literal, but also quotes it (in single-quote ' characters) $stmt = $pdo->query("SELECT * FROM test WHERE name = $var LIMIT 1"); PDO Prepared Statements: vs MySQLi prepared statements supports more database drivers and named parameters: $pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);explicit set the character set$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);disable emulating prepared statements to prevent fallback to emulating statements that MySQL can't prepare natively (to prevent injection) $stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1'); $stmt->execute(["' OR 1=1 /*"]); mysql_real_escape_string [deprecated in PHP 5.5.0, removed in PHP 7.0.0]. mysqli_real_escape_string Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection. But recommended to use Prepared Statements because they are not simply escaped strings, a statement comes up with a complete query execution plan, including which tables and indexes it would use, it is a optimized way. Use single quotes (' ') around your variables inside your query. Check the variable contains what you are expecting for: If you are expecting an integer, use: ctype_digit — Check for numeric character(s);$value = (int) $value;$value = intval($value);$var = filter_var('0755', FILTER_VALIDATE_INT, $options); For Strings use: is_string() — Find whether the type of a variable is stringUse Filter Function filter_var() — filters a variable with a specified filter:$email = filter_var($email, FILTER_SANITIZE_EMAIL);$newstr = filter_var($str, FILTER_SANITIZE_STRING);more predefined filters filter_input() — Gets a specific external variable by name and optionally filters it:$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS); preg_match() — Perform a regular expression match; Write Your own validation function.

不。你不能在没有任何上下文的情况下过滤数据。有时你想把SQL查询作为输入,有时你想把HTML作为输入。

您需要筛选白名单上的输入——确保数据符合您所期望的某些规范。然后,您需要在使用它之前对它进行转义,这取决于您使用它的上下文。

为SQL转义数据(防止SQL注入)的过程与为(X)HTML转义数据(防止XSS)的过程非常不同。

不,没有。

首先,SQL注入是一个输入过滤问题,而XSS是一个输出转义问题——因此您甚至不会在代码生命周期中同时执行这两个操作。

基本经验法则

对于SQL查询,绑定参数 使用strip_tags()过滤掉不需要的HTML 使用htmlspecialchars()转义所有其他输出,并注意这里的第2和第3个参数。

PHP过滤器扩展有许多检查外部用户输入所需的功能&它的设计是为了使数据消毒更容易和更快。

PHP过滤器可以轻松地清理和验证外部输入。

PHP 5.2引入了filter_var函数。

它支持大量的SANITIZE, VALIDATE过滤器。