Skip to content

Instantly share code, notes, and snippets.

@mala
Last active March 18, 2023 11:53
Show Gist options
  • Save mala/f86a849d15b2d60d7119e05f33b4b885 to your computer and use it in GitHub Desktop.
Save mala/f86a849d15b2d60d7119e05f33b4b885 to your computer and use it in GitHub Desktop.
Vulnerabilities related to url parser, etc / shibuya.xss #8

TBD

ma.la


Today's theme

  • Flash and CORS
  • URL Parser
  • Malicious Chrome Extensions
  • Hmm, I can't choose one.

Flash and CORS

  • There is many differences JS and Flash about crossdomain policy.
  • Many developers don't know exactly CORS policy.
  • Crossdomain image loading as "data" without crossdomain.xml is vuln, but Flash developers say it is "Hack".
  • Today, it is clear whether it is a spec or bug by CORS.

That's all, see my gist.


Malicious extensions on Chrome

  • Some people making noise "Chrome extension became malware!", so I've investigated.
  • I've downloaded TOP5000 extensions and investigated it.
  • Malicious extension load external script by obfuscated js
  • 0.7% of TOP 5000, some were already removed from webstore.

That's all, see my gist.


Vulnerabilities due to URL parser

ma.la

---- # Summary - vulnerabilities regarding URL parsers - not fixed yet in some libraries

1. What is URL parser


Issues in parsing of about URL

  • the same url brings different result depend on browsers and libraries
  • some implementations follow RFC but the others are not
  • RFC is different from the real implementations
  • for compatibility reason, browser/server may accept invalid URLs.

Example


Invalid in "strict" parsers

  • Java: new URI
  • Ruby: URI.parse

2. Vulns in URL parsing

  • bugs in URL parser itself
  • bugs regarding the time of check

SOP bypass

  • UXSS on Android
  • \u0000javascript:xxx

Commit log


Open Redirect


Open redirector in WordPress


Bypass A: http:example.com

  • parse_url doesn't return hostname
  • browsers returns the same result as http://example.com

If you check hostname like...

  • parse_url(url).host == “example.com”

Bypass B: otherprotocol:example.com

  • javascript://example.com%0A alert(1);
  • XSS with href, iframe, js refresh, etc.

Oops!

  • then, check protocol!
  • url.protocol == “http” || url.protocol == “https”

Bypass C:


Very serious in some cases.

  • origin = scheme + host + port
  • your code is not wrong, but "origin" may be failure
  • SOP bypass on server-side

URLs making hostname confusion

  • I found same bugs on the default URL parser of major languages/platforms
  • PHP, ■■■■, ■■■■■■■ (reported by mala)
  • fixed: PHP 5.6.28 / 7.0.13
  • cURL (not my work, but got hint from bug report of PHP?)

UPDATE 2017-02


Are these widely known?


WordPressの事例のテストケースにあり

  • These URL in WordPress's test case.
  • hey WordPress, it's not your bug, please report upstream!

🙅 Off the record

  • bugs or vulns?
  • disclosure timing?

Right way for parsing authority component

https://tools.ietf.org/html/rfc3986#section-3.2

   The authority component is preceded by a double slash ("//") and is
   terminated by the next slash ("/"), question mark ("?"), or number
   sign ("#") character, or by the end of the URI.

Authority component


Why are URL parsers buggy?

  • they handle absolute URLs and relative URLs in a same library
  • they handle http URLs and other schemes in a same library
  • historical reason, compatibility, fuzzy liberal parser
  • originally, user:pass can't contain reserved chars
authority     = [ userinfo "@" ] host [ ":" port ]
userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )

3. Vulnerabilities in the real world

  • URL parser's bug → vulnerability

A: DOM based XSS (client side)


B: Open redirector → XSS


🙅 Off the record


C: Open Redirector → auth bypass

  • server side
  • I've never seen any cases in the real world
  • but there would be cases

Validation of callback url

  • redirect url of OAuth, OpenID
  • check only hostname is dangerous
  • with URL parser's bug
  • and "trusted by domain" is dangerous

Why?

  • with vulnerable parsers and crafted URL, sending authentication code to wrong host is possible
  • if there is an open redirector.
  • if callback url contains external resources/links, referrer header leaks auth code/token

ID Provider


D: SSRF / TOCTOU attack

  • send HTTP request to internal network
  • send attack code to http based old CMS, admin console
  • fetch intranet URLs via proxy API

SSRF with URL parser's bug

  • check hostname by buggy parse_url
  • fetch url by other implementation

Before that, there is TOCTOU problem

  • Time-Of-Check Time-Of-Use problem
  • DNS record can be changed

Security considerations

  • You should use the same implementation for checking and use whenever possible
  • You should use same data for checking and use
  • "Normalize strings before validating them"

Related issues: problem of HTML parsers

  • I've talked about it on AppSec
  • XSS with <!--> -->
  • TinyMCE, etc

In case of URL parser

  • client / server / language, there are too many implementations.
  • need more test cases

That's all.

  • Fin.

URL Parserに起因する脆弱性

ma.la


概要

  • URLパーサに起因する脆弱性について
  • いくつかはまだ未修正

1. URL Parserとは


URLの解釈に関する話

  • ブラウザやライブラリによって異なるURLと認識される
  • RFC通りに実装されているとは限らないし、RFCが正しいとは限らない
  • 互換性のため、相互運用性のためにinvalidなURLを許容することがある

例えば


厳格なparserではerror

  • Java: new URI
  • Ruby: URI.parse

2. URL誤認による脆弱性

  • URL Parser自体にバグが有るもの
  • チェックするタイミングによって問題が起きるもの

SOP bypass

  • Android でのUXSS
  • \u0000javascript:xxx でUXSSが可能だった問題

問題の箇所


Open Redirect


WordPressの事例


Bypass A: http:example.com

  • hostが取れないけど相対パスじゃない
  • ブラウザでは http://example.com と解釈

ホスト名の一致を確認する必要がある

  • parse_url(url).host == “example.com”

Bypass B: otherprotocol:example.com

  • javascript://example.com%0A alert(1);
  • XSS with href, iframe, js refresh, etc.

Oops!

  • じゃあ、protocolもチェックしましょう
  • url.protocol == “http” || url.protocol == “https”

Bypass C:


非常に深刻な問題

  • origin = scheme + host + port
  • 正しい方法でのsame origin判定が失敗する!!
  • SOP bypass on server-side

host名を誤認するURL

  • いくつかのライブラリ、言語の標準実装で問題あり
  • PHP, ■■■■, ■■■■■■■ (reported by mala)
  • PHP 5.6.28 / 7.0.13 で直っています
  • cURL (自分の報告ではない)

UPDATE 2017-02


この問題は知られている?

  • 未修正の事例はまだ公開できないが、問題自体はcURLのケースで公知
  • https://curl.haxx.se/docs/adv_20161102J.html CVE-2016-8624
  • 複数の実装で同様の問題がある、インターネットのバグ!
  • WordPressの事例のテストケースにあり
  • PHPのバグなので上流に報告しましょう

オフレコ

  • バグか脆弱性かの問題
  • 複数実装に問題があったときの公表方法

正しい実装は?

https://tools.ietf.org/html/rfc3986#section-3.2

   The authority component is preceded by a double slash ("//") and is
   terminated by the next slash ("/"), question mark ("?"), or number
   sign ("#") character, or by the end of the URI.

Authority component

  • user:pass@example.com の部分
  • / or ? or # で問答無用で終わるのが正しい

バグが起こりやすい原因

  • 絶対URLと相対パスの両方を同じライブラリで処理
  • http urlとそれ以外のprotocolも同列に処理
  • 歴史的経緯、相互運用性、互換性のための寛容な処理
  • user:pass には本来、予約文字が使えない
authority     = [ userinfo "@" ] host [ ":" port ]
userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )

3. 実世界での問題

  • URL Parserのバグがどのように脆弱性になるか

A: DOM based XSS(client side)


B: Open Redirector → XSS

  • client side + server side
  • jQuery mobile + open redirector
  • 最近報告したものがある

jQuery mobileまだ使ってるの?

  • yes.
  • CMS製品、デフォルトでjQuery mobile使用+open redirectorあり
  • 非常に広範なwebサイトでXSSが可能だった

オフレコ


C: Open Redirector → Auth bypass

  • server side.
  • URL parserバグ起因のものは実際の事例は見つけていない
  • 危なっかしい状態だったものはあり

validation of callback url

  • OAuth, OpenIDなどのredirect url
  • domainのみ一致でcheckしていると危険
  • URL parserがバグっていると。。。
  • そもそも「ドメイン」丸ごと安全とは限らない

Why?

  • ホスト名誤認を使って別ドメインに認証コードを送る
  • オープンリダイレクタとの組み合わせ
  • referrerで外部に認証コードが漏洩するPathを指定する

Provider実装側

  • Pathは先頭一致にしないで「完全一致」にすべき
  • redirect_uri=http://example.com/auth/callback/../../../
  • これが通ってしまうと別Pathに認証コードを送ることが可能
  • そもそもuser:passが入ってるのとおかしいので、正規化して完全一致にしましょう。
  • query string部分のみ除去して登録済みURLと比較

D: SSRF / TOCTOU attack

  • イントラネットのURLにHTTP requestを送る
  • 管理画面に攻撃コード送る
  • 変換系処理のAPIで内容を取得する

SSRF with URL Parser's bug

  • URLがintranetのhostではないか確認
  • → hostname誤認問題があるparserを使っていると。。。
  • 解釈の違いによって問題が起きる場合がある

そもそも

  • check と use は異なる実装で行ってはいけない
  • Time-of-check Time-of-use problem
  • URLをcheckするタイミング、fetchするタイミング
  • DNSが変更されている可能性がある

バグをなくすための考え方

  • check / use で可能であれば同じ実装を使いましょう。
  • check / use は同じデータを使いましょう。
  • "Normalize strings before validating them"

HTML parserの問題

  • 以前発表した
  • <!--> --> の解釈の違いを使ったXSS
  • ブラウザの実装と、jsやサーバーサイドで解釈が違う
  • TinyMCE, etc.

URL Parserの場合

  • client / server / language 複数の実装が混在するのは必然
  • need more test case.

終わり


おまけ

各言語のURL Parserの実装について

Ruby

コアモジュール、URI class.

https://github.com/ruby/ruby/blob/trunk/lib/uri/rfc2396_parser.rb https://github.com/ruby/ruby/blob/trunk/lib/uri/rfc3986_parser.rb

RFCをそのまま正規表現に。 厳格。


Perl

URI moduleの中の URI::_generic を見ると良い http://cpansearch.perl.org/src/ETHER/URI-1.71/lib/URI/_generic.pm

  • 各partごとに正規表現で定義
  • 内部的には単に文字列で保持
  • 呼び出されたタイミングで指定されたパートを取り出している

Python

https://github.com/python-git/python/blob/master/Lib/urlparse.py


PHP バグあり。レポート済み。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment