php 在 Laravel 中如何以及在哪里应用 XSS 保护?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27698977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:28:44  来源:igfitidea点击:

How and where can XSS protection be applied in Laravel?

phplaravellaravel-4xss

提问by lesssugar

I wonder how (if anyhow) is XSS protection provided in Laravel. I couldn't find anything about it in the documentation.

我想知道 Laravel 中如何(如果有的话)提供 XSS 保护。我在文档中找不到任何关于它的信息。

Problem

问题

I am using Eloquent'screate()method to insert data into database ($fillable/$guardedproperties are set in the models). As it turns out, I can freely put something like this in any form's text input:

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

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

and the value will be inserted in the database. Then, when echoing it - the alert is shown.

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

Possible solutions

可能的解决方案

Now, Laravel is a really nice framework, so I would assume there mustbe something to prevent XSS out of the box. However, I can't find out what that is.

现在,Laravel 是一个非常好的框架,所以我认为必须有一些东西可以防止 XSS 开箱即用。但是,我无法找出那是什么。

If I'm wrong, what is the optimal way to handle the issue?

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

  • Do I use fancy regex validation to disallow specific characters?
  • Do I use mysql_real_escape_string()on every Input::get()I use?
  • Do I strip_tags()?
  • 我是否使用花哨的正则表达式验证来禁止特定字符?
  • mysql_real_escape_string()每次使用时都Input::get()使用吗?
  • strip_tags()吗?

View-level escaping is not enough

视图级转义是不够的

I know I can use Blade's triple curly bracketsto escape strings in the views, that's not the point, though. Makes much more sense to me not to let those sneaky bastards into the database in the first place.

我知道我可以使用 Blade 的三个大括号来转义视图中的字符串,但这不是重点。对我来说,首先不要让那些鬼鬼祟祟的混蛋进入数据库更有意义。

Anyone faced this problem already?

有人已经遇到过这个问题吗?

回答by Laurence

Makes much more sense to me not to let those sneaky bastards into the database in the first place.

对我来说,首先不要让那些鬼鬼祟祟的混蛋进入数据库更有意义。

Actually - that is not true.

实际上 - 这不是真的。

The reason that XSS is only handled by blade is that XSS attacks are an outputproblem. There is no security risk if you store <script>alert('Hacking Sony in 3...2...')</script>in your database - it is just text - it doesnt mean anything.

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

But in the context of HTML output - then the text has a meaning, and therefore that is where the filtering should occur.

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

Also - it is possible that XSS attack could be a reflected attack, where the displayed data is not coming from the database, but from another source. i.e. an uploaded file, url etc. If you fail to filter all the various input locations - you run a risk of missing something.

此外 - XSS 攻击可能是一种反射攻击,其中显示的数据不是来自数据库,而是来自另一个来源。即上传的文件、url 等。如果您未能过滤所有不同的输入位置 - 您就有丢失某些内容的风险。

Laravel encourages you to escape alloutput, regardless where it came from. You should only explicitly display non-filtered data due to a specific reason - and only if you are sure the data is from a trusted source (i.e. from your own code, never from user input).

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

p.s. In Laravel 5 the default {{ }}will escape all output - which highlights the importance of this.

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

Edit: here is a good discussion with further points on why you should filter output, not input: html/XSS escape on input vs output

编辑:这是一个很好的讨论,进一步说明了为什么应该过滤输出,而不是输入:输入与输出上的 html/XSS 转义

回答by bishop

As far as I know, the "official" Laravel position is that XSS prevention best practice is to escape output. Thus, {{{ }}}.

据我所知,Laravel 的“官方”立场是XSS 预防的最佳实践是逃避输出。因此,{{{ }}}

You can supplementoutput escaping through inputsanitation with Input::all(), strip_tags(), and array_map():

你可以补充输出通过转义输入环卫用Input::all()strip_tags()以及array_map()

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

回答by Robert Apollo

I examined the Laravel's protection {{{...}}}against xss attack. It just uses the htmlentities()function in the way like this: htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false);This protects you against xss only if you use it properly means dont use it in certain HTML tags because it will result in XSS attack possibility. For example:

我检查了 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>';

In this case, it is vulnerable to xss.

在这种情况下,它很容易受到 xss 的攻击。

回答by Balachandran

You also filter input before validation like, First create /app/Common/Utility.php

您还可以在验证之前过滤输入,例如,首先创建 /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;
    }
}

And use in your controller like this

并像这样在您的控制器中使用

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

This code will clean your input before validation

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

回答by Leonid Shumakov

The package laravelgems/blade-escapeextends Blade by adding different escaping strategies/directives - @text, @attr, @css, @js, @param

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

Example:

例子:

<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>

Read their README. XSS is very tricky, there are a lot contexts and approaches.

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

Testing page - http://laragems.com/package/blade-escape/test

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

回答by Carlos Sanchez

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);
    }
}