Security Headers Nedir?
HTTP Security Headers, modern web tarayıcılarının web sitemizin güvenliğini sağlaması için sunucu yanıtlarında headerlara eklediğimiz key-value değerlerdir. Security Headers, saldırılara karşı 100% savunma garantisi vermezken, saldırı yapılacak alanları en aza indirme, daha fazla güvenlik katmanı ekleme ve modern tarayıcıların işleri güvende tutmasına yardımcı olur.
1) Strict-Transport-Security
HTTP Strict Transport Security diğer adıyla HSTS, internet tarayıcıların gelen her istekte HTTPS'e yönlendirerek, downgrade saldırılarını önlemeye yarar.
Response Header'ına aşağıdaki değerleri ekleyerek bu saldırıları önleyebilirsiniz.
Strict-Transport-Security: max-age=16070400;
2) X-XSS-Protection
Web sitesinizi XSS (Cross-Site-Scripting) saldırılarından korumaya yarar.
X-XSS-Protection: 1; mode=block
Örnek:
ayazduru.com/arama?anahtar=<script>alert('XSS TEST!');</script>

Web sitenizine yukarıdaki gibi script kodları üzerinden saldırı yapılmasıdır. Mesela, Phishing (Oltalama) Saldırısı ile e-posta mesajlarına web site domaininizi kullanarak virüslü dosyaların indirilmesi sağlanabilir veya başka zararlı sitelere javascript ile yönlendirme yapılabilir. Burada dikkat edilmesi gereken şey, Razor sayfalarında Query string ile gelen değerleri ekrana Html.Raw methodunu kullanarak yazmamaya dikkat etmemiz gerekiyor.
3) X-Frame-Options
X-Frame-Options (XFO) güvenlik başlığı, modern web tarayıcılarının ziyaretçilerinizi clickjacking ve diğer tehditlere karşı korumalarına yardımcı olur.
X-Frame-Options: SAMEORIGIN
4) X-Content-Type-Options
MIME Type Sniffing adı verilen analiz yapılarak upload edilen içerik tahmin edilir.
Örnek:
png uzantılı html içerikli bir dosya upload edilip, yüklenen dosya url ile çağrıldığında html'in render edilmesi bir zafiyeti ortaya çıkarabilir.
X-Content-Type-Options: nosniff
5) Referrer-Policy
Sitenizden başka bir siteye link verdiğinizi düşünelim. Tarayıcı Referrer headerına sizin domain bilgilerinizi girecektir. Gizlilik, güvenlik gibi nedenlerden dolayı bu kuralı değiştirebilirsiniz.
Referrer-Policy: no-referrer-when-downgrade
6) Feature-Policy
Bu header ile konum, mikrofon, kamera gibi tarayıcı özelliklerinin kullanımını, kısıtlanmasını belirleyebilirsiniz.
Feature-Policy: geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';
7) Content-Security-Policy
CSP, XSS, Clickjacking, Protocol Downgrading, Frame Injection vb bir çok zafiyete karşı tarayıcı tarafında ekstra güvenlik sunar.
Content-Security-Policy: default-src 'self'
SameSite Cookie Nedir?
Tarayıcınızdaki her cookie bir domain ile ilişkilidir. Cookie domaini, adres çubuğundaki domainden farklı ise Cross-Site Cookie, aynı ise Same-Site Cookie'dir. Same-Site Cookielerinizi başka sitelerin kullanmasını istiyorsanız sitenizde bazı ayarların yapılması gerekmektedir.
Same-Site=None:
Cookie'nizin üçüncü taraf isteklere eklenmesine izin verir. None özelliğini kullanmak için Secure flagınıda kullanmamız gerekecek ve Cross-Site cookie kullanacak sitelerin de artık HTTPS olmaları zorunludur.
Same-Site=Strict:
İsmindende anlaşılacağı gibi üçüncü taraflardan kaynaklanan hiç bir isteğe SameSite olan Cookie gönderilmeyecektir.
Same-Site=Lax:
Üçüncü taraf bir web siteden kaynaklanan GET isteklerine Lax olarak ayarlanmış Cookieler gönderilir.
SecurityHeaderMiddleware.cs
İlk olarak bir Middleware sınıfı oluşturuyoruz.
public class SecurityHeaderMiddleware
{
public static readonly string Xss = "X-Xss-Protection";
public static readonly string XssValue = "1; mode=block";
public static readonly string XContentTypeOptions = "X-Content-Type-Options";
public static readonly string XContentTypeOptionsValue = "nosniff";
public static readonly string XFrameOptions = "X-Frame-Options";
public static readonly string XFrameOptionsValue = "SAMEORIGIN";
public static readonly string ReferrerPolicy = "Referrer-Policy";
public static readonly string ReferrerPolicyValue = "no-referrer-when-downgrade";
public static readonly string ContentSecurityPolicy = "Content-Security-Policy";
public static readonly string ContentSecurityPolicyValue = "default-src 'self'";
public static readonly string FeaturePolicy = "Feature-Policy";
public static readonly string FeaturePolicyValue = "geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';";
public static IDictionary<string,string> HeaderSecurityItems { get; }
= new Dictionary<string,string>()
{
{Xss ,XssValue},
{XContentTypeOptions ,XContentTypeOptionsValue},
{XFrameOptions ,XFrameOptionsValue},
{ReferrerPolicy ,ReferrerPolicyValue}
{ContentSecurityPolicy ,ContentSecurityPolicyValue}
{FeaturePolicy ,FeaturePolicyValue}
};
private readonly RequestDelegate _next;
public SecurityHeaderMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var headers = context.Response.Headers;
foreach (var item in HeaderSecurityItems)
headers[item.Key] = item.Value;
await _next(context);
}
}
SecurityExtensions.cs
Daha sonra Startup.cs içerisinde kullanmak için bir static extension class oluşturuyoruz.
public static class SecurityExtensions
{
public static IApplicationBuilder UseSecurityHeader(this IApplicationBuilder app) => app.UseMiddleware<SecurityHeaderMiddleware>();
private static bool DisallowsSameSiteNone(string userAgent)
{
if (String.IsNullOrWhiteSpace(userAgent))
return false;
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
public static IServiceCollection AddSameSite(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.None;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSameSite();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts(); //Strict-Transport-Security
app.UseSecurityHeader(); //X-XSS-Protection, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Feature-Policy, Content-Security-Policy
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy(); //SameSite Cookie için kullanıyoruz. UseAuthentication() methodunun üstünde olmalıdır.
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Program.cs
Eğer ASP.Net Hosting modelimiz OutOfProcess ise;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.AddServerHeader = false;
});
});
}
Sunucu Response Server headerını silerek üçüncü kişileri kullandığımız teknolojiyi göstermiyoruz.
Bonus
1) securityheaders.com
Yukarıdaki link üzerinde kendi sitenizdeki headerların doğru çalışıp çalışmadığını kontrol edebilirsiniz.

2) https://github.com/NWebsec/NWebsec
ASP.Net Projelerinde Security Headersları kullanabileceğiz başka bir açık kaynak kütüphaneyi yukarıdaki linkten inceleyebilirsiniz.
app.UseHsts(options => options.MaxAge(days: 30));
app.UseXContentTypeOptions();
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXfo(options => options.SameOrigin());
app.UseReferrerPolicy(opts => opts.NoReferrerWhenDowngrade());
3) IIS Kulllanıyorsanız Web.config içerisine
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
<add name="X-Content-Type-Options" value="nosniff"/>
<add name="X-Xss-Protection" value="1; mode=block"/>
<add name="X-Frame-Options" value="SAMEORIGIN"/>
<add name="Content-Security-Policy" value="default-src 'self'"/>
<add name="Referrer-Policy" value="no-referrer-when-downgrade"/>
<add name="Feature-Policy" value="geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';"/>
<remove name="X-Powered-By" />
<remove name="X-AspNet-Version" />
<remove name="Server" />
</customHeaders>
</httpProtocol>
...
Kendinize iyi bakın, bir sonraki yazımda görüşmek dileğiyle :)