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
9.6k
25
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実例に学ぶ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
More Decks by mala
See All by mala
The Evolution of Alert & Notification System / Becks Japan #1
mala
11
9k
TBD/Shibuya.XSS techtalk #8
mala
5
2.8k
超絶技巧CSRF / Shibuya.XSS techtalk #7
mala
41
15k
How to hack metacpan.org
mala
7
1.4k
SECCON2013 slide
mala
14
3k
Other Decks in Programming
See All in Programming
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
440
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
280
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
500
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
560
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.7k
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
750
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
910
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
330
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
570
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
290
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
200
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
170
Featured
See All Featured
Color Theory Basics | Prateek | Gurzu
gurzu
0
400
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
230
Context Engineering - Making Every Token Count
addyosmani
9
1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
980
Speed Design
sergeychernyshev
33
2k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
190
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.5k
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͍ͯ͘͜͠͠ • ҆શʹ͢ΔͨΊͷγϯϓϧͳݪଇ͋Δ • ಈతͳίʔυੜΛආ͚ΔɺࣗಈΤεέʔϓΛ͏ • + ݪଇΛ֎Εͨ࣌ʹةݥͩͱ͢Δηϯε͕ඞཁ