読者です 読者をやめる 読者になる 読者になる

jQuery 1.8 beta 1 のXSSのところの追記

jquery1.8 beta 1が出ました - ぽりぴぃすらいとを書いたところ、mentionがたどれなくなってしまったのですがtwitterで「fixとはどういう状態ですか?」と聞かれたのでコメントを見てみました。

そもそもの状態

まず、チケットの9521ですが、malaさんの指摘部分を含んではいますが、大枠(validなものとして)入力を受け付ける、ということとしてfixし、11617に渡しています。

そこで、
#11617 (Define a $.parseHTML method for creating HTML fragments)
– jQuery Core
- Bug Tracker
このように「いやいや、解決してないよ!?」と投げ込んだんですが、そこでは

Use case: rich editor in an iframe/div with contentEditable enabled, user paste some unknown html (word maybe) and we only want to allow the strong tag and remove or rename the others tag. This would be useful for many wyswyg html5 editors.

Use case: ユーザが未知のhtmlを貼り付け、強調タグやその他のタグを削除・変更することだけを可能にしたい、contentEditableが有効になっているiframeやdiv内のリッチエディタ。これは、多くのwyswyg html5エディタで便利だろう。

とコメントが返されています。

確かに便利だけど、なんだかなぁ、という気もします。そもそも.prop()とか.attr()があるんだから、relとかそういうのはそっちのAPIから指定するのがいい気もするけど、確かにそれだと、wyswygだときっついよなぁとは思います。

こういうやりとりの次に、dmethvinが
#11617 (Define a $.parseHTML method for creating HTML fragments)
– jQuery Core
- Bug Tracker
で下記のように答えています

To clarify the purpose of this method, it is beginning the process of separating the two String cases that $() handles: selectors and HTML serialization. There was some discussion in #11974 that implied it may be misunderstood as some sort of "XSS-proof HTML processing." It is not.

We want to mitigate the chances that a jQuery dev calls $(selector) thinking it is a CSS selector, but Mr. Bad Guy has managed to get script into selector and therefore executes it. We're doing that by providing $.parseHTML and eventually locking down the HTML recognition of $() to a small subset.

If/when environments provide better ways to sandbox, the ability of $.parseHTML() to make the dev's intentions clear will come in handy. However, no matter the method, jQuery allows devs to parse and execute scripts. If they process complex HTML with script and allow that script to come from untrusted or corruptible sources, it is still possible to make successful XSS attacks--just as it would be if the dev wrote their code in bare DOM methods.

ざっというと

  • $() の2つの文字列ケースを分けて考えよう。1つは、selectorでもう一つがHTML serialization
  • #11974でも議論されてるけど、"XSS-proof HTML processing" じゃないよ
  • selectorを想定している$(selector)で、悪意ある開発者によって、selectorにスクリプトが混入され、それが実行される機会を減らしたい
  • そのために、$.parseHTMLを提供し、最終的には、$()におけるHTML識別をlock downしたい
  • サンドボックス環境において、開発者の意図を明確にする$.parseHTMLの機能は役に立つと思う

と、まあ、malaさんがjQueryにおけるXSSを引き起こしやすい問題について - 金利0無利息キャッシング – キャッシングできます - subtechで書かれてる通り、selectorでもHTMLparserとしても機能するってのがXSSの混入を起こすから、両者を分けていこうと考えている(と僕は読み取っています。間違ってたらコメントください。)

んー

HTMLparserの機能がwyswygなどで重宝されるとはいえ、XSSの温床になるのは避けられる限り避けたほうがいいと思うので、

  • $.parseHTML: 自由に記述が可能
  • $.tag: 従来のHTMLタグ生成機能
  • $(): selector

みたいな形で明確に分けて、通常は$.tagと$()を使うようにできればいいような気もします。

追記 2012/07/01

自分の拙い理解の中ですが、コメント頂いたので、補足しておきます。

上で、

selectorでもHTMLparserとしても機能するってのがXSSの混入を起こす

のようにmalaさんのブログを引きましたが、

で、自分の理解(というか今後の.parseHTML含めての解釈・予測?)では、そもそも、こういう「一時的に[]や''の中にタグが入っているときにCSSセレクタと見なされる」が起こっているのは2つの機能を切り分ける時の識別ルールが煩雑になってしまうことが理由なんだと思っており、そもそも、2つの機能を同じメソッドに詰め込むことが良くないんだと。

.parseHTMLはそれらの機能を明確に識別する方向に進むよ!というのが、まさに
#11617 (Define a $.parseHTML method for creating HTML fragments)
– jQuery Core
- Bug Tracker
のコメントに現れてるんだと思いました。