security-patterns

Security Patterns for Web Applications

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "security-patterns" with this command: npx skills add thapaliyabikendra/ai-artifacts/thapaliyabikendra-ai-artifacts-security-patterns

Security Patterns for Web Applications

Security patterns and practices for building secure ABP Framework applications.

When to Use

  • Conducting security audits

  • Implementing authentication/authorization

  • Creating threat models (STRIDE)

  • Reviewing code for OWASP Top 10 vulnerabilities

  • Designing permission systems

  • Validating input and sanitizing output

STRIDE Threat Model

Framework

Category Threat Question Mitigation

Spoofing Identity theft Can attacker impersonate user? Authentication, tokens

Tampering Data modification Can attacker modify data? Integrity checks, signing

Repudiation Denial of actions Can user deny their actions? Audit logging

Information Disclosure Data exposure Can attacker access sensitive data? Encryption, access control

Denial of Service Availability attack Can attacker disrupt service? Rate limiting, scaling

Elevation of Privilege Unauthorized access Can attacker gain higher privileges? Authorization, least privilege

Threat Model Template

Threat Model: [Feature Name]

Date: YYYY-MM-DD Reviewer: [Name]

Assets

AssetSensitivityDescription
Patient DataHIGHPII including medical records
User CredentialsCRITICALPasswords, tokens
Appointment DataMEDIUMScheduling information

Threat Analysis

IDCategoryThreatLikelihoodImpactRiskMitigation
T1SpoofingAttacker impersonates patientMediumHighHIGHOAuth 2.0, MFA
T2TamperingAttacker modifies appointmentLowMediumLOWAuthorization checks
T3Info DisclosureUnauthorized patient data accessMediumCriticalCRITICALRow-level security
T4ElevationReceptionist gains admin accessLowCriticalHIGHPermission validation

Mitigations

IDThreatControlStatus
M1T1Implement OAuth 2.0 with OpenIddictImplemented
M2T3Add row-level authorization in AppServicePending

OWASP Top 10 Checklist

  1. Injection (A01)

// BAD: SQL Injection var query = $"SELECT * FROM Users WHERE Email = '{email}'";

// GOOD: Parameterized query (EF Core does this automatically) var user = await _dbContext.Users .FirstOrDefaultAsync(u => u.Email == email);

// BAD: Command injection Process.Start("cmd", $"/c dir {userInput}");

// GOOD: Validate and sanitize input if (!IsValidPath(userInput)) throw new BusinessException("Invalid path");

  1. Broken Authentication (A02)

// Checklist: // [ ] Use OAuth 2.0 / OpenIddict // [ ] Implement token expiry (short-lived access, long-lived refresh) // [ ] Hash passwords with modern algorithm (BCrypt, Argon2) // [ ] Implement account lockout after failed attempts // [ ] Use secure session management // [ ] Implement MFA for sensitive operations

  1. Sensitive Data Exposure (A03)

// BAD: Logging PII _logger.LogInformation("User {Email} logged in", user.Email);

// GOOD: Log identifiers only _logger.LogInformation("User {UserId} logged in", user.Id);

// BAD: Returning sensitive data return new UserDto { PasswordHash = user.PasswordHash };

// GOOD: Exclude sensitive fields return new UserDto { Id = user.Id, Name = user.Name };

  1. Security Misconfiguration (A05)

// Checklist: // [ ] Disable debug mode in production // [ ] Remove default credentials // [ ] Configure CORS properly // [ ] Set secure headers (CSP, X-Frame-Options) // [ ] Disable directory listing // [ ] Keep frameworks updated

  1. Broken Access Control (A01)

// BAD: No authorization public async Task<PatientDto> GetPatientAsync(Guid id) { return await _repository.GetAsync(id); }

// GOOD: Authorization enforced [Authorize(ClinicPermissions.Patients.Default)] public async Task<PatientDto> GetPatientAsync(Guid id) { var patient = await _repository.GetAsync(id);

// Additional check: Can user access this specific patient?
await AuthorizationService.CheckAsync(patient, CommonOperations.Get);

return ObjectMapper.Map&#x3C;Patient, PatientDto>(patient);

}

ABP Authorization Patterns

Permission Definition

public static class {ProjectName}Permissions { public const string GroupName = "{ProjectName}";

public static class {Feature}
{
    public const string Default = GroupName + ".{Feature}";
    public const string Create = Default + ".Create";
    public const string Edit = Default + ".Edit";
    public const string Delete = Default + ".Delete";
    public const string ViewAll = Default + ".ViewAll";
}

}

AppService Authorization

[Authorize({ProjectName}Permissions.{Feature}.Default)] public class {Entity}AppService : ApplicationService { [Authorize({ProjectName}Permissions.{Feature}.Create)] public async Task<{Entity}Dto> CreateAsync(CreateUpdate{Entity}Dto input) { // Create logic }

[Authorize({ProjectName}Permissions.{Feature}.Edit)]
public async Task&#x3C;{Entity}Dto> UpdateAsync(Guid id, CreateUpdate{Entity}Dto input)
{
    // Update logic
}

[Authorize({ProjectName}Permissions.{Feature}.Delete)]
public async Task DeleteAsync(Guid id)
{
    // Delete logic
}

}

Resource-Based Authorization

public async Task<PatientDto> GetAsync(Guid id) { var patient = await _repository.GetAsync(id);

// Check if current user can access this specific patient
if (patient.AssignedDoctorId != CurrentUser.Id)
{
    await AuthorizationService.CheckAsync(
        {ProjectName}Permissions.{Feature}.ViewAll);
}

return ObjectMapper.Map&#x3C;Patient, PatientDto>(patient);

}

Security Audit Report Template

Security Audit Report

Application: [Name] Date: YYYY-MM-DD Auditor: [Name] Risk Level: Critical | High | Medium | Low

Executive Summary

[1-2 paragraph overview of findings]

Findings

[VULN-001] [Title]

  • Severity: Critical | High | Medium | Low
  • Category: OWASP A01-A10 / STRIDE
  • Location: path/to/file.cs:line
  • Description: [What the vulnerability is]
  • Impact: [What could happen if exploited]
  • Reproduction Steps:
    1. [Step 1]
    2. [Step 2]
  • Recommendation: [How to fix]
  • Code Example:
// Vulnerable code
[code here]

// Fixed code
[code here]

Summary

Severity
Count
Fixed
Pending

Critical
0
0
0

High
0
0
0

Medium
0
0
0

Low
0
0
0

Recommendations

- [Priority recommendation]

- [Secondary recommendation]

## Security Checklist

### Authentication
- [ ] OAuth 2.0 / OpenID Connect implemented
- [ ] Token expiry configured (access: 15-60 min, refresh: 7-30 days)
- [ ] Password policy enforced (min length, complexity)
- [ ] Account lockout after failed attempts
- [ ] MFA available for sensitive operations
- [ ] Secure password reset flow

### Authorization
- [ ] All endpoints have `[Authorize]` attribute
- [ ] Permissions defined for all operations
- [ ] Role-based access enforced
- [ ] Resource-based authorization where needed
- [ ] No permission bypass vulnerabilities
- [ ] Least privilege principle applied

### Input Validation
- [ ] All DTOs have FluentValidation
- [ ] SQL uses parameterized queries (EF Core)
- [ ] File uploads restricted by type and size
- [ ] API rate limiting configured
- [ ] XSS prevention (output encoding)
- [ ] CSRF protection enabled

### Data Protection
- [ ] PII not logged
- [ ] Sensitive data encrypted at rest
- [ ] TLS enforced (HTTPS only)
- [ ] Secure headers configured
- [ ] Error messages don't expose internals
- [ ] Connection strings secured

### Audit &#x26; Monitoring
- [ ] Security events logged
- [ ] Failed auth attempts tracked
- [ ] Admin actions audited
- [ ] Anomaly detection configured
- [ ] Log integrity protected

## Authorization Anti-Patterns (Quick Scan)

Use this table for rapid code review scanning:

| Pattern | Risk Level | Fix |
|---------|------------|-----|
| No `[Authorize]` on public method | 🔴 CRITICAL | Add `[Authorize(Permission)]` |
| `[Authorize]` only at class level | 🟡 MEDIUM | Add method-level permissions for mutations |
| No permission check for bulk operations | 🔴 HIGH | Check permission per operation or batch |
| Missing `[RequiresTenant]` on tenant-specific ops | 🔴 HIGH | Add `[RequiresTenant]` attribute |
| `_dataFilter.Disable&#x3C;IMultiTenant>()` without comment | 🔴 CRITICAL | Add justification comment or remove |
| Hardcoded secrets in code | 🔴 CRITICAL | Use configuration/secrets management |
| PII in log messages | 🟡 MEDIUM | Log identifiers only, not PII |

## Multi-Tenancy Security

### Dangerous Pattern: Disabling Tenant Filter

```csharp
// ⚠️ DANGEROUS: Cross-tenant data exposure risk!
using (_dataFilter.Disable&#x3C;IMultiTenant>())
{
    // This query now sees ALL tenants' data!
    var exists = await _repository.AnyAsync(x => x.Code == code);
}

Risks:

- Cross-tenant data leakage

- Incorrect validation results (e.g., "code already exists" when it exists in another tenant)

- Security audit failures

When Disabling is Justified (Rare)

Only disable multi-tenancy with explicit justification comment:

// ✅ JUSTIFIED: License plate numbers must be globally unique across all tenants
// to ensure physical warehouse operations don't conflict between tenants sharing facilities.
// Approved by: [Name] on [Date]
using (_dataFilter.Disable&#x3C;IMultiTenant>())
{
    var existsGlobally = await _licensePlateRepository.AnyAsync(
        lp => lp.LicensePlateNumber == input.LicensePlateNumber &#x26;&#x26; !lp.ShippedOut);
}

Multi-Tenancy Security Checklist

-  No _dataFilter.Disable&#x3C;IMultiTenant>()
 without documented justification

-  Cross-tenant uniqueness checks are truly required (not accidental)

-  Error messages don't reveal other tenants' data

-  Audit logging captures cross-tenant operations

-  Unit tests verify tenant isolation

Common Vulnerability Patterns

Missing Authorization

// VULNERABLE
public async Task&#x3C;PatientDto> GetAsync(Guid id)
{
    return await _repository.GetAsync(id);
}

// SECURE
[Authorize({ProjectName}Permissions.Patients.Default)]
public async Task&#x3C;PatientDto> GetAsync(Guid id)
{
    return await _repository.GetAsync(id);
}

Information Disclosure in Errors

// VULNERABLE
catch (Exception ex)
{
    return BadRequest(ex.ToString()); // Exposes stack trace
}

// SECURE
catch (Exception ex)
{
    _logger.LogError(ex, "Error processing request");
    throw new UserFriendlyException("An error occurred");
}

Insecure Direct Object Reference

// VULNERABLE: Any user can access any patient
[HttpGet("{id}")]
public async Task&#x3C;PatientDto> Get(Guid id)
{
    return await _service.GetAsync(id);
}

// SECURE: Verify user can access this patient
[HttpGet("{id}")]
public async Task&#x3C;PatientDto> Get(Guid id)
{
    var patient = await _service.GetAsync(id);
    if (!await CanAccessPatient(patient))
        throw new UnauthorizedAccessException();
    return patient;
}

References

- references/owasp-top-10-details.md - Detailed OWASP guide

- references/abp-security-config.md - ABP security configuration

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

abp-infrastructure-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

clean-code-dotnet

No summary provided by upstream source.

Repository SourceNeeds Review
General

abp-entity-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

abp-api-implementation

No summary provided by upstream source.

Repository SourceNeeds Review