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…
📚 Teknik Terimler Sözlüğü
Bu makalede geçecek teknik terimleri önce açıklayalım:
🔧 Temel Terimler
- Worker: Web uygulamasının çalıştığı sunucu/süreç. Örneğin bir PHP, Node.js veya Python uygulaması.
- RP (Reverse Proxy): İstemcilerden gelen istekleri alıp uygun worker’lara yönlendiren ara sunucu. Yük dengeleme (load balancing) yapar.
- Yük Dengeleme (Load Balancing): Gelen istekleri birden fazla worker arasında dağıtarak sistemin performansını ve güvenilirliğini artıran sistem.
- Sticky Session: Kullanıcının oturum bilgilerinin tutarlılığını sağlamak için, aynı kullanıcının isteklerini her zaman aynı worker’a yönlendiren yapı.
- State: Bir uygulamanın veya sistemin belirli bir andaki durumu. Örneğin kullanıcının giriş yapmış olması bir state’dir.
- Stateless: Durum bilgisi tutmayan sistemler. Her istek bağımsız olarak işlenir.
- Authentication: Kimlik doğrulama. Kullanıcının gerçekten o kişi olduğunu kanıtlama süreci.
- Authorization: Yetkilendirme. Kullanıcının belirli kaynaklara erişim izninin olup olmadığını kontrol etme.
- Cookie: Web sitesinin tarayıcınızda sakladığı küçük metin dosyaları. Kullanıcı tercihleri, oturum bilgileri gibi verileri tutar.
- Session: Kullanıcının web sitesiyle olan etkileşiminin başlangıcından bitişine kadar olan süreç. Oturum bilgileri genellikle sunucu tarafında saklanır.
🔐 Güvenlik Terimleri
- CSRF (Cross-Site Request Forgery): Kullanıcının bilgisi olmadan, onun adına istek göndermeyi amaçlayan saldırı türü.
- SameSite: Cookie’lerin hangi sitelerden gönderilebileceğini kontrol eden güvenlik özelliği.
- SSL/TLS: Web trafiğini şifreleyen güvenlik protokolleri.
- JWT (JSON Web Token): İki taraf arasında güvenli bilgi aktarımı için kullanılan şifrelenmiş token formatı.
- HMAC: Mesaj doğrulama için kullanılan kriptografik bir yöntem.
🌐 Web Terimleri
- HTTP (Hypertext Transfer Protocol): Web’de veri alışverişi için kullanılan temel protokol.
- HTTPS (HTTP Secure): HTTP’nin güvenli versiyonu, SSL/TLS ile şifrelenmiş.
- REST API: Web servisleri için kullanılan standart bir mimari yaklaşım.
- Request/Response: İstemci-sunucu iletişimindeki temel kavramlar. İstek ve yanıt.
- Header/Body: HTTP mesajlarının iki ana bölümü. Header meta verileri, Body ise asıl içeriği taşır.
💾 Veri Depolama
- Redis: Yüksek performanslı, bellek içi veri depolama sistemi.
- Database: Kalıcı veri depolama için kullanılan sistem (örn. MySQL, PostgreSQL).
- In-Memory: Verilerin RAM’de tutulduğu, hızlı erişim sağlayan depolama yöntemi.
- Disk Storage: Verilerin kalıcı olarık saklandığı depolama yöntemi.
🧭 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 (ingilizce) 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.
🔒 HTTP ve HTTPS Arasındaki Fark
HTTP (Hypertext Transfer Protocol) ve HTTPS (Hypertext Transfer Protocol Secure) arasındaki temel fark, veri güvenliğidir. Bunu günlük hayattan bir örnekle açıklayalım:
📬 HTTP: Açık Posta Kutusu
- HTTP, açık bir posta kutusu gibidir
- Herkes içeriği görebilir ve değiştirebilir
- Veriler şifrelenmeden gönderilir
- Örnek:
http://example.com
🔐 HTTPS: Kilitli Posta Kutusu
- HTTPS, kilitli bir posta kutusu gibidir
- Sadece gönderen ve alıcı içeriği görebilir
- Veriler şifrelenerek gönderilir
- Örnek:
https://example.com
🔄 Nasıl Çalışır?
- HTTP’de:
- Veriler düz metin olarak gönderilir
- Ağ üzerinde yakalanabilir
- Değiştirilebilir veya okunabilir
- HTTPS’de:
- SSL/TLS protokolü kullanılır
- Veriler şifrelenir
- Sertifika ile kimlik doğrulaması yapılır
- Veri bütünlüğü korunur
⚠️ Neden HTTPS Önemli?
- Kredi kartı bilgileri
- Şifreler
- Kişisel veriler
- Oturum bilgileri gibi hassas verilerin güvenliğini sağlar.
🔍 Nasıl Anlarsınız?
- Adres çubuğunda kilit 🔒 işareti varsa HTTPS kullanılıyordur
- URL
https://
ile başlıyorsa güvenli bağlantı vardır - Modern tarayıcılar HTTP sitelerini “güvenli değil” olarak işaretler
💡 İlginç Bilgi
HTTPS, HTTP’nin güvenli versiyonudur ve 1994 yılında Netscape tarafından geliştirilmiştir. Günümüzde neredeyse tüm web siteleri HTTPS kullanmaktadır.
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. Bunlara da göz atalım.
🔍 HTTP İsteklerinde Header ve Body Yapısının Önemi
HTTP isteklerini bir mektuba benzetebiliriz. Bir mektup nasıl zarf ve içerikten oluşuyorsa, HTTP istekleri de header (zarf) ve body (içerik) olmak üzere iki ana bölümden oluşur:
📝 Header (Zarf) Kısmı
- Mektubun zarfı gibi, isteğin “kimlik bilgilerini” içerir
- Kimden geldiği (User-Agent)
- Nereye gittiği (Host)
- Ne tür bir istek olduğu (GET, POST vb.)
- Kimlik doğrulama bilgileri (Authorization)
- Çerezler (Cookies) gibi önemli bilgileri barındırır.
📄 Body (İçerik) Kısmı
- Mektubun içeriği gibi, asıl gönderilmek istenen veriyi taşır
- Form verileri
- Dosya içerikleri
- JSON verileri gibi kullanıcının göndermek istediği asıl bilgileri içerir.
Örneğin, bir alışveriş sitesinde ürün satın alırken:
- Header kısmında: Kim olduğunuz, hangi tarayıcıyı kullandığınız, oturum bilgileriniz
- Body kısmında: Seçtiğiniz ürün, adres bilgileriniz, ödeme detaylarınız yer alır.
🔐 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 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
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. Sunucu tarafında config dosyasında bulunan gizli anahtar
SYMC_ENC_KEY = "super_secret_key_123..."
# 2. Kullanıcı giriş isteği
POST /login HTTP/1.1
Host: fr0stb1rd.gitlab.io
Content-Type: application/x-www-form-urlencoded
username=mdisec&password=twitch
# 3. Sunucu yanıtı
HTTP/1.1 302 Found
Location: fr0stb1rd.gitlab.io/dashboard
Set-Cookie: SESSION={
"iv": "random_initialization_vector",
"session_data": {
"email": "mdisec@example.com",
"user_id": "12345"
},
"checksum": "hash_of_session_data",
"signature": "hmac_signature"
} | Base64Encode
- 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. Şu kaynağı bu noktada açıp okumanız faydalı olabilir (ingilizce).
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=eyJpdiI6Im5BaHZvZXFoS2d4ZEQxSHlEOTVybVE9PSIsInZhbHVI...
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?
Aşağıdaki senaryoda, kullanıcının tarayıcısında iki sekme açık olduğunu düşünelim:
1
2
3
4
5
6
7
📑 Sekme 1: Güvenli Site
URL: http://18.132.45.78
Durum: Kullanıcı giriş yapmış ve oturum açık
📑 Sekme 2: Saldırganın Sitesi
URL: http://www.hacker.com
Durum: Kullanıcı bu siteye yeni girmiş
Saldırganın sitesinde (hacker.com
) şu HTML kodu bulunuyor:
1
2
3
4
5
6
7
8
9
10
<html>
<body>
<!-- Gizli bir resim etiketi ile CSRF saldırısı -->
<img src="http://18.132.45.78/address/delete/17" style="display:none">
<!-- Kullanıcıyı meşgul etmek için sahte içerik -->
<h1>🎉 Tebrikler! Bu siteye giren 1.000.000'inci kişi oldunuz!</h1>
<p>Ödülünüzü almak için lütfen bekleyin...</p>
</body>
</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
❓ 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 saldırılarına karşı koruma sağlayan 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 sunucuya 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
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.