【转】Laravel 防止XSS攻击

目前我们的项目中存在非常严重的 XSS 安全漏洞。作为一个合格的 Web 开发工程师,必须遵循一个安全原则:

  • 永远不要信任用户提交的数据

XSS 也称跨站脚本攻击 (Cross Site Scripting),恶意攻击者往 Web 页面里插入恶意 JavaScript 代码,当用户浏览该页之时,嵌入其中 Web 里面的 JavaScript 代码会被执行,从而达到恶意攻击用户的目的。

一种比较常见的 XSS 攻击是 Cookie 窃取。我们都知道网站是通过 Cookie 来辨别用户身份的,一旦恶意攻击者能在页面中执行 JavaScript 代码,他们即可通过 JavaScript 读取并窃取你的 Cookie,拿到你的 Cookie 以后即可伪造你的身份登录网站。(扩展阅读 —— IBM 文档库:跨站点脚本攻击深入解析 )

有两种方法可以避免 XSS 攻击:

第一种,对用户提交的数据进行过滤
第二种,Web 网页显示时对数据进行特殊处理,一般使用 htmlspecialchars() 输出。

XSS 也称跨站脚本攻击 (Cross Site Scripting),恶意攻击者往 Web 页面里插入恶意 JavaScript 代码,当用户浏览该页之时,嵌入其中 Web 里面的 JavaScript 代码会被执行,从而达到恶意攻击用户的目的。

一种比较常见的 XSS 攻击是 Cookie 窃取。我们都知道网站是通过 Cookie 来辨别用户身份的,一旦恶意攻击者能在页面中执行 JavaScript 代码,他们即可通过 JavaScript 读取并窃取你的 Cookie,拿到你的 Cookie 以后即可伪造你的身份登录网站。(扩展阅读 —— IBM 文档库:跨站点脚本攻击深入解析

有两种方法可以避免 XSS 攻击:

  • 第一种,对用户提交的数据进行过滤;
  • 第二种,Web 网页显示时对数据进行特殊处理,一般使用 htmlspecialchars() 输出。

Laravel 的 Blade 语法 {{ }} 会自动调用 PHP htmlspecialchars 函数来避免 XSS 攻击

Blade 的 {!! !!} 语法是直接数据,不会对数据做任何处理。在我们这种场景下,因为业务逻辑的特殊性,第二种方法不适用,我们将使用第一种方法,对用户提交的数据进行过滤来避免 XSS 攻击。

HTMLPurifier#

HTMLPurifier 本身就是一个独立的项目,运用『白名单机制』对 HTML 文本信息进行 XSS 过滤。

『白名单机制』指的是使用配置信息来定义『HTML 标签』、『标签属性』和『CSS 属性』数组,在执行 clean() 方法时,只允许配置信息『白名单』里出现的元素通过,其他都进行过滤。

如配置信息:

‘HTML.Allowed’ => ‘div,em,a[href|title|style],ul,ol,li,p[style],br’,
‘CSS.AllowedProperties’ => ‘font,font-size,font-weight,font-style,font-family’,

当用户提交时:


文章内容

会被解析为:


文章内容

以下内容因为未指定会被过滤:

someproperty 未指定的 HTML 属性
color 未指定的 CSS 属性
script 未指定的 HTML 标签

HTMLPurifier for Laravel 5#

HTMLPurifier for Laravel 是对 HTMLPurifier 针对 Laravel 框架的一个封装。本章节中,我们将使用此扩展包来对用户内容进行过滤。
1. 安装 HTMLPurifier for Laravel 5#

使用 Composer 安装:

  • $ composer require “mews/purifier:~2.0”
  1. 配置 HTMLPurifier for Laravel 5#

命令行下运行

  • $ php artisan vendor:publish –provider=”Mews\Purifier\PurifierServiceProvider”

请将配置信息替换为以下:

config/purifier.php

<?php

return [
    'encoding'      => 'UTF-8',
    'finalize'      => true,
    'cachePath'     => storage_path('app/purifier'),
    'cacheFileMode' => 0755,
    'settings'      => [
        'user_topic_body' => [
            'HTML.Doctype'             => 'XHTML 1.0 Transitional',
            'HTML.Allowed'             => 'div,b,strong,i,em,a[href|title],ul,ol,ol[start],li,p[style],br,span[style],img[width|height|alt|src],*[style|class],pre,hr,code,h2,h3,h4,h5,h6,blockquote,del,table,thead,tbody,tr,th,td',
            'CSS.AllowedProperties'    => 'font,font-size,font-weight,font-style,margin,width,height,font-family,text-decoration,padding-left,color,background-color,text-align',
            'AutoFormat.AutoParagraph' => true,
            'AutoFormat.RemoveEmpty'   => true,
        ],
    ],
];

配置里的 user_topic_body 是我们为话题内容定制的,配合 clean() 方法使用:

  • topic>body=clean( topic->body, ‘user_topic_body’);

开始过滤#

一切准备就绪,现在我们只需要在数据入库前进行过滤即可:

app/Observers/TopicObserver.php

<?php

namespace App\Observers;

use App\Models\Topic;

// creating, created, updating, updated, saving,
// saved,  deleting, deleted, restoring, restored

class TopicObserver
{
    public function saving(Topic $topic)
    {
        $topic->body = clean($topic->body, 'user_topic_body');

        $topic->excerpt = make_excerpt($topic->body);
    }
}

HTMLPurifier#

HTMLPurifier 本身就是一个独立的项目,运用『白名单机制』对 HTML 文本信息进行 XSS 过滤。

『白名单机制』指的是使用配置信息来定义『HTML 标签』、『标签属性』和『CSS 属性』数组,在执行 clean() 方法时,只允许配置信息『白名单』里出现的元素通过,其他都进行过滤。

如配置信息:

'HTML.Allowed' => 'div,em,a[href|title|style],ul,ol,li,p[style],br',
'CSS.AllowedProperties'    => 'font,font-size,font-weight,font-style,font-family',

当用户提交时:

<a someproperty="somevalue" href="http://example.com" style="color:#ccc;font-size:16px">
    文章内容<script>alert('Alerted')</script>
</a>

会被解析为:

<a href="http://example.com" style="font-size:16px">
    文章内容
</a>

以下内容因为未指定会被过滤:

  1. someproperty 未指定的 HTML 属性
  2. color 未指定的 CSS 属性
  3. script 未指定的 HTML 标签

HTMLPurifier for Laravel 5#

HTMLPurifier for Laravel 是对 HTMLPurifier 针对 Laravel 框架的一个封装。本章节中,我们将使用此扩展包来对用户内容进行过滤。

1. 安装 HTMLPurifier for Laravel 5#

使用 Composer 安装:

  • $ composer require “mews/purifier:~2.0”

2. 配置 HTMLPurifier for Laravel 5#

命令行下运行

  • $ php artisan vendor:publish –provider=”Mews\Purifier\PurifierServiceProvider”

请将配置信息替换为以下:

config/purifier.php

<?php

return [
    'encoding'      => 'UTF-8',
    'finalize'      => true,
    'cachePath'     => storage_path('app/purifier'),
    'cacheFileMode' => 0755,
    'settings'      => [
        'user_topic_body' => [
            'HTML.Doctype'             => 'XHTML 1.0 Transitional',
            'HTML.Allowed'             => 'div,b,strong,i,em,a[href|title],ul,ol,ol[start],li,p[style],br,span[style],img[width|height|alt|src],*[style|class],pre,hr,code,h2,h3,h4,h5,h6,blockquote,del,table,thead,tbody,tr,th,td',
            'CSS.AllowedProperties'    => 'font,font-size,font-weight,font-style,margin,width,height,font-family,text-decoration,padding-left,color,background-color,text-align',
            'AutoFormat.AutoParagraph' => true,
            'AutoFormat.RemoveEmpty'   => true,
        ],
    ],
];

配置里的 user_topic_body 是我们为话题内容定制的,配合 clean() 方法使用:

$topic->body = clean($topic->body, 'user_topic_body');

开始过滤#

一切准备就绪,现在我们只需要在数据入库前进行过滤即可:

app/Observers/TopicObserver.php

<?php

namespace App\Observers;

use App\Models\Topic;

// creating, created, updating, updated, saving,
// saved,  deleting, deleted, restoring, restored

class TopicObserver
{
    public function saving(Topic $topic)
    {
        $topic->body = clean($topic->body, 'user_topic_body');

        $topic->excerpt = make_excerpt($topic->body);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值