Xra保护如何以及在何处应用于Laravel?

时间:2014-12-30 02:43:08

标签: php laravel laravel-4 xss

我想知道Laravel中提供的XSS保护(如果无论如何)。我在文档中找不到任何相关内容。

问题

我使用Eloquent's create()方法将数据插入数据库(模型中设置了$fillable / $guarded属性)。事实证明,我可以在任何形式的文本输入中自由地添加这样的东西:

<script>alert('Hacking Sony in 3...2...')</script>

,该值将插入数据库中。然后,当echo它时 - 显示警报。

可能的解决方案

现在,Laravel是一个非常好的框架,所以我认为必须是防止XSS开箱即用的东西。但是,我不知道那是什么。

如果我错了,处理这个问题的最佳方法是什么?

  • 我是否使用花哨的正则表达式验证来禁止特定字符?
  • 我是否每次mysql_real_escape_string()使用Input::get()
  • strip_tags()

视图级转义不够

我知道我可以使用Blade的triple curly brackets来逃避视图中的字符串,但这不是重点。让我更有意义的是不要让那些偷偷摸摸的混蛋进入数据库。

任何人都遇到过这个问题?

6 个答案:

答案 0 :(得分:31)

  

让我更有意义的是不要让那些偷偷摸摸的混蛋进入数据库。

实际上 - 事实并非如此。

XSS仅由刀片处理的原因是XSS攻击是输出问题。如果将<script>alert('Hacking Sony in 3...2...')</script>存储在数据库中,则不存在安全风险 - 它只是文本 - 它没有任何意义。

但是在HTML输出的上下文中 - 那么文本有意义,因此这就是过滤应该发生的地方。

此外 - XSS攻击可能是反射攻击,其中显示的数据不是来自数据库,而是来自其他来源。即上传的文件,网址等。如果您未能过滤所有不同的输入位置 - 您可能会遗漏某些内容。

Laravel鼓励您逃离所有输出,无论它来自哪里。由于特定原因,您应该只显式显示未过滤的数据 - 并且只有当您确定数据来自可信来源(即来自您自己的代码,而不是来自用户输入)时。

P.S。在Laravel 5中,默认的{{ }}将转义所有输出 - 这突出了这一点的重要性。

编辑:这是一个很好的讨论,还有关于为什么要过滤输出而不是输入的更多要点:html/XSS escape on input vs output

答案 1 :(得分:5)

据我所知,&#34;官方&#34; Laravel的立场是XSS prevention best practice is to escape output。因此,{{{ }}}

您可以使用Input::all()strip_tags()array_map()通过输入卫生补充输出:

$input = array_map('strip_tags', \Input::all());

答案 2 :(得分:4)

我检查了Laravel对xss攻击的保护{{{...}}}。它只是以这样的方式使用htmlentities()函数:htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false);只有正确使用它才能保护你免受xss的影响,这意味着不要在某些HTML标签中使用它,因为它会导致XSS攻击。例如:

$a = htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false); 
echo '<a href="'.$a.'">link</a>';

在这种情况下,它容易受到xss的攻击。<​​/ p>

答案 3 :(得分:2)

您还可以在验证之前过滤输入,例如,首先创建 /app/Common/Utility.php

<?php
namespace App\Common;
use Illuminate\Support\Facades\Input;

class Utility {
    public static function stripXSS()
    {
        $sanitized = static::cleanArray(Input::get());
        Input::merge($sanitized);
    }
    public static function cleanArray($array)
    {
        $result = array();
        foreach ($array as $key => $value) {
            $key = strip_tags($key);
            if (is_array($value)) {
                $result[$key] = static::cleanArray($value);
            } else {
                $result[$key] = trim(strip_tags($value)); // Remove trim() if you want to.
            }
       }
       return $result;
    }
}

并像你一样在你的控制器中使用

use App\Common\Utility;
public function store()
{
    Utility::stripXSS();
    // Remaining Codes
}

此代码将在验证前清理您的输入

答案 4 :(得分:2)

laravelgems/blade-escape通过添加不同的转义策略/指令来扩展Blade - @text@attr@css@js@param < / p>

示例:

<style>
.userPrefix:before { content: "@css($content)"; }
</style>
<div>
    <label class="userPrefix">@text($label)</label>
    <input type="text" name="custom" value="@attr($value)"/>
</div>
<a href="/profile?u=@param($username)">Profile</a>
<button onclick="callMyFunction('@js($username)');">Validate</button>
<script>
    var username = "@js($username)";
</script>

阅读他们的自述文件。 XSS非常棘手,有很多背景和方法。

测试页面 - http://laragems.com/package/blade-escape/test

答案 5 :(得分:0)

class XSSProtection
{
    /**
     * The following method loops through all request input and strips out all tags from
     * the request. This to ensure that users are unable to set ANY HTML within the form
     * submissions, but also cleans up input.
     *
     * @param Request $request
     * @param callable $next
     * @return mixed
     */
    public function handle(Request $request, \Closure $next)
    {
        if (!in_array(strtolower($request->method()), ['put', 'post'])) {
            return $next($request);
        }

        $input = $request->all();

        array_walk_recursive($input, function(&$input) {
            $input = strip_tags($input);
        });

        $request->merge($input);

        return $next($request);
    }
}