Tom Stacey氏は、プロキシ、CDN、バックエンドアプリケーションがHTTPトラフィックを解析する方法の違いによって、注入された改行文字が重大なデシンクロナイゼーション(desync)脆弱性へと変わり得ることを実証しました。
CRLF(carriage return and line feedの略)とは、HTTPメッセージ内でヘッダーを区切るために使われる文字シーケンスです。
アプリケーションが%0d%0aのようなエンコード済みCRLF文字を、後にリバースプロキシによってデコードされる入力に混入することを許してしまう場合、攻撃者は上流サーバーへ転送されるリクエストの構造を改変できる可能性があります。
今回の研究では、Nginxの設定が特に注意すべきリスク領域として挙げられています。特に、proxy_passディレクティブ内で$uriのような変数を使用すると、Nginxが攻撃者に制御されたリクエストパスをバックエンドへ転送する前に正規化・URLデコードしてしまうことがあります。
この挙動により、エンコードされたCRLFシーケンスが実際のHTTP改行に変換され、注入されたヘッダーや、さらには追加のリクエストが上流サービスによって処理されてしまう可能性があります。
最も深刻な結果が生じるのは、フロントエンドのプロキシとバックエンドサーバーがリクエストの境界について解釈の食い違いを起こす場合です。このようなパーサーの不一致は、HTTPリクエストのデシンクロナイゼーション、いわゆるリクエストスマグリングを引き起こします。
フロントエンドがトラフィックを1つのリクエストとして解釈する一方で、バックエンドが同じバイト列を2つのリクエストとして解釈してしまうことがあります。
攻撃者はこの食い違いを悪用して、別のユーザーの接続ストリームにリクエストを挿入したり、アプリケーションの挙動を操作したり、HTTPレスポンスが配信される順序を乱したりすることができます。
Tom Stacey氏が実証したのは、CRLFを利用したCL.TE desync手法で、Content-LengthとTransfer-Encodingの扱いが矛盾することで、フロントエンドとバックエンドがリクエストを異なる形で解析してしまうというものです。
同氏はまた、レスポンスキューポイズニングにつながりかねないリクエスト分割攻撃も示しました。このシナリオでは、サーバーがどのレスポンスがどのクライアントに属するかを把握できなくなり、正規ユーザー向けの機密情報を含むレスポンスが攻撃者の制御する接続に送信されてしまう可能性があります。
共有型のCDNやクラウド環境では、インフラ層で発生したデシンクロナイゼーションの問題が、同じエッジシステムやプロキシシステムに依存する複数のアプリケーションやテナントに影響を及ぼす可能性があります。
特に懸念される点として、一部のCRLF desync攻撃は通常のブラウザ動作を通じて仕掛けられる可能性があることが挙げられます。悪意のあるページが被害者のブラウザに細工されたリクエストを送信させることに成功すると、そのリクエストは被害者の認証済みセッションおよびネットワークコンテキストを使って発行されてしまう恐れがあります。
セッショントークンがひとたびドキュメントに描画されると、悪意のあるスクリプトがそれを読み取って外部に持ち出すことが可能になります。組織は、CRLFインジェクションを単なる軽微な検証不備としてではなく、リクエストスマグリングを引き起こし得る攻撃手段として扱うべきです。
管理者は、$uriや$document_uriを用いた安全でないNginxプロキシ設定を避け、プロキシのルーティングロジックに渡る前にエンコードされた改行文字を拒否し、CDN、ロードバランサー、リバースプロキシ、オリジンサーバー間で解析の不整合がないかを評価する必要があります。
Tom Stacey氏はさらに、より持続的な緩和策として上流接続にHTTP/2を採用することを推奨しています。
セキュリティチームに、不審な活動をより迅速に調査し、ビジネスへの影響が拡大する前に脅威を封じ込めるための可視性とコンテキストを与えましょう。 ANY.RUNで調査を強化
翻訳元: https://cyberpress.org/crlf-header-injection-flaws/