web-dev-qa-db-ja.com

LaravelでXSS保護をどのように、どこで適用できますか?

LaravelではXSS保護がどのように提供されているのでしょうか(とにかく)。私はドキュメントでそれについて何も見つけることができませんでした。

問題

Eloquent'screate()メソッドを使用してデータベースにデータを挿入しています(モデルに_$fillable_/_$guarded_プロパティが設定されています)。結局のところ、任意のフォームのテキスト入力にこのようなものを自由に入れることができます。

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

値がデータベースに挿入されます。次に、echoingすると、アラートが表示されます。

可能な解決策

ここで、Laravelは本当に素晴らしいフレームワークなので、mustXSSをすぐに使用できないようにする必要があると思います。しかし、それが何であるかを知りません。

私が間違っている場合、問題を処理する最適な方法は何ですか?

  • 特定の文字を禁止するために派手な正規表現検証を使用しますか?
  • 使用するすべてのmysql_real_escape_string()Input::get()を使用しますか?
  • strip_tags()しますか?

ビューレベルのエスケープでは不十分です

私はBladeの 三重中括弧 を使用してビュー内の文字列をエスケープできることを知っていますが、それはポイントではありません。そもそもそれらの卑劣な野郎をデータベースに入れないようにしたほうがずっと理にかなっている。

すでにこの問題に直面している人はいますか?

15
lesssugar

そもそもそれらの卑劣な野郎をデータベースに入れないようにしたほうがずっと理にかなっている。

実際にはそうではありません。

XSSがブレードによってのみ処理される理由は、XSS攻撃がoutput問題であるためです。 <script>alert('Hacking Sony in 3...2...')</script>をデータベースに保存しても、セキュリティ上のリスクはありません-それは単なるテキストです-それは何も意味しません。

しかし、HTML出力のコンテキストでは、テキストには意味があるため、フィルタリングが行われるべき場所です。

また、XSS攻撃は、表示されたデータがデータベースからではなく、別のソースからの反射攻撃である可能性があります。つまり、アップロードされたファイル、URLなど。すべてのさまざまな入力場所をフィルタリングできない場合、何かが欠落するリスクがあります。

Laravelは、どこから来たものであっても、all出力をエスケープすることをお勧めします。特定の理由により、フィルタリングされていないデータのみを明示的に表示する必要があります。データが信頼できるソース(つまり、ユーザー入力ではなく、独自のコード)からのものであることが確実な場合のみです。

追伸In Laravel 5デフォルト{{ }}はすべての出力をエスケープします-これはこの重要性を強調しています。

編集:ここでは、入力ではなく出力をフィルタリングする必要がある理由についてのさらなるポイントを含む良い議論があります: 入力/出力でのhtml/XSSエスケープ

34
Laurence

私の知る限り、「公式」Laravel位置は、 XSS防止のベストプラクティスは、output 。したがって、{{{ }}}

supplement出力をエスケープすることができますinput衛生とInput::all()strip_tags()、およびarray_map()

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

Xss攻撃に対するLaravelの保護{{{...}}}を調べました。 htmlentities()関数を次のように使用します。htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false);これは、適切に使用した場合にのみxssから保護します。XSS攻撃の可能性があるため、特定のHTMLタグで使用しないでください。 。例えば:

$a = htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false); 
echo '<a href="'.$a.'">link</a>';

この場合、xssに対して脆弱です。

5
Robert Apollo

また、検証の前に、最初の作成/ 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
}

このコードは、検証前に入力を消去します

3
Balachandran

パッケージ laravelgems/blade-escape は、異なるエスケープ戦略/ディレクティブを追加してBladeを拡張します-@text@attr@css@js@param

例:

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

READMEを読んでください。 XSSは非常に注意が必要です。多くのコンテキストとアプローチがあります。

テストページ- http://laragems.com/package/blade-escape/test

2
Leonid Shumakov
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);
    }
}
1
Carlos Sanchez