Repository navigation
Expand file tree
/
Copy path5.html
More file actions
317 lines (288 loc) · 15.7 KB
/
Copy path5.html
File metadata and controls
317 lines (288 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="AnnaWiktoria">
<meta name="copyright" content="AnnaWiktoria">
<meta name="description" content="Interaktywny kurs bezpieczeństwa aplikacji webowych. Licencja CC BY-NC-SA.">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
script-src 'self' 'unsafe-inline';
img-src 'self' data:;">
<title>Kurs bezpieczeństwa aplikacji webowych -Lekcja 05: SOP & CORS</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<style>
/* Akcent: Neon Orange (Boundaries/Firewalls) */
:root {
--accent: #ff6d00;
--accent-glow: rgba(255, 109, 0, 0.3);
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>SOP & CORS</h1>
<p>MODUŁ 05: Granice Internetu i Wyciek Danych Cross-Origin</p>
</header>
<!-- 1. SOP - PRAWO -->
<section>
<h2>> SOP (SAME-ORIGIN POLICY)</h2>
<p>SOP to najważniejsza reguła bezpieczeństwa w przeglądarce. To "Wielki Mur", który oddziela strony od
siebie.</p>
<div class="card">
<h3>ZASADA DZIAŁANIA</h3>
<p>Skrypt z domeny <code>A.com</code> <strong>nie może odczytać</strong> danych z domeny
<code>B.com</code>, chyba że domena B wyraźnie na to pozwoli.</p>
<p>Gdyby SOP nie istniał, wchodząc na <code>smieszne-koty.pl</code>, skrypt JS na tej stronie mógłby
odczytać Twoje maile z otwartej w tle karty <code>gmail.com</code>.</p>
</div>
<div class="card">
<h3>CO TO JEST "ORIGIN"?</h3>
<p>Dwie strony mają ten sam "Origin" (pochodzenie) tylko wtedy, gdy zgadzają się 3 elementy:</p>
<ol>
<li><strong>Protokół</strong> (np. https)</li>
<li><strong>Domena</strong> (np. bank.com)</li>
<li><strong>Port</strong> (np. 443)</li>
</ol>
</div>
<table>
<thead>
<tr>
<th colspan="2">Porównanie z: <span style="color:#fff">https://bank.com</span></th>
</tr>
<tr>
<th>Adres URL</th>
<th>Wynik SOP</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>https://bank.com/konto</code></td>
<td><span class="secure">SAME ORIGIN</span> (Zgodne)</td>
</tr>
<tr>
<td><code>http://bank.com</code></td>
<td><span class="status-badge s-5xx">CROSS ORIGIN</span> (Inny protokół)</td>
</tr>
<tr>
<td><code>https://api.bank.com</code></td>
<td><span class="status-badge s-5xx">CROSS ORIGIN</span> (Inna subdomena)</td>
</tr>
<tr>
<td><code>https://bank.com:8080</code></td>
<td><span class="status-badge s-5xx">CROSS ORIGIN</span> (Inny port)</td>
</tr>
</tbody>
</table>
</section>
<!-- 2. CORS - WYJĄTEK -->
<section>
<h2>> CORS (CROSS-ORIGIN RESOURCE SHARING)</h2>
<p>Czasami <code>frontend.com</code> MUSI pobrać dane z <code>api.backend.com</code>. SOP na to nie pozwala.
Wtedy wkracza CORS.</p>
<p>CORS to system "wizowy". Serwer API wysyła nagłówki mówiące przeglądarce: <br><em>"Spoko, pozwalam
domenie frontend.com czytać moje dane"</em>.</p>
<div class="card">
<h3>KLUCZOWE NAGŁÓWKI (ODPOWIEDŹ SERWERA)</h3>
<ul>
<li><code>Access-Control-Allow-Origin: https://zaufana.com</code> <br>
Tylko ta jedna domena może czytać odpowiedź.</li>
<li><code>Access-Control-Allow-Credentials: true</code> <br>
Pozwala przesyłać ciasteczka (sesję) w zapytaniu Cross-Origin. <strong>Krytyczne dla
bezpieczeństwa.</strong></li>
</ul>
</div>
</section>
<!-- 3. ATAKI -->
<section>
<h2>> BŁĘDY KONFIGURACJI CORS</h2>
<p>Pentesterzy szukają sytuacji, w których serwer jest "zbyt miły" i pozwala czytać dane atakującemu.</p>
<div class="card">
<h3>SCENARIUSZ 1: REFLECTED ORIGIN (Odbicie lustrzane)</h3>
<p>Programista był leniwy i napisał skrypt, który kopiuje nagłówek <code>Origin</code> z żądania do
nagłówka <code>Access-Control-Allow-Origin</code> w odpowiedzi.</p>
<pre><code><span class="comment"># Żądanie atakującego (złośliwa strona)</span>
GET /api/private-data HTTP/1.1
Host: bank.com
Origin: https://evil-hacker.com
<span class="comment"># Odpowiedź serwera (BŁĄD!)</span>
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://evil-hacker.com
Access-Control-Allow-Credentials: true</code></pre>
<p><strong>Skutek:</strong> Haker może stworzyć stronę, która w tle odpyta bank ofiary, a przeglądarka
pozwoli hakerowi odczytać saldo konta (bo serwer na to "zezwolił").</p>
</div>
<div class="card">
<h3>SCENARIUSZ 2: WILDCARD Z CREDENTIALS</h3>
<p>Konfiguracja:</p>
<pre><code>Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true</code></pre>
<p>To teoretycznie "święty graal", ale nowoczesne przeglądarki <strong>blokują</strong> takie
połączenie. Nie można używać gwiazdki (<code>*</code>) razem z <code>true</code>. Jednak często
zdarza się w starych aplikacjach lub narzędziach mobilnych.</p>
</div>
<div class="card">
<h3>SCENARIUSZ 3: NULL ORIGIN</h3>
<p>Niektóre serwery blokują obce domeny, ale pozwalają na <code>null</code>. Atakujący może użyć
sandboxed iframe: <code><iframe sandbox="allow-scripts ...</code>, który wysyła żądanie z
<code>Origin: null</code>. Jeśli serwer to akceptuje -> Wyciek danych.</p>
</div>
</section>
<!-- CHECKLIST -->
<section>
<h2>CHECKLISTA / RED FLAGS</h2>
<div class="card checklist-card">
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Reflected Origin:</strong> Zmień nagłówek <code>Origin</code> w Burp Suite na
<code>evil.com</code>. Jeśli serwer odpowie <code>Allowed: evil.com</code> -> Zgłoś to!</div>
</div>
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Credentials: true:</strong> Jeśli serwer pozwala na `Credentials: true` przy luźnym
Origin, można ukraść dane zalogowanego użytkownika.</div>
</div>
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Regex na domenach:</strong> Programiści często używają słabych wyrażeń regularnych. Np.
pozwalają na `bank.com`, ale przez pomyłkę wpuszczają też `bank.com.evil.com`.</div>
</div>
</div>
</section>
<!-- QUIZ -->
<section id="quiz-section">
<h2>🎓 WERYFIKACJA WIEDZY</h2>
<div id="quiz-container"></div>
</section>
<footer>
<p style="text-align: center; margin-top: 50px; color: #555;">© 2026 Hack & Learn: Web Edition | Moduł
05</p>
</footer>
</div>
<!-- DANE DO QUIZU -->
<script>
const quizData = [
{
question: "Co składa się na definicję 'Origin' (Pochodzenia)?",
options: [
"Tylko domena (np. google.com).",
"Domena i adres IP.",
"Protokół, Domena i Port.",
"Kraj pochodzenia serwera."
],
correct: 2,
explanation: "Aby dwa adresy były 'Same Origin', muszą mieć ten sam protokół (http/https), tę samą domenę i ten sam port."
},
{
question: "Co domyślnie blokuje SOP (Same-Origin Policy)?",
options: [
"Wysyłanie żądań do innego serwera.",
"Odczytywanie odpowiedzi z innego serwera przez skrypty JS.",
"Ładowanie obrazków z innego serwera.",
"Używanie CSS z innego serwera."
],
correct: 1,
explanation: "To kluczowe rozróżnienie: SOP zazwyczaj pozwala WYSYŁAĆ żądania (dlatego działa CSRF), ale zabrania ODCZYTYWAĆ odpowiedzi (dlatego chroni dane przed wyciekiem)."
},
{
type: "scenario",
question: "Testujesz API. W odpowiedzi widzisz nagłówek 'Access-Control-Allow-Origin: *'. Czy to zawsze jest błąd?",
options: [
"Tak, to zawsze krytyczna podatność.",
"Nie. Jeśli API udostępnia dane publiczne (np. prognozę pogody) i nie wymaga logowania, to jest to poprawne.",
"Tak, przeglądarki tego nie obsługują.",
"Zależy od wersji Apache."
],
correct: 1,
explanation: "Gwiazdka (*) jest bezpieczna TYLKO dla danych publicznych. Jeśli endpoint zwraca dane prywatne, musi wymagać uwierzytelnienia, a wtedy gwiazdka jest zabroniona."
},
{
type: "scenario",
question: "Wysyłasz żądanie z nagłówkiem 'Origin: https://hacker.com'. Serwer odpowiada: 'Access-Control-Allow-Origin: https://hacker.com' oraz 'Access-Control-Allow-Credentials: true'. Co to oznacza?",
options: [
"Serwer jest dobrze zabezpieczony.",
"To podatność 'CORS Misconfiguration'. Możesz stworzyć stronę, która ukradnie dane zalogowanego użytkownika.",
"To błąd 500.",
"To atak SQL Injection."
],
correct: 1,
explanation: "To klasyczny przykład 'Reflected Origin'. Serwer ślepo ufa temu, co wyślesz w nagłówku Origin i pozwala Twojej domenie na dostęp do ciasteczek (Credentials)."
},
{
question: "Do czego służy żądanie 'Preflight' (metoda OPTIONS) w CORS?",
options: [
"Do sprawdzenia, czy serwer działa.",
"Przeglądarka wysyła je automatycznie przed właściwym żądaniem (np. PUT/DELETE lub z customowymi nagłówkami), aby zapytać serwer o zgodę.",
"Służy do kasowania cache.",
"To wirus."
],
correct: 1,
explanation: "Złożone żądania (np. JSON z Content-Type application/json) wymagają zgody serwera PRZED wysłaniem właściwych danych. Przeglądarka robi to sama."
},
{
question: "Czy 'http://example.com' i 'https://example.com' to ten sam Origin?",
options: [
"Tak, domena jest ta sama.",
"Nie, różnią się protokołem.",
"Tak, jeśli port jest ten sam.",
"Zależy od przeglądarki."
],
correct: 1,
explanation: "Protokół jest częścią definicji Origin. HTTP i HTTPS są traktowane jako dwa różne światy."
},
{
question: "Co oznacza nagłówek 'Access-Control-Allow-Credentials: true'?",
options: [
"Zezwala na dostęp do kamery.",
"Pozwala na wysyłanie hasła w URL.",
"Pozwala przeglądarce dołączyć ciasteczka (sesję) i nagłówki autoryzacyjne do żądania Cross-Origin.",
"Wymusza zmianę hasła."
],
correct: 2,
explanation: "Bez tego nagłówka, nawet jeśli serwer pozwoli na dostęp domenowy, przeglądarka nie wyśle ciasteczek sesyjnych, więc żądanie będzie anonimowe."
},
{
type: "scenario",
question: "Programista pozwolił na dostęp CORS dla domeny `bank.com`. Atakujący zarejestrował domenę `bank.com.evil.com`. Jeśli serwer używa słabego regexa, czy atak się uda?",
options: [
"Nie, SOP to zablokuje.",
"Tak, jeśli regex sprawdza tylko czy ciąg zawiera 'bank.com' lub kończy się na nim w niewłaściwy sposób.",
"Nie, DNS to zablokuje.",
"Tylko w Internet Explorerze."
],
correct: 1,
explanation: "Błędy parsowania Origin są częste. Regex typu `Origin.endsWith('bank.com')` przepuści `evilbank.com` lub `bank.com.hacker.site`."
},
{
question: "Jaka jest relacja między SOP a XSS?",
options: [
"SOP chroni przed XSS.",
"XSS pozwala obejść SOP. Skrypt wstrzyknięty przez XSS wykonuje się w kontekście domeny ofiary ('Same Origin'), więc ma dostęp do wszystkiego.",
"Nie mają ze sobą nic wspólnego.",
"SOP blokuje XSS."
],
correct: 1,
explanation: "To jest sedno sprawy! XSS jest tak groźny, bo 'oszukuje' przeglądarkę. Skrypt hakera działa JAKO strona banku, więc SOP go nie blokuje."
},
{
question: "Kiedy przeglądarka blokuje dostęp do odpowiedzi przy błędzie CORS?",
options: [
"Żądanie w ogóle nie wychodzi z przeglądarki.",
"Żądanie jest wysyłane, serwer je przetwarza i odpowiada, ale przeglądarka UKRYWA treść odpowiedzi przed skryptem JS.",
"Serwer odrzuca połączenie.",
"Komputer się wyłącza."
],
correct: 1,
explanation: "Ważne dla pentesterów: Błąd CORS w konsoli nie oznacza, że request nie dotarł. Często akcja na serwerze się wykonała (np. przelew), ale JS nie zobaczył potwierdzenia."
}
];
</script>
<script src="quiz.js"></script>
</body>
</html>