Posted at

AngularのXSS(クロスサイトスクリプティング)対策

More than 1 year has passed since last update.


はじめに

AngularのXSS対策について調査してみました。

+ 調査環境:4.0.0-beta.8


種類に応じたサニタイジング

Angularは、HTML, STYLE, URL, RESOUCE_URL, SCRIPT, NONEの6種類のサニタイジングを行うことができるように設計されています。

各分類は以下のようになっています。

Schema
Context

HTML
iframe:srcdoc, *:innerHTML, *:outerHTML

STYLE
*:style

URL
*:formAction, area:href, area:ping, audio:src, a:href, a:ping, blockquote:cite, body:background, del:cite, form:action, img:src, img:srcset, input:src, ins:cite, q:cite, source:src, source:srcset, track:src, video:poster, video:src

RESOURCE_URL
applet:code', applet:codebase', base:href', embed:src', frame:src', head:profile', html:manifest', iframe:src', link:href', media:src', object:codebase', object:data', script:src'


サニタイジング漏れのエラーメッセージ

適切にサニタイジングされていない場合、HTMLとSTYLEとURLは自動でサニタイジングされます。SCRIPTとRESOURCE_URLはエラーになり処理を中断します。

SCRIPTは以下のエラーメッセージになります。

unsafe value used in a script context

RESOURCE_URLは以下のエラーメッセージになります。

unsafe value used in a resource URL context (see http://g.co/ng/security#xss)

サニタイジングされているものの、その方式に誤りがある場合は、次のエラーメッセージを出力します。



Required a safe ${expectedType}, got a ${value.getTypeName()} (see http://g.co/ng/security#xss)



ただし、URLはSafeUrlとSafeResourceUrlの両方を許可していため、SafeResourceUrlはRESOURE_URLとURLの両方のチェックを通過します。


URLのサニタイジング

URLのサニタイジング処理はチェックのみ行います。

以下のどれかの正規表現にマッチすれば有効なURLと判断します。

/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi

/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i

URLは、複数のURLを指定する srcset にも対応しています。


URLのエラーメッセージ

適切にサニタイジングされていない場合、以下のエラーメッセージが表示され、先頭に unsafe: が追加されたURLに置換されます。

WARNING: sanitizing unsafe URL value ${url} (see http://g.co/ng/security#xss)


Styleのサニタイジング

予め定義されたスタイルのキーワードとマッチするか、クォート("と')の整合性がとれているかのチェックを行います。

URLでスタイルシートを指定した場合は、URLのサニタイジングチェックを行います。

予め定義されたスタイルのキーワードは以下です。

種別
定義


[-,."\'%_!# a-zA-Z0-9]+

変形
(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|3d)?


(?:rgb|hsl)a?

グラデーション
(?:repeating-)?(?:linear|radial)-gradient

CSS3
(?:calc|attr)

引数
\\([-0-9.%, #a-zA-Z]+\\)


Styleのエラーメッセージ

適切にサニタイジングされていない場合、以下のエラーメッセージが表示され、Styleは 'unsafe' に置換されます。

WARNING: sanitizing unsafe style value ${value} (see http://g.co/ng/security#xss).


HTMLのサニタイジング

DOMを分解し、URLとvalueをサニタイジングします。

valueは、以下の置換が行われます。

置換前
置換後

&
&

[\uD800-\uDBFF][\uDC00-\uDFFF]
&#(Unicode)

[^#-~ |!]
&#(Unicode)

<
&lt;

>
&gt;


参考



  • スキーマの定義


    • モジュール:@angular/compiler

    • ソース:schema/dom_security_schema.ts




  • セキュリティ分類


    • モジュール:@angular\core

    • ソース:security.ts




  • URLのサニタイジング


    • モジュール:@angular\platform-browser

    • ソース:security\url_sanitizer.ts




  • Styleのサニタイジング


    • モジュール:@angular\platform-browser

    • ソース:security\style_sanitizer.ts




  • HTMLのサニタイジング


    • モジュール:@angular\platform-browser

    • ソース:security\html_sanitizer.ts