Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
実例に学ぶXSS脆弱性の発見と修正方法/line_dm 16 20160916 how to ...
Search
mala
September 26, 2016
Programming
25
9.4k
実例に学ぶXSS脆弱性の発見と修正方法/line_dm 16 20160916 how to find and fix xss
LINE Developer Meetup in Fukuoka #16
http://connpass.com/event/38413/
mala
September 26, 2016
Tweet
Share
More Decks by mala
See All by mala
The Evolution of Alert & Notification System / Becks Japan #1
mala
11
8.8k
TBD/Shibuya.XSS techtalk #8
mala
5
2.7k
超絶技巧CSRF / Shibuya.XSS techtalk #7
mala
41
14k
How to hack metacpan.org
mala
7
1.4k
SECCON2013 slide
mala
14
3k
Other Decks in Programming
See All in Programming
Portapad紹介プレゼンテーション
gotoumakakeru
1
130
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_install_cms
rdlabo
0
480
大規模FlutterプロジェクトのCI実行時間を約8割削減した話
teamlab
PRO
0
480
CEDEC2025 長期運営ゲームをあと10年続けるための0から始める自動テスト ~4000項目を50%自動化し、月1→毎日実行にした3年間~
akatsukigames_tech
0
140
Go製CLIツールをnpmで配布するには
syumai
2
1.2k
GUI操作LLMの最新動向: UI-TARSと関連論文紹介
kfujikawa
0
950
Langfuseと歩む生成AI活用推進
licux
3
240
Flutter로 Gemini와 MCP를 활용한 Agentic App 만들기 - 박제창 2025 I/O Extended Seoul
itsmedreamwalker
0
140
Gemini CLIの"強み"を知る! Gemini CLIとClaude Codeを比較してみた!
kotahisafuru
3
1.1k
プロダクトという一杯を作る - プロダクトチームが味の責任を持つまでの煮込み奮闘記
hiliteeternal
0
460
#QiitaBash TDDで(自分の)開発がどう変わったか
ryosukedtomita
1
370
自作OSでDOOMを動かしてみた
zakki0925224
1
1.3k
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.4k
BBQ
matthewcrist
89
9.8k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
460
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
890
Optimising Largest Contentful Paint
csswizardry
37
3.4k
What's in a price? How to price your products and services
michaelherold
246
12k
Transcript
࣮ྫʹֶͿXSS੬ऑੑͷ ൃݟͱमਖ਼ํ๏ ma.la
ςʔϚ • ͍͔ͭ͘ࠓ·ͰXSSʹؔͯ͠ൃද͖ͯͨ͠(AppSec,AVTokyo, etc) • ओʹൣͳαΠτʹӨڹ͢ΔϥΠϒϥϦͷ੬ऑੑͳͲΛղઆ • ࠓճൃݟํ๏ࣄྫʹ͍ͭͯத৺ʹղઆ • αΠτ։ൃऀଆͰͷରࡦ͕ඞཁͳՕॴ
Part0. XSSͬͯԿ • αʔϏεΛఏڙ͍ͯ͠ΔυϝΠϯ্ͰɺҙͷJavaScriptίʔυ͕࣮ߦ Ͱ͖Δ੬ऑੑ • ͦͷυϝΠϯͰදࣔ͞ΕΔใΛ౪Έग़ͨ͠Γɺউखʹߋ৽͢Δ͜ͱ͕ ग़དྷΔ • डಈత߈ܸ:
ඃΛड͚Δͷ߈ܸϦϯΫΛ౿ΜͩϢʔβʔ
Part1. How to find XSS
ίʔυϨϏϡʔͷϙΠϯτ • ೖྗՕॴͱධՁ͢ΔՕॴʹ͢Δ • source ͱ sink ͱݺΕͨΓ͢Δ
୯७ͳXSSͷ߹ • αʔόʔଆͷHTML templateͰͷग़ྗՕॴɺධՁՕॴಉ͡ • ग़ྗՕॴͰhtml tagscriptΛදࣔ • ίʔυΛ͍͚ͬͯେମશ෦ݟ͔ͭΔ •
Ұ෦Λআ͖ɺࣗಈΤεέʔϓͰશ෦Δ
୯७Ͱͳ͍XSSͷࣄྫ • JavaScriptίʔυͷಈతੜ • URLͷՕॴʹ javascript:xxx • HTML escapeͰ͛ͳ͍ •
DOM based XSSͱݺΕΔͷ
DOM based XSSͷ߹ • ೖྗՕॴͱධՁ͢ΔՕॴ͕ҧ͏ • JavaScriptͷίʔυΛΘͳ͍ͱ͔Βͳ͍ • ൃݟ͕͍͠ݪҼ
ೖྗՕॴͷྫ location.* (location.href, location.hash, etc) document.* (document.URL, document.cookie, etc) window.name
ධՁ͢ΔՕॴͷྫ ೖྗ͞Εͨύϥϝʔλ͕ग़ྗ͞ΕΔՕॴ URLͱͯ͠ධՁɺJavaScriptίʔυͱͯ͠ධՁɺHTMLͱͯ͠ධՁ
URLͱͯ͠ධՁ • location.href = , iframe.src = • ajax, XMLHttpRequest
ͰͷಡΈࠐΈ • etc
ίʔυͱͯ͠ධՁ • ίʔυΛಈతʹੜ͢ΔΑ͏ͳ͍ํ (͋·Γແ͍) • eval() • จࣈྻͰͷ setTimeout() setInterval()
(͋·ΓΘΕͳ͍) • Function() (͋·ΓΘΕͳ͍) • etc
HTMLग़ྗ • innerHTML = • document.write() • jQuery() $() $(el).html()
• ֤छςϯϓϨʔτΛͬͨग़ྗ • etc
ίʔυͷྲྀΕΛ͍ͬͯ͘ • ag ͳͲͷίʔυݕࡧπʔϧΛ͏ • ҆શͩͱ֬ೝ͕Ͱ͖ͨॴআ֎͍ͯ͘͠ • ag innerHTML |
ag -v "safe" • ೖྗՕॴɺग़ྗՕॴɺͲͪΒ͔ΒͰո͍͠Օॴݟ͔ͭΔ
ݟམͱ͕ͪ͠ͳϙΠϯτ
document.cookie / localStorage • ݕࡧΩʔϫʔυཤྺΛอ࣋͢Δػೳ • ҙͷΛอଘग़དྷΔ͜ͱ͕͋Δ • ೖྗ࣌ͱग़ྗ࣌Ͱ͕࣌ؒࠩൃੜ͢Δ͜ͱ͕͋Δ
Persistent DOM XSS • DOM based XSSͷӬଓԽ͕Մೳ • cookie /
localStorageʹ߈ܸ༻ͷίʔυΛอଘ • දࣔ͢Δͨͼʹ࣮ߦ͞ΕΔΑ͏ͳέʔε • → ࣗࣾͰͷࣄྫɺࠂωοτϫʔΫͷiframeͰ࣮ྫ͋Γ
ಛʹ cookie ͷ߹ • αϒυϝΠϯ͔ΒͰઃఆ͕Մೳ • vuln.example.com → .example.com •
੬ऑੑͷ͋ΔαϒυϝΠϯ͔ΒcookieΛset • ߈ܸରͷυϝΠϯͰ cookie ىҼͷ DOM based XSS • MITM attackͰcookieͷઃఆ͕Մೳ
CookieΛͬͨ߈ܸ (XSS or ServerSide) • ͦͷαʔϏεͰ৴༻Ͱ͖Δ͔͠ग़ྗ͠ͳ͍߹ͰXSSՄೳ • MITMͰͷcookieઃఆ → HSTS
include subdomainΛΘͳ͍ͱ͛ͳ͍ • JS ͰserverͰ৴པͰ͖ͳ͍͕ೖΔ͜ͱΛલఏʹઃܭ͢Δඞཁ͕͋Δ • ࡉͨ͠cookieΛͬͨremote code executionͷࣄྫ͍͔ͭ͋͘Γ
Part2. मਖ਼ํ๏
ग़ྗՕॴʹԠͯ҆͡શʹ͢Δ • ධՁ͞ΕΔίϯςΩετʹԠͯ͡ରࡦҧ͏ • શͯʹରͯ͠༗ޮͳvalidationescape ruleଘࡏ͠ͳ͍ • յΕͯྑ͍ͳΒҰϑΟϧλ͢ΔΑ͏ͳॲཧ࡞ΕΔ <> ͕ೖྗ͞Ε͍ͯΔͱແ༻ͰΤϥʔʂ
JavaScriptͷมग़ྗ • ͦͦආ͚Δ • data-xxx="html escaped value" ͰຒΊࠐΈΛਪ • ಉ͡escape
ruleͰରԠՄೳɺίϯςΩετΛҙࣝ͠ͳ͍͍ͯ͘ • Ͳ͏ͯ͠ඞཁͰ͋Εɺhtml escapeͰͳ͘js escape
URLΛग़ྗ͢Δ߹ • javascript: xxx ͕ೖ͍͚ͬͯͳ͍ • ̋ validation ruleΛ࡞ͬͯద༻͢Δ •
HTML Escape / JS escape ͚ͩͰෆे • URLΛೖग़ྗ͢ΔΑ͏ͳՕॴɺͲͷΈͪvalidation͕͋Δͣ
ίʔυΛੜ͢Δ߹ • eval() ͦͦΘͳ͍Α͏ʹ͢Δ • JSON.parseͷ༻ͱͯ͠ɺͨ·ʹݟΔ → ͏͍Βͳ͍ɺpolyfill༻͢ΕΑ͍
HTMLΛग़ྗ͢Δ߹ • innerHTMLΛͳΔ͘Θͳ͍(࠷ऴతͳग़ྗ࣌ͷΈ) • ࣗಈescapeՄೳͳtemplate engine͏ → mustache ͳͲ •
jQuery ͷ html() → ෆཁͰ͋Ε text() ʹஔ͖͑Δ • html() ͷଟ༻ϨϏϡʔͷෛ୲ʹͳΔ
XSSͷݟ͚ͭํͱ͠ํಉ͡ • ag ͳͲͷίʔυݕࡧπʔϧΛ͏ • ҆શͩͱ֬ೝ͕Ͱ͖ͨॴআ֎͍ͯ͘͠ • ag innerHTML |
ag -v "safe" • ೖྗՕॴɺग़ྗՕॴɺͲͪΒ͔ΒͰո͍͠Օॴݟ͔ͭΔ
मਖ਼ํ๏ͷϙΠϯτ • ։ൃऀ͔Βݟͯ҆શ != ϨϏϡΞʔ͔Βݟͯ҆શ • ։ൃऀةݥ͕ແ͍ύϥϝʔλͱ͍ͬͯͯύοͱݟͰΘ͔Βͳ͍ • ιʔείʔυݕࡧͰɺո͍͠Օॴ͕ݟ͔ͭΒͳ͍ঢ়ଶ •
ϨϏϡʔ͍͢͠ίʔυʹ͢Δ → ࣗͰίʔυݕࡧͯ͠ΈΔͱྑ͍
Part3. ൃੜཁҼͷ • ͲͷλΠϛϯάͰԿʹҙ͢Εྑ͍ͷ͔͔Βͳ͍ • ةݥͳ͜ͱΛ͍ͯ͠Δ͕֮ࣗͳ͍ • ʮԿΛ͠Α͏ͱͯ͠ى͖ͨͷ͔ʯΛओ࣠ʹղઆ
ࣄྫ: ݕࡧΩʔϫʔυͷදࣔ • ϦϑΝϥ͔Βऔಘ • ݕࡧΫΤϦ͔Βͷऔಘ • ࠂ࠷దԽ༻ͷύϥϝʔλΩʔϫʔυϋΠϥΠτͰ͍ͬͯͨ • ऩӹ૿ՃͷͨΊʹ͋ΒΏΔαʔϏεʹXSS͕Ճ͞Ε͍ͯͨ
۩ମྫ var keyword = '[% param.keyword | html %]'; //
͜Ε͕ ↓ var keyword = ''; alert(1); ''; // ͜͏ͳΔ • ͍࣌ͬͯͨςϯϓϨʔτΤϯδϯ͕ɺγϯάϧΫΦʔτΛΤεέʔ ϓ͠ͳ͔ͬͨ • ࠓͰ͋·ΓΈͳ͍ • ϦϑΝϥ͔Βऔಘ͢Δͷ → DOM based XSSʹ
ϦϑΝϥΛͬͨXSS • ϦϑΝϥ͔ΒΩʔϫʔυऔಘͯ͠Φεεϝهࣄදࣔ • ϦϑΝϥʹ ه߸HTMLλά͕ೖΔ͜ͱΛఆ͍ͯ͠ͳ͍
ֶͼ • ϓϥεΞϧϑΝͷػೳͰXSS͕ى͖͍ͯΔ • αʔϏεͷຊମͷػೳ͡Όͳ͍෦Ͱ͍ͭͷؒʹ͔XSS͕ग़དྷͯΔ • ։ൃऴΘͬͯΔΜ͚ͩͲɺ༉அͯ͠Δͱ͜ΖͰɻɻ • ιʔγϟϧϘλϯՃ →
ݱࡏͷURLΛdocument.writeͰग़ྗɺ
ࣄྫ: HTML EntityͷղऍΛ͍ͨ͠ • $(el).text() Λͬͯද͍ࣔͯͨ͠Β HTML࣮ମࢀরɺࢀরจࣈ͕ද ࣔ͞Εͳ͘ͳͬͨ • ͜͏͍͏ͷͶ
B'z → B'z • → $(el).html() ʹมߋɺࣗಈΤεέʔϓ֎͢ॲཧΛೖΕͯ͠·͏ • Ϣʔβʔೖྗ͕ೖΒͳ͍͔Ͳ͏͔֬ೝ͕ඞཁ • ҆શͳೖྗՕॴͰ͋ͬͯϨϏϡʔ͕େมʹͳΔ
Ͳ͏͢Εྑ͍ʁ • HTML entityͷղऍͷͨΊʹɺhtml() ΛΘͳ͍ɻ • html() Λ͏ͱɺ͋ΔಥવةݥʹͳΔ • ඞཁͳॲཧhtmlग़ྗͰͳ͘ɺdecode
html entities • textarea hack $("<textarea/>").html(value).text()
ࣅͨࣄྫ: escapeํࣜͷมߋ • αʔόʔαΠυͰΤεέʔϓɺjsͰͷग़ྗͰΤεέʔϓ • ೋॏescapeʹͳͬͯ͠·ͬͨʂ & " ͳͲ͕ը໘ʹදࣔ͞Ε
Δ • html escape → js escape ͷมߋ • ͜Εࣗମਖ਼͍͕͠ɺຊʹେৎʁ
escapeํࣜมߋʹ͏ • A: ̋ js escapeͰมຒΊࠐΈ → js templateͰauto escapeͰදࣔ
• B: ˚ html escapeͰมຒΊࠐΈ → js templateͰauto escapeͰදࣔ → ೋॏescape • C: ☓ js escapeͰมຒΊࠐΈ → innerHTML $() html() Ͱग़ྗՕॴ͕͋Δ
Կ͕͔ʁ • ೋॏΤεέʔϓόά͚ͩͲ XSS ੬ऑੑ • B → C ʹѱԽ͢ΔՄೳੑ͕͋Δ
(όάΛͯ͠੬ऑੑ͕ൃݱ) • पลՕॴͷϨϏϡʔηοτͰߦΘͳ͍ͱμϝ
ֶͼ • ද͕ࣔόάͬͯ·͢ → ҰൠϢʔβʔQA͔Βͷใࠂ • ରॲྍ๏తʹ͢ɺ͔ͬͯΔਓ͕ϨϏϡʔ͠ͳ͍··ద༻ • ೋॏΤεέʔϓόά͕XSSͱͯ͠ѱԽͯ͠͠·͏ •
ͨ͠ຊਓόάΛͨͭ͠Γ
ࣄྫ: ίϝϯτΞτ ׂͱ͍͠λΠϓ
JavaScriptதͷมग़ྗՕॴͷίϝϯτΞτ • /* */ Λ͏έʔε • */ ΛೖΕΔ͜ͱͰίϝϯτΛڧ੍ऴྃ͢Δ /* var
keyword = '[% keyword %]' */ ↓ /* var keyword = '*/ alert(1) /*' */
// Λ͏έʔε • վߦͰಥഁՄೳ // var keyword = ' alert(1)//‘
• U+2028 / U+2029 ͰಥഁՄೳ • վߦΛϑΟϧλͳΜͯத్ͳ͜ͱ͠ͳ͍Α͏ʹɻ
ίϝϯτΞτ • jsͷಈతੜɺมຒΊࠐΈΛΊΔɺͱ͍͏ݪଇͰରԠՄೳ • มग़ྗՕॴͷจ຺Λҙࣝ͢Δ͜ͱͰ͙ → ͍͠ • JavaScriptத͔ͩΒjs escape!!
ͱ͍͏ܒ͕ग़དྷ͍ͯͯൃੜ͢Δ • ͦͦίϝϯτΞτ͠ͳ͍Ͱؙ͝ͱফ͢ɺgitʹϩάΔ
ࣄྫ: ίϯςϯπͷಈతͳϩʔυ • HTMLஅยΛදࣔ͢ΔΑ͏ͳέʔε • Single page appͷྲྀߦͰଟ͘ͳͬͨ → router͕ͪΌΜͱॻ͔Ε͍ͯ
Ε੬ऑੑগͳ͍ • ͪΐͬͱલʹ࡞ΒΕͨΑ͏ͳαΠτɺlocation.hash ͔Βऔಘ • ΞχϝެࣜαΠτϥϯσΟϯάϖʔδͳͲͰΑ͘ݟΔ
HTMLஅยϩʔυͷ • ಉҰυϝΠϯʹ੍ݶ͍ͯͯ҆͠શͰͳ͍έʔε͕͋Δ • ಉҰυϝΠϯʹΦʔϓϯϦμΠϨΫλ • ಉҰυϝΠϯͰ <> ΛؚΉίϯςϯπΛಈతੜՄೳ(JSONP API)
• ඞཁͳ͜ͱ → ఆͨ͠path͔Ͳ͏͔ͷݫ֨ͳνΣοΫ
ϥΠϒϥϦͰͷ • ಉҰυϝΠϯͷίϯςϯπ҆શͰ͋Δɺͱ͍͏ࢥ͍ࠐΈ • jQuery mobile → ϋογϡࢦఆͰಉҰυϝΠϯϩʔυ • Rails
ͷ turbolinks → ϦϯΫઌΛAjaxͰಡΈࠐΜͰߴԽ • ύονॻ͍ͨΓͨ͠ (ಈతϩʔυΛߦͳ͏content-typeͷ੍ݶ)
·ͱΊ • XSS͍ͯ͘͜͠͠ • ҆શʹ͢ΔͨΊͷγϯϓϧͳݪଇ͋Δ • ಈతͳίʔυੜΛආ͚ΔɺࣗಈΤεέʔϓΛ͏ • + ݪଇΛ֎Εͨ࣌ʹةݥͩͱ͢Δηϯε͕ඞཁ