PHP 安全輸入輸出方式 「防止 XSS 注入」

Sparkfly發表於2019-08-13

XSS攻擊通常指的是透過利用網頁開發時留下的漏洞,透過巧妙的方法注入惡意指令程式碼到網頁,使使用者載入並執行攻擊者惡意製造的網頁程式。我在開發中使用嚴進嚴出的安全保障方式:

保證安全輸入(嚴進)

新增中介軟體,對所有引數進行過濾轉換:

  • htmlspecialchars() 函式把一些預定義的字元轉換為 HTML 實體
  • strip_tags() 函式剝去字串中的 HTMLXML 以及 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 協議》,轉載必須註明作者和本文連結

相關文章