我想知道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来逃避视图中的字符串,但这不是重点。让我更有意义的是不要让那些偷偷摸摸的混蛋进入数据库。
任何人都遇到过这个问题?
答案 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非常棘手,有很多背景和方法。
答案 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);
}
}