PHP 安全输入输出方式 「防止 XSS 注入」
XSS
攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。我在开发中使用严进严出的安全保障方式:
保证安全输入(严进)
添加中间件,对所有参数进行过滤转换:
htmlspecialchars()
函数把一些预定义的字符转换为HTML
实体strip_tags()
函数剥去字符串中的HTML
、XML
以及PHP
的标签
class XSSFilter
{
public function handle($request, Closure $next)
{
// 配置不执行过滤转换参数项,如 env 配置: XSS_EXCEPT=article_contents,html_contents
$param_except_string = config('const.xss_filter_param_except');
$param_except = [];
if (!empty($param_except_string)) {
$param_except = explode(',', $param_except_string);
}
$input = $request->except($param_except);
array_walk_recursive($input, function (&$input) {
// $input = strip_tags($input); // 清除标签内容
$input = htmlspecialchars($input, ENT_NOQUOTES, 'UTF-8', false); // 过滤转换预定符号
});
$request->merge($input);
return $next($request);
}
}
使用安全输出(严出)
Laravel 安全输出方式
- Blade 模板中使用转义输出:
{{ }}
- 直接输出时,使用
e()
函数进行过滤
Bad:
$nickname = "<img src='x' onerror='alert(0)' />测试昵称";
{!! $nickname !!}
@php
echo $nickname
@endphp
Good:
$nickname = "<img src='x' onerror='alert(0)' />测试昵称";
{{ $nickname }}
@php
echo e($nickname);
@endphp
等同于:
- 使用
htmlspecialchars
进行过滤转换
Bad:
$nickname = "<img src='x' onerror='alert(0)' />测试昵称";
echo $nickname;
Good:
function p($value) {
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
}
$nickname = "<img src='x' onerror='alert(0)' />测试昵称";
echo p($nickname);
开启 httpOnly
开启 httpOnly
后,禁止 JavaScript
脚本直接读取该 Cookie
内容
Laravel Session
创建 Cookie
时,调用
cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
最后一个参数 $httpOnly = true
PHP 原生 Session
如果是 PHP
原生 Session
对应 Cookie
键值默认为: PHPSESSID
需要手工修改 php.ini
配置开启 httpOnly
: Session.cookie_httponly = On
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: