LoginSignup
0
3

More than 1 year has passed since last update.

Laravelのクロスサイトスクリプト(XSS)対策

Last updated at Posted at 2022-06-04

LaravelのXSS対策で意識することをまとめます。

要点

1、htmlのタグ内ではダブルクオテーションで囲う
<input value="{{ $text }}">

2、フロントに文字列を渡す時は、htmlspecialcharsでサニタイズする

htmlのタグ内ではダブルクオテーションで囲う

ダブルクオテーションで囲わないと予期せぬ属性が追加されてしまう。

実行例

TestController.php
class TestController extends Controller
{
    public function index()
    {
        $text = "test onclick=alert(1);";  
        return view('tests.test', compact('text'));
    }
}
test.blade.php
<input type="text" value="{{$text}}">  {{-- 正しい --}}
<br>
<br>
<input type="text" value={{$text}}> {{-- 誤り --}}

結果

クオテーションで囲まない方はonclick属性が追加できてしまった。
無題のプレゼンテーション.png

フロントの言語に変数を渡す時は、htmlspecialchars関数でサニタイズする

実行例

ボタンを押下したらlogが出力される機能を作成

{{-- ボタン(onclick属性) --}}
<button onclick="test({{$text}})">ボタン</button>

{{-- js --}}
<script>
 function test(text){
   console.log(text);
 }
</script>

渡すテキスト
$text = "test' onclick=alert(1);";
・シングルクオートあり
・()あり

出力されたログ

エラー
Uncaught SyntaxError: missing ) after argument list (at

修正例

{{-- シングルクオテーションで囲むことで()が文字列として扱われる --}}
{{-- さらにhtmlspecialchars関数でシングルクオテーションをサニタイズする --}}
<button onclick="test('{{htmlspecialchars($text,3)}}')">ボタン</button>

出力結果

test&#039; onclick=alert(1);

サニタイズする前の文字列を表示したい場合はjs側で処理する必要あり。
今回は範囲外とします。

追加

別パターン:json形式で渡す

blade.html
<button onclick="test2( {{ json_encode(['text' => $text], JSON_HEX_TAG | JSON_HEX_AMP) }} )">ボタン</button>
script.js
 function test2(text){
  console.log(text.text);
 }

出力結果

test' onclick=alert(1);
渡したテキストがそのまま取れました。これが一番良さそうです。
上司が教えてくれました。感謝。

他にもっと有効な方法があれば是非教えてください。

0
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3