JavaScript を使用せずに信頼できない入力を CSS カスタム プロパティに安全に割り当てる: ガイド
P粉356361722
P粉356361722 2023-09-06 22:32:52
0
1
746

文字列キーと文字列値のオブジェクトがあり、それらを CSS カスタム プロパティとしてサーバー生成の HTML に書き込みたいとします。どうすれば安全にこれを行うことができますか?

セキュリティとは

  • 可能であれば、カスタム プロパティの宣言によって、ブラウザーが他のスタイル宣言や HTML ドキュメントの一部を正しく解析できなくなるような CSS 構文エラーが発生しないようにする必要があります。何らかの理由でこれが不可能な場合は、キーと値のペアを省略する必要があります。
  • さらに重要なのは、これによりクロスサイト スクリプティングが不可能になることです。

わかりやすくするために、[a-zA-Z0-9_-] クラスの文字のみを許可するようにキーを制限します。

CSS 仕様を読んで個人的なテストを行った結果、次の手順に従って値を取得すると、大幅に進歩できると思います。

    文字列の検索
  • 各引用符の後に同じタイプの別の (エスケープされていない) 引用符 (" または ') が続いていることを確認してください。そうでない場合は、このキーと値のペアを破棄してください。
  • 文字列の外側のすべての左中括弧
  • {([ 文字列の外側に一致する右中括弧があることを確認します。そうでない場合は、このキーと値のペアを破棄します。
  • < のすべてのインスタンスをエスケープするには \3C を使用し、<> のすべてのインスタンスをエスケープするには 3E を使用します。
  • \3B を使用して、; のすべてのインスタンスをエスケープします。
この CSS 構文仕様に基づいて上記の手順を思いつきました

コンテキストとして、これらのプロパティは、他の場所に挿入するユーザー定義スタイルで使用できますが、同じオブジェクトがテンプレート内のテンプレート データとしても使用されるため、コンテンツとして意図された文字列や CSS としてミックスインに期待される文字列が含まれる可能性があります。変数。上記のアルゴリズムは、CSS で役立つ可能性のあるキーと値のペアを大量に破棄するリスクを冒すことなく、非常にシンプルであるという良いバランスをとっているように感じます (CSS への将来の追加も考慮していますが、そうでないことを確認したいと考えています)何かが足りないわけではありません。


これは私が達成しようとしていることを示す JS コードです。

obj は問題のオブジェクトであり、preprocessPairs はオブジェクトを取得して前処理し、上記の手順で説明したように値を削除/再フォーマットする関数です。 リーリー

したがって、次のようなオブジェクトが与えられた場合

リーリー

CSS を次のようにしたい:

リーリー

--theme-title は CSS で使用すると非常に役に立たないカスタム変数ですが、CSS は理解できないプロパティを無視するため、実際にはスタイルシートを破壊しません。

P粉356361722
P粉356361722

全員に返信(1)
P粉898107874

実際には、特定の言語に依存せずに正規表現やその他のアルゴリズムを使用することもできます。それが必要なものであることを願っています。

オブジェクト キーが [a-zA-Z0-9_-] 内にあると宣言することで、何らかの方法で値を解析する必要があります。

価値モデル

そこで、カテゴリに分類して、何が見つかるかを確認します (わかりやすくするために、若干簡略化されている可能性があります):

  1. '.*' (アポストロフィで囲まれた文字列、貪欲)
  2. ".*" (二重引用符で囲まれた文字列、貪欲)
  3. [ -]?\d (\.\d )?(%|[A-z] )? (整数と小数、オプションのパーセンテージまたは単位付き)
  4. #[0-9A-f]{3,6}(カラー)
  5. [A-z0-9_-] (キーワード、名前付きの色、「使いやすさ」など)
  6. ([\w-] )\([^)] \) (url()calc()> などに似た関数。 )

最初のフィルター

これらのパターンを特定する前に、何らかのフィルタリングを実行できることは想像できます。おそらく最初に値文字列をトリミングします。前述したように、# と # は、上記のモードのように表示されないため、preprocessPairs() 関数の先頭でエスケープできます。エスケープされていないセミコロンをどこにも表示したくない場合は、セミコロンをエスケープすることもできます。

認識パターン

その後、 内でこれらのパターンを識別することを試みることができ、パターンごとにフィルタリングを再度実行する必要がある場合があります。これらのパターンはいくつか (または 2 つ) の空白文字で区切られることが予想されます。

エスケープされた改行である複数行文字列のサポートを含めても問題ありません。

ロケール

フィルタリングするコンテキストが少なくとも 2 つあることを認識する必要があります (HTML と CSS)。 要素にスタイルを含める場合、入力は安全であり、有効な CSS である必要があります。幸いなことに、要素の style 属性に CSS を含めていないため、これは少し簡単です。

値パターンに基づくフィルタリング

  1. アポストロフィで囲まれた文字列 - アポストロフィとセミコロン以外は何も気にしないので、文字列内でこれらの文字の unscaped インスタンスを見つけてエスケープを解除する必要があります。 Escape
  2. 上記と同じですが、二重引用符を使用するだけです
  3. 問題ないはずです
  4. 問題ないはずです
  5. 基本的には問題ありません
  6. これが楽しい部分です

したがって、ポイント 1 ~ 5 は非常に単純で、ほとんどの値はこの後の単純なフィルタリングとトリミングでカバーされます。いくつかの追加 (パフォーマンスにどのような影響があるかはわかりません) を加えれば、正しい単位やキーワードなどについて追加のチェックが行われる可能性もあります。

しかし、他のポイントと比較して、比較的大きな課題はポイント 6 だと思います。このカスタム スタイルの url() を単純に無効にして、関数への入力をチェックできるようにすることもできます。たとえば、セミコロンをエスケープしたり、関数内を再度チェックしたりすることもできます。 tiny tweak パターンは、たとえば calc() です。

###結論は###

一般的に、これは私の意見です。これらの正規表現にいくつかの調整を加えることで、すでに行っていることを補完し、CSS 機能を調整するたびにコードを調整する手間を省きながら、CSS を入力する際に​​可能な限り柔軟に対応できるようになります。

###例### リーリー

コメント、議論、批判をしてください。また、特に関心のあるトピックについて触れ忘れていた場合はお知らせください。

###ソース###

免責事項: 私は、以下に記載されている情報源の著者、所有者、投資家、または寄稿者ではありません。たまたま情報を得るために利用しているだけです。

    https://www.w3.org/TR/css-values-3
  • https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/05-Testing_for_CSS_Injection
  • https://cheatsheetseries.owasp.org/cheatsheets/Securing_Cascading_Style_Sheets_Cheat_Sheet.html
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート