我应该使用 htmlspecialchars 吗?


Should I be using htmlspecialchars?

我似乎很难理解何时使用htmlspecialchars()。

假设我在插入数据时执行以下操作:

$_POST = filter_input_array(INPUT_POST, [
    'name' => FILTER_SANITIZE_STRING,
    'homepage' => FILTER_DEFAULT // do nothing
]);
$course = new Course();
$course->name = trim($_POST['name']);
$course->homepage = $_POST['homepage']; // may contain unsafe HTML
$courseDAO = DAOFactory::getCourseDAO();
$courseDAO->addCourse($course);  // simple insert statement

当我输出时,我会执行以下操作:

$courseDAO = DAOFactory::getCourseDAO();
$course = $courseDAO->getCourseById($_GET['id']);
?>
<?php ob_start() ?>
<h1><?= $course->name ?></h1>
<div class="homepage"><?= $course->homepage ?></div>
<?php $content = ob_get_clean() ?>
<?php include 'layout.php' ?>

我希望浏览器$course->homepage处理并呈现为 HTML。

我一直在阅读有关这个问题的答案。我应该在这里的任何地方使用htmlspecialchars()吗?

(从安全 POV 中)有三种类型的数据可以输出到 HTML 中:

  • 发短信
  • 受信任的网页
  • 不受信任的网页

(请注意,HTML 属性和某些元素是特殊情况,例如,onclick 属性需要 HTML 编码的 JavaScript,因此您的数据需要 HTML 安全和 JS 安全)。

如果是文本,则使用htmlspecialchars将其转换为 HTML。

如果它是受信任的 HTML,则只需输出它。

如果它是不受信任的 HTML,那么您需要对其进行清理以使其安全。这通常意味着使用 DOM 解析器解析它,然后删除所有不在白名单上显示为安全的元素和属性(某些属性可能是特殊情况以过滤而不是剥离),然后将 DOM 转换回 HTML。像HTML Purifier这样的工具可以做到这一点。

$course->主页 = $_POST['主页'];//可能包含不安全的 HTML

我希望浏览器将$course->主页视为HTML并呈现为HTML。

然后你有第三种情况,需要过滤 HTML。

看起来您正在数据库中存储原始 html,然后稍后将其呈现到页面。

将数据存储到数据库中之前,我不会对数据进行过滤,您可能会损坏用户的输入,并且如果从未存储过原始数据,则无法检索原始数据。

如果您希望浏览器将输出的数据视为html,则不,htmlspecialchars不是解决方案。

但是,值得考虑使用条带标签来删除脚本标签以对抗XSS。使用striptags,您必须将允许的标签列入白名单,这显然很乏味,但非常安全。

可能也值得你看看tinyMCE,看看他们如何处理这些事情

输出纯 HTML,

如果您确定内容。 在所有其他资源上使用 HTMLSpecialchar,尤其是对于用户输入以防止安全问题。