webgoat-jwt代码审计

webgoat-jwt代码审计

代码段一 :

try {
   Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parseClaimsJws(accessToken);
   Claims claims = (Claims) jwt.getBody();
   String user = (String) claims.get("user");
   boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
   if (isAdmin) {
     removeAllUsers();
   } else {
     log.error("You are not an admin user");
   }
} catch (JwtException e) {
  throw new InvalidTokenException(e);
}

解析:

关键代码: parseClaimsJws(accessToken)

含义: 这个方法明确要求解析一个 签名的 JWS (JSON Web Signature)。

行为: 它会强制检查 Token 是否包含签名,并使用提供的密钥 ( JWT_PASSWORD ) 验证该签名。

后果: 如果攻击者发送一个没有签名的 Token(例如使用 alg: none ),或者签名不匹配,这个方法会直接抛出异常( JwtException ),代码会进入 catch 块(第 11-12 行)

代码段二:

try {
   Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
   Claims claims = (Claims) jwt.getBody();
   String user = (String) claims.get("user");
   boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
   if (isAdmin) {
     removeAllUsers();
   } else {
     log.error("You are not an admin user");
   }
} catch (JwtException e) {
  throw new InvalidTokenException(e);
}

解析:

关键代码: parse(accessToken)

含义: 这是一个通用的解析方法。它不强制要求 Token 必须是签名的。

行为: 它会根据 Token 头部的 alg 字段来决定如何解析。

后果: 如果攻击者构造一个 Token,将其头部的算法设置为 "alg": "none" , parse() 方法会接受这个 Token,并且 不验证签名(因为算法是 none)。这意味着解析过程会成功,不会抛出异常。