Skip to content

Segurança de Aplicações .NET

🔐 OAuth 2.0 e OpenID Connect

OAuth 2.0 Flows

Authorization Code Flow

csharp
public class OAuth2Client
{
    private readonly HttpClient _httpClient;
    private readonly string _clientId;
    private readonly string _clientSecret;
    
    public async Task<TokenResponse> GetTokenAsync(string code)
    {
        var tokenRequest = new TokenRequest
        {
            GrantType = "authorization_code",
            Code = code,
            RedirectUri = "https://app.com/callback",
            ClientId = _clientId,
            ClientSecret = _clientSecret
        };
        
        return await _httpClient.PostAsJsonAsync("/token", tokenRequest);
    }
}

Client Credentials Flow

csharp
public async Task<TokenResponse> GetClientCredentialsTokenAsync()
{
    var tokenRequest = new TokenRequest
    {
        GrantType = "client_credentials",
        ClientId = _clientId,
        ClientSecret = _clientSecret,
        Scope = "api.read api.write"
    };
    
    return await _httpClient.PostAsJsonAsync("/token", tokenRequest);
}

OpenID Connect

JWT Token Validation

csharp
public class JwtTokenValidator
{
    private readonly SecurityKey _signingKey;
    private readonly string _issuer;
    private readonly string _audience;
    
    public ClaimsPrincipal ValidateToken(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var validationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = _signingKey,
            ValidateIssuer = true,
            ValidIssuer = _issuer,
            ValidateAudience = true,
            ValidAudience = _audience,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };
        
        return tokenHandler.ValidateToken(token, validationParameters, out _);
    }
}

Identity Providers Integration

Azure AD
csharp
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));

services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireRole("Admin"));
});
Auth0
csharp
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://your-domain.auth0.com/";
        options.Audience = "https://your-api.com";
    });

🛡️ OWASP Top 10

1. Broken Access Control

csharp
[Authorize(Roles = "Admin")]
public class AdminController : ControllerBase
{
    [HttpGet("users")]
    public async Task<IActionResult> GetUsers()
    {
        var currentUser = User.Identity.Name;
        var userRole = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value;
        
        if (userRole != "Admin")
        {
            return Forbid();
        }
        
        return Ok(await _userService.GetAllUsers());
    }
}

2. Cryptographic Failures

csharp
public class EncryptionService
{
    private readonly byte[] _key;
    private readonly byte[] _iv;
    
    public string Encrypt(string plainText)
    {
        using var aes = Aes.Create();
        aes.Key = _key;
        aes.IV = _iv;
        
        using var encryptor = aes.CreateEncryptor();
        using var msEncrypt = new MemoryStream();
        using var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
        using var swEncrypt = new StreamWriter(csEncrypt);
        
        swEncrypt.Write(plainText);
        swEncrypt.Close();
        
        return Convert.ToBase64String(msEncrypt.ToArray());
    }
}

3. Injection

csharp
// SQL Injection Prevention
public async Task<User> GetUserByIdAsync(int id)
{
    return await _context.Users
        .FirstOrDefaultAsync(u => u.Id == id);
}

// XSS Prevention
public string SanitizeHtml(string input)
{
    var sanitizer = new HtmlSanitizer();
    return sanitizer.Sanitize(input);
}

🔒 Autenticação e Autorização

Custom Authentication Handler

csharp
public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey("Authorization"))
        {
            return AuthenticateResult.Fail("Authorization header not found");
        }
        
        var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
        
        try
        {
            var claims = ValidateToken(token);
            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, Scheme.Name);
            
            return AuthenticateResult.Success(ticket);
        }
        catch
        {
            return AuthenticateResult.Fail("Invalid token");
        }
    }
}

Role-Based Authorization

csharp
[Authorize(Roles = "Admin,Manager")]
public class SecureController : ControllerBase
{
    [Authorize(Policy = "MinimumAge")]
    public IActionResult GetSensitiveData()
    {
        return Ok("Sensitive data");
    }
}

// Custom Policy
services.AddAuthorization(options =>
{
    options.AddPolicy("MinimumAge", policy =>
        policy.RequireAssertion(context =>
            context.User.HasClaim(c => 
                c.Type == "Age" && 
                int.Parse(c.Value) >= 18)));
});

🔐 Secrets Management

Azure Key Vault

csharp
public class KeyVaultService
{
    private readonly SecretClient _secretClient;
    
    public async Task<string> GetSecretAsync(string secretName)
    {
        var secret = await _secretClient.GetSecretAsync(secretName);
        return secret.Value.Value;
    }
}

// Configuration
services.AddAzureClients(builder =>
{
    builder.AddSecretClient(new Uri("https://your-keyvault.vault.azure.net/"));
});

Environment Variables

csharp
// appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=MyDb;"
  }
}

// Program.cs
builder.Configuration.AddEnvironmentVariables();

📊 Security Headers

Middleware Configuration

csharp
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Frame-Options", "DENY");
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    context.Response.Headers.Add("X-XSS-Protection", "1; mode=block");
    context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
    context.Response.Headers.Add("Content-Security-Policy", 
        "default-src 'self'; script-src 'self' 'unsafe-inline'");
    
    await next();
});

🧪 Security Testing

Unit Tests

csharp
[Test]
public async Task GetUser_WithInvalidToken_ReturnsUnauthorized()
{
    var controller = new UserController(_userService);
    controller.ControllerContext = new ControllerContext
    {
        HttpContext = new DefaultHttpContext()
    };
    
    var result = await controller.GetUser(1);
    
    Assert.IsInstanceOf<UnauthorizedResult>(result);
}

Integration Tests

csharp
[Test]
public async Task AdminEndpoint_WithUserRole_ReturnsForbidden()
{
    var client = _factory.CreateClient();
    var token = await GetUserTokenAsync(client);
    client.DefaultRequestHeaders.Authorization = 
        new AuthenticationHeaderValue("Bearer", token);
    
    var response = await client.GetAsync("/admin/users");
    
    Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode);
}

📋 Checklist de Segurança

  • [ ] Implementar HTTPS em produção
  • [ ] Configurar headers de segurança
  • [ ] Validar todas as entradas do usuário
  • [ ] Implementar rate limiting
  • [ ] Usar autenticação forte (OAuth 2.0/OpenID Connect)
  • [ ] Implementar autorização baseada em roles
  • [ ] Criptografar dados sensíveis
  • [ ] Gerenciar secrets de forma segura
  • [ ] Implementar logging de auditoria
  • [ ] Realizar testes de segurança regulares
  • [ ] Manter dependências atualizadas
  • [ ] Implementar CORS adequadamente
  • [ ] Configurar backup e recuperação
  • [ ] Documentar políticas de segurança