Web Security 101 0x03 | Session'ı ve CSRF Zafiyetini Anlamak & SameSite Cookie Önlemi MDISEC
Session ve CSRF zafiyetleri nedir ve nasıl çalışır? Bu makalede Session yönetimi, CSRF açıklarını ve SameSite Cookie önlemini öğreneceksiniz.
📝 Önsöz & Yasal Uyarı
Yasal Uyarı: Bu yazı, yalnızca eğitim amaçlıdır. Burada öğrenilen bilgilerin kötüye kullanılması yasalara aykırıdır. Lütfen bu bilgileri yalnızca güvenlik eğitimi ve savunma amaçlı kullanın. Kötü niyetli kullanımlar yasal sonuçlar doğurabilir.
Bu yazı, güvenliğimizi sağlamak için yazılmıştır. Mehmet İnce’nin (mdisec)
Web Security 101 0x03 | Session'ı ve CSRF Zafiyetini Anlamak & SameSite Cookie Önlemi
adlı eğitiminden (twitch | youtube) öğrenilen bilgilerin derlenmiş toparlanmış blog haline getirilmiş halidir.Daha iyi bir deneyim için videoyu izleyerek ve kendi notlarınızı çıkararak (özellikle a4 kağıdı ve mavi tükenmez kalem kullanarak) öğrenmeniz şiddetle önerilir (ben tarafından).
Aklınıza takılan yerler olunca ya da tekrar etmek istediğinizde bu sayfayı yer imlerinize ekleyip oradan bir tıkla bakmanız tavsiye olunur (yine ben tarafından). Aşağıda video var, iyi Seyirler, iyi okumalar, iyi öğrenmeler…
🧭 Bölüm 0: HTTP Nedir?
HTTP, basit ihtiyaçların giderilmesi için tasarlanmış bir protokoldür. Her zaman bir request karşılığında bir response alınır. Yani her şey request-response arasında yaşanır.
Farklı OSI katmanlarındaki protokoller birbiriyle kıyaslanmasa da şöyle bir kıyaslama yapabiliriz.
HTTP dediğimizde aklımıza TCP 3-Way Handshake gelebilir.
📊 TCP 3-Way Handshake (ASCII Diagram)
1
2
3
4
5
6
7
8
9
Client Server
| |
| ----------- SYN (seq=x) -----------------> |
| |
| <------ SYN-ACK (seq=y, ack=x+1) --------- |
| |
| ----------- ACK (seq=x+1, ack=y+1) ------> |
| |
| Bağlantı Kuruldu |
Burada TCP 3-Way Handshake yapısını görebilirsiniz. Peki böyle bir yapıya neden ihtiyaç var?
Öncelikle bu yapının en büyük katkısı işlemler tamamlandığı zaman karşımızda konuşmak istediğimiz kişiyi doğrulamış olmamızdır.
🔄 TCP 3-Way Handshake Nedir?
Bu yapıda bir canlandırma yapacak olursak şu şekilde bir konuşma geçmektedir:
Client: “Merhaba, seninle konuşmak istiyorum.”
Server: “Merhaba benimle konuşmak istediğini duydum ve seninle konuşmaya müsaitim.”
Client: “Merhaba, ben seninle konuşmak istediğimi söylemiştim, sen de bunu duymuşsun ve benimle konuşmak için müsait olduğunu duydum. Hadi konuşalım.”
Daha detaylı incelemek isterseniz:
1️⃣ SYN (Sen) — İlk adım:
- Client (istemci), bağlantı kurmak istediğini belirtir.
- SYN bayrağı set edilir.
- Bir başlangıç sıra numarası (
seq=x
) gönderir.
2️⃣ SYN-ACK (Sen-Acknowledge) — İkinci adım:
- Server (sunucu), isteği alır ve kabul ettiğini belirtir.
- Hem SYN, hem ACK bayrakları set edilir.
- Kendi sıra numarasını (
seq=y
) gönderir. - İstemciden aldığı sıra numarasını onaylar (
ack=x+1
).
3️⃣ ACK (Acknowledge) — Üçüncü adım:
- Client, sunucunun gönderdiği sıra numarasını onaylar (
ack=y+1
). - ACK bayrağı set edilir.
- Artık bağlantı kuruldu ve veri alışverişi başlayabilir.
Daha daha detaylısını arıyorsanız bu yazıya bakabilirsiniz.
Bu şekilde 3’lü paket gönderilmektedir. En büyük katkısı karşı taraftaki kişiyi doğrulamasıdır. (İnsan diyerek benzetme yapıyoruz ama bunlar makina sonuçta.)
Bunu HTTP ile kıyasladığımızda HTTP’deki en büyük eksikliklerden biri protokolde authentication olmamasıdır. Bir diğer konu da state’lerdir.
Farklı katmanlardaki protokolleri kıyaslamak her ne kadar doğru olmasa da bir özellik için örnek vermekteyiz.
Burada görmüş olduğunuz request bir HTTP Post request’idir.
1
2
3
4
5
POST /index.html HTTP/1.1
Host: fr0stb1rd.gitlab.io
User-Agent:
{'name':'fr0stb1rd'}
Bu post request’i Header ve Body olmak üzere 2 kısımdan oluşmaktadır.
🔍 HTTP İsteklerinde Header ve Body Yapısının Önemi
HTTP isteklerini insan vücuduna benzetebiliriz: Tıpkı bir insanın baş ve vücut kısımları olduğu gibi, HTTP istekleri de header (baş) ve body (vücut) olmak üzere iki ana bölümden oluşur. Header kısmında, tıpkı beynimizin önemli bilgileri barındırması gibi, isteğin kritik bilgileri (örneğin kimlik doğrulama bilgileri, cookie’ler, istek türü gibi) yer alır. Body kısmı ise, vücudumuzun diğer kısımları gibi, isteğin asıl içeriğini taşır. Bu nedenle, örneğin cookie gibi önemli kimlik bilgileri her zaman header kısmında gönderilir.
Genellikle 4 terim duyarız; HTTP Request’inin Body ve Header’ı, Bu request’e karşılık olarak gelen Response’un Body ve Header’ı.
İletişim Türü | Header | Body |
---|---|---|
HTTP Request | Request Header | Request Body |
HTTP Response | Response Header | Response Body |
🔒 HTTP ve HTTPS Arasındaki Fark
HTTPS’deki tek fark gelip giden verilerin şifrelenmesidir. HTTP mekanizması içerisinde bir authentication desteği yoktur, peki günümüzde authentication mekanizması nasıl ilerlemektedir?
🔐 Günümüzde Authentication Mekanizması
Bu kısımda internet tarayıcıları ile HTTP protokolünün kendi arasında anlaştığı bir yapıyı inceleyelim.
HTTP’nin header’ında özel bir alan bulunur: Cookie alanı. Bu cookie’ler sunucu tarafında oluşturulur ve browser’ın yerel veritabanında saklanır.
Örnek bir login isteği:
1
2
3
4
POST /login HTTP/1.1
Host: fr0stb1rd.gitlab.io
username=mdisec&password=twitch
Sunucudan gelen yanıt:
1
2
3
HTTP 302 OK
Location: fr0stb1rd.gitlab.io/dashboard
Set-Cookie: SESSION=fr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rd
HTTP’de authentication mekanizması olmadığı için şöyle bir süreç izlenir:
- Browser, response’un header’ında Set-Cookie değerini görür
- Bu bilgiyi yerel veritabanına kaydeder
- Sonraki isteklerde Cookie alanını otomatik olarak ekler
Bu sayede her istekte kullanıcı adı ve parola göndermenize gerek kalmaz. HTTP protokolü state tutmadığı için bu bilgileri hatırlamaz. Her request-response döngüsü bağımsızdır.
Ancak uygulama katmanının sizi tanıması gerekir. Çünkü giriş yaptıktan sonra kim olduğunuzu bilmesi gerekir. Bu yüzden browser’larda böyle bir düzen bulunur.
Bu yapıda önemli bir soru ortaya çıkar:
1
2
3
GET /dashboard HTTP/1.1
Host:mdisec
Cookie: fr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rdfr0stb1rd {keyword: HTTP Security Headers}
Browser’ın cookie’leri neye göre eklediğini inceleyelim:
1
http://www.fr0stb1rd.gitlab.io:80/
Browser şu üç bilgiye bakar:
- Protocol (http/https)
- Domain (www.fr0stb1rd.gitlab.io)
- Port (80)
Bu üç değer eşleştiğinde cookie’yi ekler. Bu yüzden HTTP’den HTTPS’e geçtiğinizde oturum kaybı yaşayabilirsiniz.
🎯 Sonuç
Biz kullanıcı adı ve parolamızı verdikten sonra uygulama sunucusu bunun karşılığında bize bir kimlik verir. Bu kimliği bir ID gibi düşünebiliriz. Burada bir takas söz konusudur.
Verdiğimiz bilgilere karşılık olarak yapılan kontroller sonucunda bir kimlik alırız. Bu kimliği artık kendi bünyemizde taşırız.
Browser her zaman aynı yere geldiğinde bu kimlik ile gelir. Uygulama bu kimliğe bakınca kendi ürettiği kimlik olduğunu görür. Eğer kimlik aktifse, geçişe izin verir. Peki Üretilen Cookie Sunucu Tarafında Nerede Saklanır?
💾 Bölüm 1: Web Mimarilerinde Oturum (Session) Yönetimi Stratejileri
Burada bir web uygulaması, bir kullanıcı ve diğer sistemler bulunmaktadır. Aşağıdaki diyagram, bir kullanıcının oturum bilgilerini (örneğin, “giriş yaptı” durumu) saklamak için kullanılabilecek dört farklı yaklaşımı ve bu yaklaşımların mimarideki yerini göstermektedir. Her yaklaşımın kendi avantajları ve dezavantajları vardır.
💿 Seçenek 1: Web Sunucusunun Kendisinde (Worker Memory/Disk)
Bu, en temel yaklaşımdır. Kullanıcının oturum bilgisi, isteği işleyen Worker‘ın (uygulama sunucusunun) kendi belleğinde veya yerel diskindeki bir dosyada tutulur.
- Nasıl Çalışır:
- Kullanıcı bir
Worker
‘a (W1) bağlanır ve giriş yapar. - W1, bu kullanıcının oturum bilgisini kendi belleğine kaydeder ve kullanıcıya bir oturum ID’si içeren bir cookie gönderir.
- Kullanıcı yeni bir istek yaptığında, yük dengeleyici (RP) isteği yine W1’e yönlendirmelidir (
sticky session
), aksi takdirde başka bir worker (W2) oturum bilgisini bulamaz.
- Kullanıcı bir
- Avantajları:
- Tek sunuculu basit uygulamalar için kurulumu en kolay yöntemdir.
- Dezavantajları:
- Diyagramdaki gibi çoklu sunucu ortamında çalışmaz, “sticky sessions” gerektirir ki bu da yük dengelemenin verimini düşürür.
Worker
yeniden başlarsa üzerindeki tüm oturum bilgileri kaybolur.- Diskte tutulduğu zaman bazı problemler ortaya çıkar. Kullanıcı her geldiğinde cookie değeri alınır ve diskteki karşılığına bakılır. Bu adımlar diskte I/O işlemlerine sebep olur. Sonuç olarak request ve response döngüsü yavaşlar. Sürekli bir yazma silme işlemi gerçekleşir.
- Bir diğer durum da şöyledir. Yukarıdaki görselde görebileceğiniz gibi web application’ın çalıştığı uygulama sayısı birden ikiye çıkabilir. Bu durumda ön tarafa gelen request’leri dağıtmak için bir reverse proxy konur. Bu durumda session’ları senkronize etmeniz gerekir. Bu nedenle diskte tutmak mantıklı bir yöntem değildir.
🗄️ Seçenek 2: Merkezi Veritabanında (Database)
Bu yaklaşımda oturum verileri, uygulamanın ana Veritabanındaki (2) (örn: PostgreSQL, MySQL) bir tabloda saklanır.
- Nasıl Çalışır:
- Redis ile aynı mantıkta çalışır.
Worker
, oturum verisini okumak veya yazmak için merkezi veritabanına bağlanır. - Bir cookie geldiğinde veritabanında sorgulama yapılır. Cookie’nin var olup olmadığı tespit edilir. Eğer doğru kişiyse, session’daki tüm bilgiler database’den alınır.
- Redis ile aynı mantıkta çalışır.
- Avantajları:
- Veriler kalıcıdır. Sunucular veya Redis çökse bile oturum bilgileri kaybolmaz.
- Genellikle mimaride zaten bir veritabanı olduğu için ek bir bileşen gerektirmez.
- Az önce bahsettiğimiz senkronizasyon problemi de ortadan kalkar. Çünkü diğer web uygulaması da database’den veri alabilir.
- Dezavantajları:
- Disk tabanlı olduğu için Redis’e göre oldukça yavaştır.
- Her istekte veritabanına ek sorgu yükü bindirir, bu da performansı etkileyebilir.
- Günümüzde en çok karşılaştığımız yapı bu şekilde database’de tutulmasıdır. Ancak bunun da olumsuz yanları vardır. Yük ve performans konusu devreye girer.
⚡ Seçenek 3: Merkezi Önbellek Sunucusunda (Redis)
Bu, modern uygulamalarda çok yaygın kullanılan bir yöntemdir. Oturum verileri, tüm Worker
‘ların erişebildiği merkezi ve çok hızlı bir bellek-içi (in-memory) veri deposunda saklanır.
- Nasıl Çalışır:
- Kullanıcı giriş yaptığında, herhangi bir
Worker
oturum verisini merkezi Redis (3) sunucusuna yazar. - Kullanıcıya bu veriye işaret eden bir oturum ID’si cookie olarak gönderilir.
- Sonraki isteklerde, isteği karşılayan
Worker
(W1 veya W2), cookie’deki ID ile Redis’e giderek oturum verisini çok hızlı bir şekilde okur.
- Kullanıcı giriş yaptığında, herhangi bir
- Avantajları:
- Çok hızlıdır, çünkü veriler disk yerine bellekte tutulur.
- Merkezi olduğu için yük dengelemeli mimarilerle mükemmel uyum sağlar.
- Redis, hiçbir diske dokunmayan bir servistir. Sadece işletim sistemi aracılığıyla hafızada key-value şeklinde veri tutar. Memory’de tutulduğu için çok hızlı çalışır.
- Dezavantajları:
- Mimaride yönetilmesi gereken ek bir bileşen (Redis) gerektirir.
- Redis sunucusu çökerse (ve kalıcılık ayarlanmadıysa) tüm oturumlar kaybolabilir.
- Herhangi bir veri kaybı olduğunda en kötü ihtimal user’ın 302 kodu almasıdır. Bu durumda kullanıcı yeniden login olarak cookie’sini kolayca yenileyebilir.
🍪 Seçenek 4: İstemcide (Client-Side Cookie)
Bu yöntemde oturum verisi sunucuda herhangi bir yerde saklanmaz. Bunun yerine, tüm oturum bilgisi şifrelenip imzalanarak doğrudan kullanıcının tarayıcısındaki Cookie içinde tutulur. JWT (JSON Web Tokens) bu yaklaşımın popüler bir uygulamasıdır.
- Nasıl Çalışır:
- Kullanıcı giriş yapar.
- Sunucu, kullanıcı bilgilerini içeren bir veri paketini (payload) oluşturur, bunu bir anahtarla imzalar/şifreler ve cookie olarak kullanıcıya gönderir.
- Kullanıcı sonraki her isteğinde bu cookie’yi sunucuya gönderir.
- Sunucu (herhangi bir
Worker
), cookie’deki imzayı doğrulayarak oturumun geçerli olduğunu anlar ve veriyi okur.
- Detaylı İşleyiş:
- Önce bir JSON objesi oluşturulur
- Bir IV değerine random bir değer atanır
- Kullanıcıdan gelen bilgiler JSON objesine eklenir
- Sonuç olarak bir Session JSON’u oluşur
- Daha sonra bir Checksum oluşturulur
- Symmetric Encryption için IV değeri kullanılır
- Session data’sının tamamı şifrelenir
- Şifreleme için sunucu tarafında config dosyasında bulunan SYMC ENC SUPER SECRET KEY kullanılır
- Verinin değişmediğinden emin olmak için HMAC ile bir Signature oluşturulur
- Bu değer Base64 ile encode edilir
- Son olarak bu değer user’a verilir
- Artık session’ı kullanıcı taşır
Örnek bir cookie yapısı:
1
2
3
4
5
6
7
8
9
SUNUCU TARAFINDA CONFıG DOSYASINDA BULUNAN SYMC ENC SUPER SECRET KEY ...!!!
username=mdisec&password=twitch
HTTP 302 OK
Location: fr0stb1rd.gitlab.io/dashboard
Set-Cookie: {
'IV':'RANDOM_DEGER',
'session_data':ENC(['email','user_id'])}|CHECKSUM --SIGNATURE --> BASEE64ENCODE
- Avantajları:
- Sunucu taraflı depolama maliyeti yoktur (
stateless
). - Yatay ölçeklendirme (load balancing) için mükemmeldir, çünkü isteğin hangi
Worker
‘a gittiğinin bir önemi kalmaz.
- Sunucu taraflı depolama maliyeti yoktur (
- Dezavantajları:
- Cookie boyutu (~4KB) ile sınırlıdır, çok fazla veri saklanamaz.
- Güvenlik tamamen anahtarın gizliliğine bağlıdır.
- Sunucu, bir oturumu süresi dolmadan anında sonlandıramaz (blacklist mekanizmaları gerekir).
Çerez (cookie), bir kullanıcının kimliğini belirlemek için sunucu tarafından kullanılan bir anahtar veya kimlik iken, oturum (session) bu kimliğe ait bilgilerin sunucu tarafında tutulduğu bir bilgi topluluğudur ve ikisi birbirine bağlı ancak farklı kavramlardır.
Burada okumanızı önereceğimiz bir ek kaynak da bırakalım: https://guides.rubyonrails.org/security.html
Peki tüm bu anlatılan konular ile CSRF nerede birleşmektedir?
🛡️ Bölüm 2: CSRF Hakkında
Örnek bir delete request’i:
1
2
3
4
5
6
7
8
9
10
11
GET /address/delete/17 HTTP/1.1
Host: 18.132.45.78
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic YWRtaW46ZWVzZWFzeW91bWVLYXN5Z293aWxseW91bWVNbw==
Connection: close
Referer: http://18.132.45.78/address
Cookie: XSRF-TOKEN=eyJpdiI6Im5BaHZvX...
Upgrade-Insecure-Requests: 1
GET /address/delete/17 HTTP/1.1 Sunucuya
17
ID’li adres kaydını silme isteği gönderilmektedir. Normalde bu işlem içinDELETE
metodu kullanılması beklenir; burada iseGET
yöntemiyle silme işlemi tetiklenmiş olabilir (bu, kötü tasarlanmış API’lerde sıkça görülür).Host Hedef sunucunun IP adresini belirtir:
18.132.45.78
User-Agent İsteğin hangi tarayıcı ve işletim sisteminden yapıldığını belirtir. Burada Firefox 56.0 ve Windows 10 (WOW64) kullanıldığı görülüyor.
Accept / Accept-Language / Accept-Encoding İstemcinin hangi içerik türlerini, dilleri ve sıkıştırma türlerini kabul edebileceğini belirtir.
Authorization HTTP Basic Authentication yöntemiyle kimlik doğrulama bilgileri iletilmektedir. Şifrelenmiş base64 string mevcuttur.
Connection: close İstek sonrasında bağlantının kapatılacağını belirtir.
Referer Bu isteğin hangi sayfadan yönlendirildiğini gösterir:
http://18.132.45.78/address
.Cookie: XSRF-TOKEN Cross-Site Request Forgery (CSRF) saldırılarına karşı koruma amacıyla kullanılan güvenlik token’ıdır. Bu token, oturum güvenliğini sağlamak için her istekte gönderilir.
Upgrade-Insecure-Requests: 1 Tarayıcının HTTP yerine mümkünse HTTPS kullanmayı tercih ettiğini belirtir.
Web uygulaması, gelen isteğin kullanıcı tarafından bilinçli olarak mı yoksa farkında olmadan mı gönderildiğini anlamak zorundadır.
⚠️ CSRF Saldırısı Nasıl Gerçekleşir?
İki sekme açık olduğunu düşünelim:
1
2
3
4
5
1. TAB
18.132.45.78
2. TAB
www.hacker.com
Hacker.com’da şöyle bir HTML kodu var:
1
2
3
4
<html>
<img src="http://18.132.45.78/address/delete/17"></img>
<h1> Bu siteye giren 1M'inci kişi oldunuz... </h1>
</html>
Saldırı şu şekilde gerçekleşir:
- Browser img tag’ini görünce otomatik olarak HTTP request’i gönderir
- Cookie’ler “domain”+”protocol”+”port” yapısına göre eklenir
- Browser, resmi yüklemek için GET request’i üretir
- Cookie’ler adresle eşleştiği için otomatik eklenir
- Kullanıcı bu request’in gönderildiğinin farkında değildir
- Web uygulaması cookie değerini doğrular ve işlemi gerçekleştirir
1
2
3
4
5
6
7
8
9
10
11
GET /address/delete/17 HTTP/1.1
Host: 18.132.45.78
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic YWRtaW46ZWVzZWFzeW91bWVLYXN5Z293aWxseW91bWVNbw==
Connection: close
Referer: http://18.132.45.78/address
Cookie: XSRF-TOKEN=eyJpdiI6Im5BaHZvZXFoS2d4ZEQxSHlEOTVybVE9PSIsInZhbHVI...
Upgrade-Insecure-Requests: 1
GET /address/delete/17 HTTP/1.1
17
ID’li bir adres kaydını silmek için (veya bu işlemi simüle etmek için) yapılan bir GET isteğidir. REST mimarisinde silme işlemleri için geneldeDELETE
metodu kullanılması beklenir. Bu kullanım güvenli kodlama açısından problem yaratabilir.Host Sunucunun IP adresini belirtir:
18.132.45.78
User-Agent İstemcinin hangi tarayıcı ve işletim sisteminden geldiğini belirtir.
Accept / Accept-Language / Accept-Encoding Sunucudan beklenen içerik türleri, diller ve sıkıştırma biçimlerini belirtir.
Authorization: Basic HTTP Basic Authentication yöntemi ile kimlik doğrulama yapılmıştır.
YWRtaW46...
ifadesi base64 formatında şifrelenmiş kullanıcı adı ve şifre içerir.Connection: close İletişim sonrasında TCP bağlantısının kapatılacağını bildirir.
Referer Bu isteğin hangi sayfa üzerinden yapıldığını gösterir.
Cookie: XSRF-TOKEN CSRF (Cross-Site Request Forgery) saldırılarına karşı koruma sağlayan güvenlik token’ıdır.
Upgrade-Insecure-Requests: 1 Tarayıcıdan HTTPS kullanım tercihini belirtir.
❓ CSRF Nedir?
CSRF (Cross Site Request Forgery), siteler arası istek sahteciliği anlamına gelir. Kullanıcının bilgisi olmadan, onun adına istek göndermeyi amaçlar.
🛡️ CSRF Nasıl Engellenir?
CSRF’i engellemek için iki şey gerekir:
- İsteğin kullanıcı tarafından bilinçli olarak mı gönderildiğini tespit etmek
- Hassas işlemlerde CSRF token kullanmak
CSRF token şöyle çalışır:
- Sunucu, kullanıcının sayfasına özel bir token ekler
- Bu token sadece o kullanıcının sayfasında bulunur
- Hacker bu token’a erişemez
- Token olmadan işlem gerçekleştirilemez
1
2
3
4
5
6
7
8
9
<div class="row">
<div class="col-sm-9">
asdasd
</div>
<div class="col-sm-3">
<a href="http://18.132.45.78/address/delete/17">Delete</a>
</div>
</div>
<hr>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /address HTTP/1.1
Host: 18.132.45.78
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 77
Origin: http://18.132.45.78
Authorization: Basic YWRtaW46ZWFzeWNvbWVlYXN5Z293aWxseW91bGV0bWVnbw==
Connection: close
Referer: http://18.132.45.78/address
Cookie: XSRF-TOKEN=... (uzun CSRF token değeri)
Upgrade-Insecure-Requests: 1
token=BapfPvHAe8riG3sk82FJGcgj1VtcxFkkOP4cUSGw&name=qweqwe&content=qweqwe
POST /address
: Yeni bir adres verisi sunucuya gönderilir.Content-Type
: Verilerapplication/x-www-form-urlencoded
formatında gönderilmiştir.Authorization
: Temel kimlik doğrulama için kullanılan Base64 şifreli kullanıcı adı ve parola içerir.token
: Formdan gelen CSRF güvenlik token’ıdır.name
vecontent
: Form üzerinden gönderilen kullanıcı giriş verileridir.Cookie
: Sunucu tarafından gönderilen CSRF token’ı içerir ve formun güvenliğini sağlar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<h3>Add New Address</h3>
<p>You can add new delivery location.</p>
<form method="POST" action="http://18.132.45.78/address">
<!-- CSRF koruması için gizli token -->
<input type="hidden" name="_token" value="BapfPvHAe8riG3sk82FJGcgj1VtcxFkkOP4cUSGw">
<!-- Adres adı -->
<label>Name</label>
<input type="text" name="name" class="form-control">
<!-- Adres içeriği -->
<label>Address</label>
<textarea name="content" rows="5" class="form-control"></textarea>
<!-- Gönder butonu -->
<button type="submit" class="btn btn-default">Submit</button>
</form>
method="POST"
: Formun verilerini sunucuya göndermek içinPOST
yöntemi kullanılır.action="http://18.132.45.78/address"
: Form verileri bu adrese gönderilir.<input type="hidden" name="_token" ...>
: CSRF (Cross-Site Request Forgery) saldırılarına karşı koruma sağlayan bir güvenlik önlemidir.<textarea>
ve<input>
: Kullanıcının girdiği adres bilgileri bu alanlarda toplanır.
Bu yapının güvenli bir şekilde çalışması için sunucuda CSRF token doğrulaması yapılmalıdır.
🔐 REST API’lerde CSRF Koruması Neden Gerekli Değil?
REST API’lerde CSRF token kullanılmasa bile zafiyet oluşmaz. Çünkü:
- Browser, request’i hacker.com’a gönderirken cookie’leri otomatik ekler
- Hacker, header’daki alanlara erişemez
- Authorization bilgisine sahip olamaz
1
2
3
4
5
6
7
8
9
10
11
POST /address/delete/ HTTP/1.1
Host: api.mdisec.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic YWRtaW46ZWFzeWNvbWVlYXN5Z293aWxseW91bGV0bWVnbw==
Connection: close
Origin: http://mdisec.com/
{'id':'17'}
🔒 Bölüm 3: SameSite Cookie
Modern browser’larda şöyle bir yapı bulunur:
1
Set-Cookie: sessionId=abc123; SameSite=Strict
SameSite özelliği üç farklı değer alabilir:
- Strict: Cookie’ler sadece aynı site içindeki isteklerde gönderilir
- Lax: Cookie’ler aynı site içindeki isteklerde ve bazı üst seviye navigasyonlarda gönderilir
- None: Cookie’ler tüm isteklerde gönderilir (güvenli değil)
🔄 SameSite Nasıl Çalışır?
Örnek bir senaryo:
- Kullanıcı
example.com
sitesinde oturum açmış durumda - Kullanıcı
malicious.com
sitesine gidiyor malicious.com
sitesiexample.com
‘a istek gönderiyor- SameSite=Strict ayarı varsa, cookie’ler gönderilmez
- SameSite=Lax ayarı varsa, sadece bazı durumlarda cookie’ler gönderilir
- SameSite=None ayarı varsa, cookie’ler her zaman gönderilir
⭐ SameSite Neden Önemli?
SameSite özelliği şu avantajları sağlar:
- CSRF saldırılarını engeller
- Kullanıcı oturumlarını korur
- Üçüncü parti sitelerden gelen istekleri kontrol eder
📋 SameSite Kullanım Önerileri
- Hassas işlemler için Strict kullanın
- Genel kullanım için Lax yeterlidir
- None değerini sadece gerekli durumlarda kullanın
- HTTPS ile birlikte kullanın
Burada anlatılanların daha detaylı düzenli anlatılmış hali şurada var. İngiliççeniz varsa ve göz gezdirmeyi unutursanız Mehmet İnce gecenin 3’ünde pcnize girip neden bakmadığınız hakkında sorular sorup sizi darlayabilir. Ben olsam okurdum. Hatta okumaya gidiyorum.
Başka bir yazıda görüşmek üzere, esen kalın.