本文概述
- Parsedown解决方案
- 其他解析器库的解决方案
当然, 你已经听说过PHP函数htmlentities, htmlspecialchars等, 这些函数允许你对HTML上使用的符号进行编码和解码, 但是如果你没有太多时间, 则无法自行使用它。主要是, 解析器应提供正确的功能, 但是它们也必须灵活且有用, 但是有时由于项目的特性, 它可能无法100%正确地工作。例如, 以下降价促销:
# Hello WorldI am a programmer and i wrant to write code. I don't write code with bad intentions, just share my knowledge```html<
script>
alert("First alert");
<
/script>
```<
script>
alert("second alert");
<
/script>
<
img src="http://url.to.file.which/not.exist" onerror=alert(document.cookie);
>
使用cebeb的markdown解析器将其解析为HTML, 并在浏览器中呈现, 将仅发出” 第二警报” 警报。这是因为解析器足够聪明, 可以将代码块内的所有内容自动转换为相应的HTML实体。但是, 任何代码块之外的脚本标签仍被浏览器解释为JavaScript, 这显然是一个问题, 从不存在的文件加载的img也将被触发。
在本文中, 我们将向你展示如何防止JavaScript插入
Parsedown解决方案通过解析提供在解析中的markdown内的所有标记, Parsedown使事情变得非常容易。但是, 默认情况下未启用它, 并且不足以阻止所有XSS攻击方式。因此, 如果你想使用安全版本的Parsedown, 我们建议你使用secureparsedown软件包。 Aidan Woods对原始parsedown库所做的更改提供了一种安全模式的实现, 该模式将保护HTML不受XSS的攻击。
在这种情况下, 具有Aidan更改的1.7.0版本尚未发布, 因此直到你可以从以下软件包下载parsedown的安全版本之日:
composer require aidantwoods/secureparsedown
使用此版本的优点是它将使用Parsedown的最新版本, 但也会创建安全模式。或者, 如果愿意, 请手动修改composer.json文件, 然后运行composer install:
{"require": {"aidantwoods/secureparsedown": "^1.0"}}
安装完成后, 像平常一样使用Parsedown, 不要忘记使用setMarkupEscaped和setSafeMode方法来提供安全的HTML来呈现:
<
?phpuse Aidantwoods\SecureParsedown\SecureParsedown;
$markdown = "# Title <
script>
alert('XSS Attack ...');
<
/script>
";
$Parsedown = new SecureParsedown;
// Escape the input markdown to prevent any html from being and enable parsedown in safe mode$Parsedown->
setSafeMode(true);
// Secure HTMLecho $Parsedown->
text($markdown);
这很方便, 因为Markdown内部所有解释为HTML的文本都将转换为其无害的html实体表示形式(这可以防止XSS攻击)。但是, 此功能仅在该库中可用。如果要防止出现某些特定标签, 请也从其他解析器库中实施解决方案。
其他解析器库的解决方案如果你在PHP中使用其他Markdown解析器, 则它可能不会具有Parsedown的相同功能。在这种情况下, 你将需要安装htmlpurifier库。 HTML Purifier是用PHP编写的符合标准的HTML过滤器库。 HTML Purifier不仅会使用经过全面审核, 安全且允许的白名单删除所有恶意代码(更名为XSS), 还将确保你的文档符合标准, 这只有在全面了解W3C规范的情况下才能实现。
要使用Composer在项目中安装htmlpurifier, 请在终端上执行以下命令:
composer require "ezyang/htmlpurifier":"dev-master"
使用Composer将库安装到项目中之后, 你将可以轻松使用它。通过从解析器处理的markdown生成的HTML中删除脚本标签来实现目标的最简单方法是, 通过使用选项HTML.ForbiddenElements禁止特定标签(每个标签都是参数数组的一项):
<
?php // The source of your markdown$markdown = "# Title <
script>
alert('Super unsafe markdown ...');
<
/script>
";
// Create an instance of your parser if available ...$parser = new YourFavoriteMarkdownParserExample();
// This contains the generated HTML from your markdown$parsedMarkdown = $parser->
parse($markdown);
// Initialize a config object of html purifier$config = HTMLPurifier_Config::createDefault();
// The HTML nodes that you want to prevent from being rendered// as second argument within an array$config->
set('HTML.ForbiddenElements', array('script', 'applet'));
// Initialize html purifier$purifier = new HTMLPurifier($config);
// Purify the generated HTML and// Use this safe HTML to display in the browser !$HTMLWithoutForbiddenTags = $purifier->
purify($parsedMarkdown);
另外, 如果你希望完全控制将要呈现的标签, 则可以决定可以呈现哪些HTML标签以及哪些属性:
<
?php // The source of your markdown$markdown = "# Title <
script>
alert('Super unsafe markdown ...');
<
/script>
";
$parser = new YourFavoriteMarkdownParserExample();
$config = \HTMLPurifier_Config::createDefault();
// Allow Text without tag e.g P or DIV (plain text, obviously necessary for markdown)$config->
set('Core.LexerImpl', 'DirectLex');
// Define manually which elements can be rendered// In this example, we allow (almost) all the basic elements that are converted with markdown$config->
set('HTML.Allowed', 'h1, h2, h3, h4, h5, h6, br, b, i, strong, em, a, pre, code, img, tt, div, ins, del, sup, sub, p, ol, ul, table, thead, tbody, tfoot, blockquote, dl, dt, dd, kbd, q, samp, var, hr, li, tr, td, th, s, strike');
// The attributes are up to you$config->
set('HTML.AllowedAttributes', 'img.src, *.style, *.class, code.class, a.href, *.target');
// Create an instance of the purifier with the configuration$purifier = new \HTMLPurifier($config);
// Print the purified HTML echo $purifier->
purify($parser->
text($markdown));
【如何防止XSS攻击并禁止PHP Markdown解析器生成的HTML中的特定标签】编码愉快!
推荐阅读
- 如何在Twig中有条件地扩展模板或导入宏
- 解决方案错误(名称为”yourtable.tablename”的表已存在)
- 如何在Symfony 3上的控制器(带有或不带有FOSUserBundle)中手动验证(登录)用户
- 如何在WinForms C#中使用LiveCharts库创建地理图表(GeoHeatMap)
- 如何在Microsoft Visual Studio Code中禁用自动补全和智能感知
- 为什么我在android studio中调试时看不到代码()
- 如何在2020年成为一名Android开发人员[关闭]
- Android NDK。从.PVR文件加载ETC1压缩纹理
- google-app-engine部署错误