API'lerde CORS ve Güvenlik Başlıkları
Modern API güvenliği, yalnızca kimlik doğrulama ve yetkilendirme ile sınırlı değildir. Tarayıcı tabanlı istemcilerin API'nize güvenli erişebilmesi için CORS ve bir dizi güvenlik başlığı (security headers) doğru yapılandırılmalıdır. Yanlış CORS yapılandırması API'yi CSRF saldırılarına açık hale getirirken; eksik güvenlik başlıkları XSS ve clickjacking gibi saldırılara zemin hazırlar.
1. CORS Nedir ve Neden Gerekli?
Same-Origin Policy, tarayıcıların güvenlik modelinin temelidir: bir sayfa, yalnızca aynı origin'e (protokol + alan adı + port) sahip kaynaklara erişebilir. CORS (Cross-Origin Resource Sharing), sunucuların belirli origin'lere bu kısıtlamayı gevşetmesini sağlayan bir mekanizmadır .
Kritik Uyarı: CORS bir güvenlik özelliği değildir; aksine güvenliği gevşetir. Microsoft'un ifadesiyle: "CORS, güvenliği gevşetir. CORS'a izin veren bir API daha güvenli hale gelmez."
Basit vs. Preflight İstekler:
-
Basit istek:
GET,HEAD,POST(sadecetext/plain,form-urlencoded,multipart/form-data) — doğrudan gönderilir. -
Preflight:
PUT,DELETE,application/jsonveya özel başlıklar içeren istekler — önce birOPTIONSisteği gönderilir .
2. ASP.NET Core'da CORS Yapılandırması
csharp
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowWebApp", policy =>
{
policy.WithOrigins("https://app.example.com")
.WithMethods("GET", "POST", "PUT", "DELETE")
.WithHeaders("Content-Type", "Authorization")
.AllowCredentials();
});
});
app.UseRouting();
app.UseCors("AllowWebApp"); // UseAuthorization'dan önce
app.UseAuthorization();
Kritik Middleware Sırası: UseCors, UseRouting sonrasında ve UseAuthorization öncesinde çağrılmalıdır. UseResponseCaching kullanılıyorsa, UseCors ondan önce gelmelidir .
3. CORS Güvenlik Tuzakları
❌ Tehlikeli Yapılandırma:
csharp
policy.AllowAnyOrigin() // Tüm origin'lere izin
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // ÇALIŞMAZ ve GÜVENSİZ!
Neden? Access-Control-Allow-Origin: * ile Access-Control-Allow-Credentials: true birlikte kullanılamaz. ASP.NET Core, bu kombinasyonu reddeder . Ayrıca *, kimlik bilgileri (cookie, Authorization) taşıyan isteklerde tarayıcı tarafından kabul edilmez .
✅ Güvenli Yapılandırma:
csharp
policy.WithOrigins("https://app.example.com") // Belirli origin
.AllowCredentials();
Dinamik Origin Doğrulama: Birden fazla alt alan adı varsa:
csharp
policy.SetIsOriginAllowed(origin =>
{
var host = new Uri(origin).Host;
return host.EndsWith(".example.com");
});
Önemli: CORS, yalnızca tarayıcılar tarafından uygulanır. curl, Postman veya sunucu taraflı istemciler CORS'u görmezden gelir. Bu nedenle CORS'u bir güvenlik katmanı olarak değil, bir tarayıcı politikası olarak düşünün .
4. Güvenlik Başlıkları (Security Headers)
CORS'un yanı sıra, API yanıtlarına eklenmesi gereken güvenlik başlıkları vardır:
| Başlık | Amaç | Örnek Değer |
|---|---|---|
Strict-Transport-Security (HSTS) |
Yalnızca HTTPS kullanımını zorlar | max-age=31536000; includeSubDomains |
Content-Security-Policy (CSP) |
Hangi kaynakların yüklenebileceğini kontrol eder (XSS koruması) | default-src 'self' |
X-Content-Type-Options |
MIME sniffing'i engeller | nosniff |
X-Frame-Options |
iframe içinde gösterimi engeller (clickjacking) | DENY |
Referrer-Policy |
Referrer bilgisini kısıtlar | strict-origin-when-cross-origin |
Permissions-Policy |
Kamera/mikrofon/konum erişimini kısıtlar | camera=(), microphone=() |
Bu başlıklar, OWASP Secure Headers Project tarafından önerilmektedir .
5. .NET'te Güvenlik Başlıklarını Ekleme
csharp
app.Use(async (context, next) =>
{
context.Response.Headers.Append("X-Content-Type-Options", "nosniff");
context.Response.Headers.Append("X-Frame-Options", "DENY");
context.Response.Headers.Append("Referrer-Policy", "strict-origin-when-cross-origin");
context.Response.Headers.Append("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
await next();
});
HSTS Yapılandırması:
csharp
builder.Services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(365);
});
if (!app.Environment.IsDevelopment())
app.UseHsts();
app.UseHttpsRedirection();
6. En İyi Pratikler
| Pratik | Açıklama |
|---|---|
| CORS'u daraltın | Sadece ihtiyaç duyulan origin'lere izin verin; AllowAnyOrigin() kullanmayın. |
Credentials ile * kullanmayın |
AllowCredentials() varken origin belirtin. |
| Tüm güvenlik başlıklarını ekleyin | Middleware ile merkezi yönetin. |
| CSP'yi kademeli uygulayın | Önce Report-Only ile test edin. |
| Başlıkları test edin | securityheaders.com gibi araçlarla doğrulayın . |
| CORS'u güvenlik sanmayın | Sunucu taraflı yetkilendirme her zaman ayrıca yapılmalıdır. |
Sonuç
CORS ve güvenlik başlıkları, modern API güvenliğinin tamamlayıcı iki bileşenidir. CORS, tarayıcı tabanlı istemcilerin API'nize güvenli erişmesini sağlarken; güvenlik başlıkları XSS, clickjacking ve MIME sniffing saldırılarına karşı koruma sağlar. ASP.NET Core'da AddCors() ve özel middleware ile bu yapılandırmaları merkezi ve tutarlı biçimde yönetebilirsiniz. Unutmayın: CORS bir güvenlik mekanizması değil, bir tarayıcı politikasıdır; gerçek güvenlik, sunucu taraflı kimlik doğrulama, yetkilendirme ve input validasyonu ile sağlanır.