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
JSでDoSる/ Shibuya.XSS techtalk #11
Search
Masato Kinugawa
May 16, 2019
Technology
7.2k
20
Share
JSでDoSる/ Shibuya.XSS techtalk #11
Shibuya.XSS techtalk #11 の発表資料です。
Masato Kinugawa
May 16, 2019
More Decks by Masato Kinugawa
See All by Masato Kinugawa
Shadow DOMとセキュリティ - 光と影の境界を探る / Shibuya.XSS techtalk #13
masatokinugawa
0
810
Shadow DOM & Security - Exploring the boundary between light and shadow
masatokinugawa
1
2.1k
ブラウザのレガシー・独自機能を愛でる-Firefoxの脆弱性4選- / Browser Crash Club #1
masatokinugawa
1
1.1k
注目したいクライアントサイドの脆弱性2選/ Security.Tokyo #3
masatokinugawa
8
4.3k
バグハンティングのすゝめ / P3NFEST
masatokinugawa
5
2.7k
Pwn2OwnでMicrosoft Teamsをハッキングして2000万円を獲得した方法/ Shibuya.XSS techtalk #12
masatokinugawa
13
21k
How I Hacked Microsoft Teams and got $150,000 in Pwn2Own
masatokinugawa
1
24k
Electron: Abusing the lack of context isolation - CureCon(en)
masatokinugawa
5
110k
Electron: Context Isolationの欠如を利用した任意コード実行 / Electron: Abusing the lack of context isolation - CureCon(ja)
masatokinugawa
9
29k
Other Decks in Technology
See All in Technology
Swift Sequence の便利 API 再発見
treastrain
1
260
Vision Banana: Image Generators are Generalist Vision Learners
kzykmyzw
0
360
アプリブロック機能のつくりかたと、AIとHTMLの不合理な相性の良さについて
kumamotone
1
250
Modernizing Your HCL Connections Experience: Visual Report to chain, Profile Enhancements, and AI Integration
wannesrams
0
300
ワールドカフェ再び、そしてゴール・ルール・ロール・ツール / World Café Revisited, and the Goals-Rules-Roles-Tools
ks91
PRO
0
140
AI時代に越境し、 組織を変えるQAスキルの正体 / QA Skills for Transforming an Organization
mii3king
5
4.3k
Shiny New Tools Won't Fix Your Problem
trishagee
1
120
AI-Assisted Contributions and Maintainer Load - PyCon US 2026
pauloxnet
1
100
Sociotechnical Architecture Reviews: Understanding Teams, not just Artefacts
ewolff
1
170
AI駆動開発で生産性を追いかけたら、行き着いたのは品質とシフトレフトだった
littlehands
0
490
20260513_生成AIを専属DSに_AI分析結果の検品テクニック_ハンズオン_交通事故データ
doradora09
PRO
0
220
(きっとたぶん)人材育成や教育のような何かの話
sejima
0
710
Featured
See All Featured
Technical Leadership for Architectural Decision Making
baasie
3
360
Exploring anti-patterns in Rails
aemeredith
3
350
KATA
mclloyd
PRO
35
15k
Color Theory Basics | Prateek | Gurzu
gurzu
0
310
Facilitating Awesome Meetings
lara
57
6.8k
30 Presentation Tips
portentint
PRO
1
290
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
510
Mobile First: as difficult as doing things right
swwweet
225
10k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
120
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
180
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
440
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
690
Transcript
for(;;){ alert(` `); } /* 2019/05/16 Shibuya.XSS techtalk #11*/ /*
Masato Kinugawa */
• • •
None
• • • • •
• • • •
• • • • • • • • • •
•
while(1){ alert(` `); }
• •
•
• • > decodeURIComponent("%E3%81%82"); < " " > decodeURIComponent("%FF"); ‣
Uncaught URIError: URI malformed
None
• • • > encodeURIComponent(" "); < "%E3%81%82" > encodeURIComponent("\uDC00");
‣ Uncaught URIError: URI malformed
https://www.ecma-international.org/ecma-262/9.0/index.html#sec-encode
(function a(){ alert(` `); a(); })()
• • • • / \/ • " \" •
\ \\ <script> userInput = "AAA\\\";alert(1)\/\/ <\/script>"; displayContents(); </script>
• <script> userInput = "AAA [ ] BBB"; displayContents(); </script>
• <script> userInput = "AAA BBB"; displayContents(); </script>
• https://www.ecma-international.org/ecma-262/9.0/index.html#table-33
• https://www.ecma-international.org/ecma-262/9.0/index.html#table-33
• <script> userInput = "AAA [U+2028] BBB"; displayContents(); </script>
• • • • •
<script> userInput = "<!--<script>"; displayContents(); </script>
• • <script> userInput = "<!--<script>"; </script> <textarea></script> <img src=x
onerror=alert(1)> </textarea>
• • https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script- elements
• <script> userInput = "<%"; </script> <textarea>%></script><img src=x onerror=alert(1)> </textarea>
https://html5sec.org/#91 <xmp> <% </xmp> <textarea> %></xmp><img src=x onerror=alert(1)> </textarea>
• • • • •
setInterval(` alert(\` \`) `,1);
• •
•
• • • userInfo = {"name": 123}// name = userInfo.name.toUpperCase()
Uncaught TypeError: userInfo.name.toUpperCase is not a function
siteData = {"url":"https:// ...","title":{"toString":null},...}; url = "url: " + siteData.url;
title = "title: " + siteData.title;
• • • ({toString: function(){alert(1)} })+""; ({valueOf : function(){alert(2)} })+"";
• • • > ({toString:null})+""; ‣ Uncaught TypeError: Cannot convert
object to primitive value
• • • • •
• > typeof "aaa"; < ‣ "string" > typeof 123;
< ‣ "number" > typeof true; < ‣ "boolean" > typeof []; < ‣ "object" > typeof {}; < ‣ "object" > typeof null; < ‣ "object"
• • > Array.isArray([]); < ‣ true > Array.isArray({}); <
‣ false > null === null < ‣ true
• • > Object.prototype.toString.call("aaa"); < ‣ "[object String]" > Object.prototype.toString.call(123);
< ‣ "[object Number]" > Object.prototype.toString.call(true); < ‣ "[object Boolean]" > Object.prototype.toString.call([]); < ‣ "[object Array]" > Object.prototype.toString.call({}); < ‣ "[object Object]" > Object.prototype.toString.call(null); < ‣ "[object Null]"
<style>*{ color:expression( alert(" ") )}
• • • <toString>AAA</toString>
• • •
• • function tellMeFruitColor(USER_INPUT){ fruits = { "apple":"red", "lemon":"yellow", "peach":"pink"
}; if(fruits[USER_INPUT]){ return USER_INPUT + ": " + fruits[USER_INPUT]; }else{ return "I don't know that fruit"; } }
> tellMeFruitColor("apple"); < "apple: red" > tellMeFruitColor("lemon"); < "lemon: yellow"
> tellMeFruitColor("strawberry"); < "I don't know that fruit" > tellMeFruitColor("toString"); < "toString: function toString() { [native code] }" > tellMeFruitColor("constructor"); < "constructor: function Object() { [native code] }" > tellMeFruitColor("__proto__"); < "__proto__: [object Object]"
None
• •
https://qiita.com/howdy39/items/35729490b024ca295d6c
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
if(fruits["toString"]){ return "toString" + ": " + fruits["toString"]; }else{ return
"I don't know that fruit"; }
> ({"toString":function(){return "a"}})+""; < " " > ({"prop":"a"})+""; < "[object
Object]"
whiteListTags = { "span":funcForSanitizingSpanElem, "div": funcForSanitizingDivElem, "a":" funcForSanitizingAElem, ... }
// whiteListTags[ ] <toString> whiteListTags["toString"]()
fileIcons = { "txt":"https://example.com/img/icon-txt.gif", "png":"https://example.com/img/icon-png.gif", "jpg":" https://example.com/img/icon-jpg.gif ", ... }
// fileIcons[ ] dos.constructor fileIcons["constructor"]
• • • •
• • function tellMeFruitColor(USER_INPUT){ fruits = { ... }; -
if(fruits[USER_INPUT]){ + if(Object.prototype.hasOwnProperty.call(fruits,USER_INPUT)){ return USER_INPUT + ": " + fruits[USER_INPUT]; }else{ return "I don't know that fruit"; } }
> tellMeFruitColor("apple"); < "apple: red" > tellMeFruitColor("lemon"); < "lemon: yellow"
> tellMeFruitColor("strawberry"); < "I don't know that fruit" > tellMeFruitColor("toString"); < "I don't know that fruit" > tellMeFruitColor("constructor"); < "I don't know that fruit" > tellMeFruitColor("__proto__"); < "I don't know that fruit"
• • fruits["toString"] undefined function tellMeFruitColor(USER_INPUT){ - fruits = {
... }; + fruits = Object.create(null); + fruits = Object.assign(fruits,{"apple":"red","lemon": ... }) if(fruits[USER_INPUT]){ return USER_INPUT + ": " + fruits[USER_INPUT]; }else{ return "I don't know that fruit"; } }
• • function tellMeFruitColor(USER_INPUT){ - fruits = { ... };
+ fruits = new Map(["apple","red"], + ["lemon","yellow"], + ["peach","pink"]); - if(fruits[USER_INPUT]){ - return USER_INPUT + ": " + fruits[USER_INPUT]; + if(fruits.get(USER_INPUT)){ + return USER_INPUT + ": " + fruits.get(USER_INPUT); }else{ return "I don't know that fruit"; } }
({toString: function(){ alert(` `); this+""; } })+"";
• •
• • • USER_INPUT = {"length": 1e10,"constructor":{"name":"Array"}}; if(USER_INPUT.constructor.name === "Array"){
array = []; for (var i = 0; i < USER_INPUT.length; i++) { array.push(USER_INPUT[i]); } }
==== JS stack trace ========================================= Security context: 00000099763A5549 <JSObject> 1:
/* anonymous */ [repl:~1] [pc=000000C1A3E8B9B9](this=00000382794865D9 <JSGlobal Object>) 5: /* anonymous */ [vm.js:65] [bytecode=000002EDD76E8421 offset=87](this=0000021A2A00C731 <ContextifyScript map = 00000203C25E1319>,options=0000021A2A00C709 <Object map = 00000203C25E13C9>) 6: defaultEval [repl.js:244] [bytecode=000002EDD76E7089 offset=445](this=0000021A2A00C7A1 <REPLServer ... FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 1: node::DecodeWrite 2: node_module_register 3: v8::internal::FatalProcessOutOfMemory 4: v8::internal::FatalProcessOutOfMemory 5: v8::internal::Factory::NewUninitializedFixedArray 6: v8::internal::WasmDebugInfo::SetupForTesting 7: v8::internal::interpreter::BytecodeArrayRandomIterator::UpdateOffsetFromIndex 8: 000000C1A3D043C1
• • •
•
• • • • •
for(;;){ alert(` `); } /* */