ASP.NET Core`da Güvenlik İçin 15 Kural - Kod Örnekleri
ASP.NET Core projelerinde güvenliği artırmak için kod örnekleri ile beraner 15 temel kural paylaşmak istedim.
1. Ara katman yazılımı kullanarak HTTPS'yi zorunlu kılın ve tüm HTTP trafiğini yönlendirin
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
options.HttpsPort = 443;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.MapGet("/", () => "HTTPS Zorunlu!");
app.Run();
2. Uç noktaları [Authorize] ve JWT kimlik doğrulamasıyla güvenli hale getirin
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet]
public IActionResult GetOrders()
{
return Ok(new[] { "Order1", "Order2" });
}
}
3. Veren, hedef kitle ve son kullanma tarihi dahil olmak üzere JWT belirteçlerini doğrulayın
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://auth.myapp.com",
ValidateAudience = true,
ValidAudience = "myapp-api",
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("super-secret-signing-key"))
};
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/secure", [Authorize]() => "JWT ile korunan endpoint");
app.Run();
4. Sabit kodlanmış değerler yerine rol/politika/claim/özel yetkilendirme kullanın
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Admin"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
[Authorize(Policy = "AdminOnly")]
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
[HttpDelete("user/{id}")]
public IActionResult DeleteUser(int id)
{
// Sadece Admin rolündeki kullanıcılar erişebilir
return Ok($"User {id} deleted");
}
}
app.Run();
5. Gelen tüm modellerde katı giriş doğrulaması uygulayın
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
public class RegisterDto
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(8)]
public string Password { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
[HttpPost("register")]
public IActionResult Register([FromBody] RegisterDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
// Kayıt işlemleri
return Ok("Kayıt başarılı");
}
}
6. Aşırı gönderimi ve veri enjeksiyonunu önlemek için DTO'ları kullanın
public class UserUpdateDto
{
public string DisplayName { get; set; }
}
public class User
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string InternalSecret { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpPut("{id}")]
public IActionResult UpdateUser(int id, [FromBody] UserUpdateDto dto)
{
// Örnek: veritabanından kullanıcıyı çektiğinizi varsayın
var user = new User { Id = id, DisplayName = "Old Name", InternalSecret = "DoNotTouch" };
// Sadece izin verilen alanlar güncellenir
user.DisplayName = dto.DisplayName;
return Ok(user);
}
}
7. Yalnızca güvenilir kaynaklara ve yöntemlere izin vermek için CORS'u yapılandırın
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("TrustedOrigins", policy =>
{
policy.WithOrigins("https://myfrontend.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
app.UseCors("TrustedOrigins");
app.MapGet("/api/data", () => "Sadece güvenilir origin erişebilir");
app.Run();
8. Üretimde ayrıntılı hata mesajlarını gizleyin
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/error");
app.UseHsts();
}
app.Map("/error", () =>
{
// Kullanıcıya detay vermeden genel bir hata mesajı
return Results.Problem("Beklenmeyen bir hata oluştu.");
});
app.MapGet("/throw", () =>
{
throw new Exception("Detaylı hata - sadece loglarda");
});
app.Run();
9. Kaba kuvvet saldırılarını ve kötüye kullanımı engellemek için hız sınırlaması uygulayın
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", limiterOptions =>
{
limiterOptions.PermitLimit = 10; // 10 istek
limiterOptions.Window = TimeSpan.FromSeconds(10); // 10 saniyede
limiterOptions.QueueLimit = 0;
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/api/limited", () => "Rate limited endpoint")
.RequireRateLimiting("fixed");
app.Run();
10. Belirteçleri, parolaları ve hassas kullanıcı verilerini kaydetmekten kaçının
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Identity;
public class AuthService
{
private readonly ILogger<AuthService> _logger;
private readonly IPasswordHasher<string> _passwordHasher;
public AuthService(ILogger<AuthService> logger, IPasswordHasher<string> passwordHasher)
{
_logger = logger;
_passwordHasher = passwordHasher;
}
public void Login(string username, string password)
{
// HATALI: _logger.LogInformation("User {User} logged in with password {Password}", username, password);
_logger.LogInformation("User {User} attempted login", username);
// Parola asla düz metin olarak saklanmaz
var hashed = _passwordHasher.HashPassword(username, password);
// hashed değeri veritabanında saklanabilir
}
}
11. HSTS ve X-Content-Type-Options gibi güvenlik başlıkları ekleyin
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// HSTS (sadece HTTPS üzerinde çalışırken)
if (!app.Environment.IsDevelopment())
{
app.UseHsts();
}
app.Use(async (context, next) =>
{
context.Response.Headers["X-Content-Type-Options"] = "nosniff";
context.Response.Headers["X-Frame-Options"] = "DENY";
context.Response.Headers["X-XSS-Protection"] = "1; mode=block";
await next();
});
app.MapGet("/", () => "Güvenlik başlıkları eklendi");
app.Run();
12. Bilinen güvenlik açıklarını düzeltmek için NuGet paketlerini düzenli olarak güncelleyin
REM Komut satırı örnekleri (Windows) dotnet list package --outdated dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 8.0.0 REM CI/CD pipeline içinde periyodik kontrol script'i yazılabilir
13. Çerezleri HttpOnly, Secure ve SameSite özellikleriyle ayarlayın
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/set-cookie", (HttpContext context) =>
{
context.Response.Cookies.Append("session-id", "abc123", new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Expires = DateTimeOffset.UtcNow.AddHours(1)
});
return "Güvenli çerez ayarlandı";
});
app.Run();
14. Kullanılmayan uç noktaları ve gereksiz denetleyicileri kaldırın
// En iyi yaklaşım: kullanılmayan controller ve endpoint'leri projeden tamamen silmek
// Geçici olarak gizlemek için:
using Microsoft.AspNetCore.Mvc;
[ApiExplorerSettings(IgnoreApi = true)]
[ApiController]
[Route("api/[controller]")]
public class LegacyController : ControllerBase
{
[HttpGet("old-endpoint")]
public IActionResult OldEndpoint()
{
return NotFound("Bu endpoint artık kullanılmıyor");
}
}
15. Kullanıcıları yönetirken güçlü parola politikaları kullanın
using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdentityCore<IdentityUser>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
})
.AddRoles<IdentityRole>()
.AddSignInManager()
.AddDefaultTokenProviders();
var app = builder.Build();
app.MapGet("/", () => "Güçlü parola politikaları yapılandırıldı");
app.Run();
#ASP-NET-Core-güvenlik #HTTPS-zorunlu-kılma #JWT-doğrulama #API-güvenliği #Rol-tabanlı-yetkilendirme #CORS-güvenli-yapılandırma #Rate-limiting #Güvenli-hata-yönetimi #Security-headers #Cookie-güvenliği #Parola-politikaları