skills/hack23/cia/threat-modeling

threat-modeling

SKILL.md

Threat Modeling Skill

Purpose

This skill provides structured methodology for identifying, analyzing, and mitigating security threats in the CIA platform using industry-standard frameworks including STRIDE, PASTA, and attack tree analysis. It ensures proactive security design aligned with Hack23 ISMS requirements.

When to Use This Skill

Apply this skill when:

  • ✅ Designing new features that handle sensitive political data
  • ✅ Integrating external APIs (Riksdagen, World Bank, Election Authority)
  • ✅ Implementing authentication or authorization mechanisms
  • ✅ Modifying security architecture or trust boundaries
  • ✅ Before major releases to identify residual risks
  • ✅ After security incidents to prevent recurrence
  • ✅ Conducting annual security architecture reviews

Do NOT use for:

  • ❌ Routine bug fixes without security implications
  • ❌ UI/UX changes that don't affect security
  • ❌ Performance optimizations (unless affecting security)

STRIDE Threat Model Framework

S - Spoofing Identity

Threats to Consider:

  • Attackers impersonating legitimate users
  • Session hijacking or fixation
  • Credential theft or replay attacks
  • API key theft and misuse

CIA Platform Attack Scenarios:

Threat: Attacker impersonates politician to modify profile data
├─ Entry Point: User authentication endpoint (/login)
├─ Attack Vector: Credential stuffing with breached password databases
├─ Impact: Reputational damage, data integrity loss
└─ Mitigation:
    ├─ Implement rate limiting (5 attempts per 15 minutes)
    ├─ Enable 2FA for sensitive accounts
    ├─ Monitor for suspicious login patterns
    └─ Enforce strong password policy (12+ chars, complexity)

Mitigation Checklist:

  • ✅ Multi-factor authentication for privileged accounts
  • ✅ Certificate-based authentication for API clients
  • ✅ Strong password policies (bcrypt with cost factor 12)
  • ✅ Session tokens with HMAC integrity protection
  • ✅ JWT signature verification for API tokens

Code Pattern:

@Service
public class AuthenticationService {
    
    private static final int MAX_LOGIN_ATTEMPTS = 5;
    private static final Duration LOCKOUT_PERIOD = Duration.ofMinutes(15);
    
    @Autowired
    private LoginAttemptService loginAttemptService;
    
    @Autowired
    private UserDetailsService userDetailsService;
    
    public AuthenticationToken authenticate(LoginRequest request) {
        String username = request.getUsername();
        
        // Check if account is locked due to failed attempts
        if (loginAttemptService.isLocked(username)) {
            throw new AccountLockedException(
                "Account temporarily locked. Try again in " + 
                loginAttemptService.getTimeUntilUnlock(username) + " minutes"
            );
        }
        
        try {
            // Authenticate user
            UserDetails user = userDetailsService.loadUserByUsername(username);
            
            if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
                loginAttemptService.recordFailedAttempt(username);
                throw new BadCredentialsException("Invalid credentials");
            }
            
            // Success - reset attempt counter
            loginAttemptService.resetAttempts(username);
            
            // Generate secure token
            return tokenService.generateToken(user);
            
        } catch (UsernameNotFoundException e) {
            // Don't reveal if username exists
            throw new BadCredentialsException("Invalid credentials");
        }
    }
}

T - Tampering with Data

Threats to Consider:

  • Modification of politician voting records
  • Alteration of financial data or reports
  • Database injection attacks
  • Parameter tampering in HTTP requests

CIA Platform Attack Scenarios:

Threat: Attacker modifies politician absence rate to damage reputation
├─ Entry Point: REST API endpoint /api/politicians/{id}/data
├─ Attack Vector: SQL injection via unvalidated input parameters
├─ Impact: Data integrity compromise, false political analysis
└─ Mitigation:
    ├─ Use JPA parameterized queries exclusively
    ├─ Implement data integrity checks (checksums, timestamps)
    ├─ Enable database audit logging
    └─ Apply digital signatures to critical data

Mitigation Checklist:

  • ✅ All database queries use parameterized statements
  • ✅ Input validation on all user-provided data
  • ✅ Data integrity checks (checksums, digital signatures)
  • ✅ Database audit logging enabled
  • ✅ CSRF protection on all state-changing operations
  • ✅ Immutable data structures for sensitive information

Code Pattern:

@Entity
@Table(name = "politician_voting_record")
@Audited // Hibernate Envers for audit trail
public class VotingRecord {
    
    @Id
    @GeneratedValue
    private Long id;
    
    @Column(nullable = false)
    private String politicianId;
    
    @Column(nullable = false)
    private String voteType;
    
    @Column(nullable = false)
    private LocalDateTime voteDate;
    
    // Integrity protection - computed hash of critical fields
    @Column(name = "data_hash")
    private String dataHash;
    
    @PrePersist
    @PreUpdate
    private void calculateHash() {
        this.dataHash = DigestUtils.sha256Hex(
            politicianId + voteType + voteDate.toString()
        );
    }
    
    public boolean verifyIntegrity() {
        String expectedHash = DigestUtils.sha256Hex(
            politicianId + voteType + voteDate.toString()
        );
        return expectedHash.equals(this.dataHash);
    }
}

@Repository
public interface VotingRecordRepository extends JpaRepository<VotingRecord, Long> {
    // Safe: JPA query with named parameters
    @Query("SELECT v FROM VotingRecord v WHERE v.politicianId = :politicianId " +
           "AND v.voteDate BETWEEN :startDate AND :endDate")
    List<VotingRecord> findByPoliticianAndDateRange(
        @Param("politicianId") String politicianId,
        @Param("startDate") LocalDateTime startDate,
        @Param("endDate") LocalDateTime endDate
    );
}

R - Repudiation

Threats to Consider:

  • Users denying actions they performed
  • Lack of audit trails for sensitive operations
  • Missing transaction logs
  • Insufficient evidence for security investigations

CIA Platform Attack Scenarios:

Threat: Administrator denies modifying user permissions
├─ Entry Point: Admin panel /admin/users/{id}/permissions
├─ Attack Vector: No audit logging of administrative actions
├─ Impact: Accountability loss, inability to investigate incidents
└─ Mitigation:
    ├─ Implement comprehensive audit logging
    ├─ Log all authentication and authorization events
    ├─ Include timestamps, user identity, IP address, action details
    └─ Store logs in tamper-proof storage (write-once)

Mitigation Checklist:

  • ✅ Comprehensive audit logging for all sensitive operations
  • ✅ Logs include: timestamp, user, IP, action, outcome
  • ✅ Logs stored in tamper-resistant storage
  • ✅ Log retention policy enforced (minimum 1 year)
  • ✅ Regular log review and analysis
  • ✅ Digital signatures on critical transactions

Code Pattern:

@Component
@Aspect
public class AuditLoggingAspect {
    
    private static final Logger auditLog = LoggerFactory.getLogger("AUDIT");
    
    @Autowired
    private AuditLogRepository auditLogRepository;
    
    @Around("@annotation(Audited)")
    public Object logAuditEvent(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        String className = signature.getDeclaringTypeName();
        
        // Capture context
        String username = SecurityContextHolder.getContext()
            .getAuthentication().getName();
        String ipAddress = RequestContextHolder.currentRequestAttributes()
            .getSessionId();
        
        AuditLogEntry entry = new AuditLogEntry();
        entry.setTimestamp(Instant.now());
        entry.setUsername(username);
        entry.setIpAddress(ipAddress);
        entry.setAction(className + "." + methodName);
        entry.setParameters(Arrays.toString(joinPoint.getArgs()));
        
        try {
            // Execute the method
            Object result = joinPoint.proceed();
            
            entry.setOutcome("SUCCESS");
            entry.setResult(result != null ? result.toString() : "void");
            
            return result;
            
        } catch (Exception e) {
            entry.setOutcome("FAILURE");
            entry.setErrorMessage(e.getMessage());
            throw e;
            
        } finally {
            // Always log, even on failure
            auditLogRepository.save(entry);
            auditLog.info("Audit: {}", entry.toJson());
        }
    }
}

@Entity
@Table(name = "audit_log")
public class AuditLogEntry {
    @Id
    @GeneratedValue
    private Long id;
    
    @Column(nullable = false, updatable = false)
    private Instant timestamp;
    
    @Column(nullable = false, updatable = false)
    private String username;
    
    @Column(updatable = false)
    private String ipAddress;
    
    @Column(nullable = false, updatable = false)
    private String action;
    
    @Column(updatable = false, columnDefinition = "TEXT")
    private String parameters;
    
    @Column(nullable = false, updatable = false)
    private String outcome;
    
    // Immutable - prevent tampering
    @PreUpdate
    private void preventUpdate() {
        throw new IllegalStateException("Audit log entries cannot be modified");
    }
}

I - Information Disclosure

Threats to Consider:

  • Exposure of personal identifiable information (PII)
  • Leakage of API keys or credentials
  • Verbose error messages revealing system details
  • Insufficient access controls on sensitive data

CIA Platform Attack Scenarios:

Threat: Attacker accesses politician personal contact information
├─ Entry Point: Public API endpoint /api/politicians/{id}
├─ Attack Vector: Insufficient access control, over-fetching data
├─ Impact: GDPR violation, privacy breach
└─ Mitigation:
    ├─ Implement field-level access control
    ├─ Return only public data in API responses
    ├─ Redact or mask sensitive fields (phone, email)
    └─ Log all access to PII for audit purposes

Mitigation Checklist:

  • ✅ Sensitive data encrypted at rest (database encryption)
  • ✅ TLS 1.2+ for all data in transit
  • ✅ Error messages sanitized (no stack traces in production)
  • ✅ Access control on all data endpoints
  • ✅ Data classification and handling procedures
  • ✅ PII minimization and purpose limitation

Code Pattern:

@RestController
@RequestMapping("/api/politicians")
public class PoliticianController {
    
    @GetMapping("/{id}")
    public ResponseEntity<PoliticianDTO> getPolitician(
            @PathVariable String id,
            @AuthenticationPrincipal UserDetails currentUser) {
        
        Politician politician = politicianService.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("Politician not found"));
        
        // Apply field-level filtering based on user role
        PoliticianDTO dto = mapToDTO(politician, currentUser);
        
        // Log PII access for audit
        auditLogger.logPIIAccess(currentUser.getUsername(), "Politician", id);
        
        return ResponseEntity.ok(dto);
    }
    
    private PoliticianDTO mapToDTO(Politician politician, UserDetails user) {
        PoliticianDTO dto = new PoliticianDTO();
        
        // Always include public information
        dto.setFirstName(politician.getFirstName());
        dto.setLastName(politician.getLastName());
        dto.setParty(politician.getParty());
        dto.setDistrict(politician.getDistrict());
        
        // Only include sensitive data for authorized users
        if (hasRole(user, "ADMIN") || hasRole(user, "RESEARCHER")) {
            // Redact instead of exposing full data
            dto.setEmail(redactEmail(politician.getEmail()));
            dto.setPhone(redactPhone(politician.getPhone()));
        }
        
        return dto;
    }
    
    private String redactEmail(String email) {
        if (email == null) return null;
        int atIndex = email.indexOf('@');
        if (atIndex > 2) {
            return email.substring(0, 2) + "***" + email.substring(atIndex);
        }
        return "***" + email.substring(atIndex);
    }
}

@Configuration
public class SecurityHeadersConfig {
    
    @Bean
    public SecurityFilterChain securityHeaders(HttpSecurity http) throws Exception {
        http.headers(headers -> headers
            .contentSecurityPolicy("default-src 'self'; script-src 'self'; style-src 'self'")
            .xssProtection()
            .frameOptions().deny()
            .httpStrictTransportSecurity()
                .maxAgeInSeconds(31536000)
                .includeSubDomains(true)
        );
        return http.build();
    }
}

D - Denial of Service

Threats to Consider:

  • Resource exhaustion attacks (CPU, memory, disk)
  • Application-level DoS (expensive queries)
  • Distributed denial of service (DDoS)
  • API abuse and rate limit bypass

CIA Platform Attack Scenarios:

Threat: Attacker overwhelms system with expensive political data queries
├─ Entry Point: Public search API /api/search?query=*
├─ Attack Vector: Recursive queries, unbounded result sets
├─ Impact: Service unavailability, degraded performance for legitimate users
└─ Mitigation:
    ├─ Implement rate limiting (100 requests/minute per IP)
    ├─ Query result pagination (max 100 results per page)
    ├─ Timeout for long-running queries (30 seconds)
    └─ Resource quotas per user tier

Mitigation Checklist:

  • ✅ Rate limiting on all public APIs
  • ✅ Request size limits enforced
  • ✅ Query timeouts configured
  • ✅ Pagination on all list endpoints
  • ✅ Resource monitoring and alerting
  • ✅ Circuit breakers for external dependencies

Code Pattern:

@Configuration
public class RateLimitingConfig {
    
    @Bean
    public RateLimiter apiRateLimiter() {
        return RateLimiter.create(100.0); // 100 requests per second
    }
}

@Component
public class RateLimitingInterceptor implements HandlerInterceptor {
    
    @Autowired
    private RateLimiter rateLimiter;
    
    private final LoadingCache<String, AtomicInteger> requestCounts = CacheBuilder.newBuilder()
        .expireAfterWrite(1, TimeUnit.MINUTES)
        .build(new CacheLoader<String, AtomicInteger>() {
            public AtomicInteger load(String key) {
                return new AtomicInteger(0);
            }
        });
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                            Object handler) throws Exception {
        
        String clientIp = getClientIP(request);
        
        // Apply rate limit
        if (!rateLimiter.tryAcquire(1, TimeUnit.SECONDS)) {
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().write("Rate limit exceeded. Try again later.");
            return false;
        }
        
        // Check per-IP limit
        int requestCount = requestCounts.get(clientIp).incrementAndGet();
        if (requestCount > 1000) {
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().write("IP-based rate limit exceeded.");
            return false;
        }
        
        return true;
    }
}

@Repository
public interface PoliticianSearchRepository extends JpaRepository<Politician, Long> {
    
    // Pageable prevents unbounded result sets
    @Query("SELECT p FROM Politician p WHERE " +
           "LOWER(p.firstName) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR " +
           "LOWER(p.lastName) LIKE LOWER(CONCAT('%', :searchTerm, '%'))")
    @QueryHints(@QueryHint(name = "org.hibernate.timeout", value = "30")) // 30 second timeout
    Page<Politician> search(@Param("searchTerm") String searchTerm, Pageable pageable);
}

@RestController
public class SearchController {
    
    private static final int MAX_PAGE_SIZE = 100;
    
    @GetMapping("/api/search")
    public Page<PoliticianDTO> search(
            @RequestParam String query,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        // Enforce maximum page size
        if (size > MAX_PAGE_SIZE) {
            size = MAX_PAGE_SIZE;
        }
        
        Pageable pageable = PageRequest.of(page, size);
        return searchService.search(query, pageable);
    }
}

E - Elevation of Privilege

Threats to Consider:

  • Horizontal privilege escalation (access other users' data)
  • Vertical privilege escalation (gain admin rights)
  • Bypassing authorization checks
  • Exploiting misconfigured access controls

CIA Platform Attack Scenarios:

Threat: Regular user gains administrative access to modify site configuration
├─ Entry Point: Admin API endpoint /api/admin/settings
├─ Attack Vector: Missing @PreAuthorize annotation on controller method
├─ Impact: Unauthorized configuration changes, system compromise
└─ Mitigation:
    ├─ Enforce role-based access control on all endpoints
    ├─ Use Spring Security annotations (@PreAuthorize, @Secured)
    ├─ Implement defense in depth (controller + service layer checks)
    └─ Regular access control audits

Mitigation Checklist:

  • ✅ Role-based access control (RBAC) implemented
  • ✅ Principle of least privilege enforced
  • ✅ Authorization checks at multiple layers
  • ✅ Regular access control reviews
  • ✅ Privilege escalation attempts logged and alerted
  • ✅ No default or backdoor admin accounts

Code Pattern:

@RestController
@RequestMapping("/api/admin")
@PreAuthorize("hasRole('ADMIN')") // Controller-level authorization
public class AdminController {
    
    @PostMapping("/settings")
    @PreAuthorize("hasAuthority('MODIFY_SETTINGS')") // Method-level check
    public ResponseEntity<SystemSettings> updateSettings(
            @RequestBody @Valid SystemSettingsRequest request,
            @AuthenticationPrincipal UserDetails currentUser) {
        
        // Log privileged action
        auditLogger.logPrivilegedAction(
            currentUser.getUsername(),
            "UPDATE_SYSTEM_SETTINGS",
            request.toString()
        );
        
        // Service layer also enforces authorization
        SystemSettings updated = adminService.updateSettings(request);
        
        return ResponseEntity.ok(updated);
    }
}

@Service
public class AdminService {
    
    @PreAuthorize("hasRole('ADMIN')")
    public SystemSettings updateSettings(SystemSettingsRequest request) {
        // Verify authorization again at service layer (defense in depth)
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (!auth.getAuthorities().stream()
                .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) {
            throw new AccessDeniedException("Admin role required");
        }
        
        // Perform update
        SystemSettings settings = settingsRepository.findCurrent();
        settings.updateFrom(request);
        return settingsRepository.save(settings);
    }
}

// Global method security enabled
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler handler = 
            new DefaultMethodSecurityExpressionHandler();
        handler.setPermissionEvaluator(new CustomPermissionEvaluator());
        return handler;
    }
}

Attack Tree Analysis

Example: Compromise Politician Data Integrity

ROOT: Compromise Politician Voting Record Data
├─ AND: Gain Write Access
│  ├─ OR: Exploit Authentication
│  │  ├─ Brute force credentials [Mitigated: Rate limiting]
│  │  ├─ Credential stuffing [Mitigated: 2FA]
│  │  └─ Session hijacking [Mitigated: Secure cookies]
│  └─ OR: Exploit Authorization
│     ├─ Privilege escalation [Mitigated: RBAC]
│     └─ IDOR vulnerability [Mitigated: Ownership checks]
└─ AND: Modify Data
   ├─ OR: Direct Database Access
   │  ├─ SQL injection [Mitigated: Parameterized queries]
   │  └─ Database credential theft [Mitigated: Secrets management]
   └─ OR: API Manipulation
      ├─ Parameter tampering [Mitigated: Input validation]
      └─ CSRF attack [Mitigated: CSRF tokens]

Attack Tree Legend:

  • AND: All child nodes must succeed
  • OR: Any child node success achieves goal
  • [Mitigated]: Control in place, residual risk accepted

Security Architecture Review

Trust Boundaries

Internet Users (Untrusted)
    ├─→ Application Firewall / Rate Limiter
    │       │
    │       ├─→ Spring Boot Application (DMZ)
    │       │       │
    │       │       ├─→ Authentication Filter
    │       │       ├─→ Authorization Filter
    │       │       └─→ CSRF Protection
    │       │
    │       └─→ Internal Network (Trusted)
    │               │
    │               ├─→ PostgreSQL Database (Encrypted)
    │               └─→ Redis Session Store (Encrypted)
    └─→ External APIs (Semi-Trusted)
            ├─→ Riksdagen API (HTTPS only)
            ├─→ World Bank API (HTTPS only)
            └─→ Election Authority API (HTTPS only)

Data Flow Diagram (DFD) Security Analysis

Level 0 DFD - Context Diagram:

[Public Users] → (CIA Web App) → [Database]
[Admin Users] → (CIA Web App) → [External APIs]

Security Analysis:

  • Public Users: Untrusted, require authentication for sensitive operations
  • Admin Users: Trusted but verify, require strong authentication (2FA)
  • External APIs: Semi-trusted, validate all responses
  • Database: Trusted, encrypted at rest and in transit

Threat Model Documentation Template

# Threat Model: [Feature Name]

## Overview
- **Component**: [Component being analyzed]
- **Last Updated**: [Date]
- **Reviewer**: [Name]
- **Risk Rating**: [Critical/High/Medium/Low]

## Assets
1. Politician personal information (GDPR protected)
2. Voting records (integrity critical)
3. User credentials (confidentiality critical)
4. API keys for external services

## Trust Boundaries
- Internet → Application Server
- Application Server → Database
- Application Server → External APIs

## STRIDE Analysis

### Spoofing
- **Threat**: [Description]
- **Likelihood**: [High/Medium/Low]
- **Impact**: [High/Medium/Low]
- **Risk**: [Critical/High/Medium/Low]
- **Mitigation**: [Controls in place]
- **Residual Risk**: [Accepted/Needs treatment]

[Repeat for T, R, I, D, E]

## Attack Trees
[Attach attack tree diagrams]

## Security Requirements
1. [Requirement 1]
2. [Requirement 2]

## Security Test Cases
1. Test authentication bypass attempts
2. Test authorization escalation
3. Test input validation

## ISMS Compliance
- ISO 27001:2022 A.5.15 (Access Control)
- NIST CSF PR.AC-4 (Access Permissions)
- CIS Control 6.1 (Access Control Management)

## Sign-off
- **Security Team**: [Approved/Rejected]
- **Development Team**: [Approved/Rejected]
- **Date**: [Date]

ISMS Compliance Mapping

ISO 27001:2022 Controls

  • A.5.15 - Access Control: STRIDE analysis ensures proper access controls
  • A.8.8 - Management of Technical Vulnerabilities: Threat modeling identifies vulnerabilities proactively
  • A.14.2.1 - Secure Development Policy: Threat modeling is mandatory step in SDLC
  • A.16.1 - Management of Information Security Incidents: Attack trees inform incident response

NIST Cybersecurity Framework

  • ID.RA-1: Vulnerabilities identified through threat modeling
  • ID.RA-3: Threats identified internally and externally
  • PR.IP-1: Baseline security configurations from threat analysis
  • DE.CM-4: System monitored for malicious activity based on threat model

CIS Controls v8

  • Control 18.3: Establish and maintain architecture documentation
  • Control 18.4: Establish secure application design
  • Control 18.5: Document application design flaws

Hack23 ISMS Policy References

Threat Management Framework:

All Hack23 ISMS Policies: https://github.com/Hack23/ISMS-PUBLIC

CIA Platform Architecture References

References

Threat Modeling Standards

Tools & Frameworks

Weekly Installs
5
Repository
hack23/cia
GitHub Stars
213
First Seen
12 days ago
Installed on
opencode5
claude-code5
github-copilot5
codex5
amp5
cline5