Broken Authentication

What is Broken Authentication?

Broken Authentication occurs when an API's authentication mechanisms are improperly implemented, allowing attackers to compromise passwords, keys, or session tokens. This can result in unauthorized access to the API and sensitive user data.

Maps to OWASP Top 10

Broken Authentication is categorized under A01:2021 - Broken Access Control in the OWASP Top 10. Broken Access Control is considered the most critical web application security risk, as it affects many applications and can lead to severe consequences like data theft and unauthorized data modification.

Vulnerable Code and Secure Code Example

Attack Scenario

Imagine a company provides an API that requires users to log in with their username and password. The API generates a session token for authenticated users, which must be included in subsequent requests to access protected resources.

Insecure Implementation (Prone to Broken Authentication) Using Java Spring Security

In this insecure implementation, the API does not implement sufficient protections against brute force attacks or session hijacking.

@RestController
@RequestMapping("/api")
public class AuthController {

    private final UserRepository userRepository;

    public AuthController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestParam String username, @RequestParam String password) {
        User user = userRepository.findByUsername(username);

        if (user == null || !user.getPassword().equals(password)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }

        // Generate a session token (insecurely)
        String token = UUID.randomUUID().toString();
        user.setToken(token);
        userRepository.save(user);

        return ResponseEntity.ok(token);
    }

    @GetMapping("/protected")
    public ResponseEntity<?> getProtectedResource(@RequestHeader("Authorization") String token) {
        User user = userRepository.findByToken(token);

        if (user == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
        }

        return ResponseEntity.ok("Protected resource accessed");
    }
}

Attack Payload Example:

curl -X POST -d "username=admin&password=wrongpassword" http://localhost:8080/api/login
curl -H "Authorization: <stolen-token>" http://localhost:8080/api/protected

In this case, attackers can brute force the login endpoint or use a stolen token to access protected resources.

Secure Implementation (Mitigating Broken Authentication) Using Java Spring Security

In the secure implementation, the API includes protections against brute force attacks, session hijacking, and other common vulnerabilities.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/api/login").permitAll()
                .anyRequest().authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

@RestController
@RequestMapping("/api")
public class AuthController {

    private final UserRepository userRepository;
    private final AuthenticationManager authenticationManager;
    private final JWTTokenProvider tokenProvider;

    public AuthController(UserRepository userRepository, AuthenticationManager authenticationManager, JWTTokenProvider tokenProvider) {
        this.userRepository = userRepository;
        this.authenticationManager = authenticationManager;
        this.tokenProvider = tokenProvider;
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestParam String username, @RequestParam String password) {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            User user = userRepository.findByUsername(username);

            // Generate a secure JWT token
            String token = tokenProvider.createToken(username);

            return ResponseEntity.ok(token);
        } catch (AuthenticationException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }
    }

    @GetMapping("/protected")
    public ResponseEntity<?> getProtectedResource(@RequestHeader("Authorization") String token) {
        if (tokenProvider.validateToken(token)) {
            String username = tokenProvider.getUsername(token);
            User user = userRepository.findByUsername(username);

            return ResponseEntity.ok("Protected resource accessed");
        }

        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
    }
}

public class JWTTokenProvider {
    private final String secretKey = "mySecretKey";

    public String createToken(String username) {
        Claims claims = Jwts.claims().setSubject(username);
        Date now = new Date();
        Date validity = new Date(now.getTime() + 3600000); // 1 hour validity

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(now)
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }

    public String getUsername(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
    }
}

The secure implementation:

  • Uses JWT tokens for secure session management.

  • Configures Spring Security to handle authentication and authorization.

  • Implements measures to protect against brute force attacks and session hijacking.

Key Points for Developers

  • Implement secure authentication mechanisms such as JWT tokens.

  • Protect against brute force attacks by implementing rate limiting, account lockout, and CAPTCHA.

  • Securely generate and manage session tokens to prevent session hijacking.

  • Use secure coding practices to validate inputs and handle authentication errors properly.

Summary and Key Takeaways

Broken Authentication vulnerabilities occur when authentication mechanisms are improperly implemented, leading to unauthorized access to APIs and sensitive data. This can be mitigated by implementing secure authentication methods, protecting against brute force attacks, and securely managing session tokens. By following these practices, developers can ensure robust API security and prevent unauthorized access.

Last updated