CVE-2014-2062: Improper Authentication (CWE-287)
value: Jenkins before 1.551 and LTS before 1.532.2 does not invalidate the API token when a user is deleted, which allows remote authenticated users to retain access via the token.
CWE description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
Published: 2014-10-17T15:55Z
Repository: https://github.com/jenkinsci/jenkins
Language: Java
Files changed: core/src/main/java/jenkins/security/ApiTokenFilter.java
Commit date: 2014-02-11 14:19:31 -0500
Commit message: [FIXED SECURITY-89] When checking an API token, verify that the user actually exists.

Diff: diff --git a/core/src/main/java/jenkins/security/ApiTokenFilter.java b/core/src/main/java/jenkins/security/ApiTokenFilter.java
index 630ae5ec04..b1078e6240 100644
--- a/core/src/main/java/jenkins/security/ApiTokenFilter.java
+++ b/core/src/main/java/jenkins/security/ApiTokenFilter.java
@@ -1,12 +1,16 @@
 package jenkins.security;
 
 import hudson.model.User;
 import hudson.security.ACL;
+import hudson.security.UserMayOrMayNotExistException;
 import hudson.util.Scrambler;
+import jenkins.model.Jenkins;
 import org.acegisecurity.context.SecurityContext;
 import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.userdetails.UsernameNotFoundException;
+import org.springframework.dao.DataAccessException;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -39,10 +43,21 @@ public class ApiTokenFilter implements Filter {
             // authenticate the user
             String uidpassword = Scrambler.descramble(authorization.substring(6));
             int idx = uidpassword.indexOf(':');
             if (idx >= 0) {
                 String username = uidpassword.substring(0, idx);
+                try {
+                    Jenkins.getInstance().getSecurityRealm().loadUserByUsername(username);
+                } catch (UserMayOrMayNotExistException x) {
+                    // OK, give them the benefit of the doubt.
+                } catch (UsernameNotFoundException x) {
+                    // Not/no longer a user; deny the API token. (But do not leak the information that this happened.)
+                    chain.doFilter(request, response);
+                    return;
+                } catch (DataAccessException x) {
+                    throw new ServletException(x);
+                }
                 String password = uidpassword.substring(idx+1);
 
                 // attempt to authenticate as API token
                 User u = User.get(username);
                 ApiTokenProperty t = u.getProperty(ApiTokenProperty.class);

Fixed code: import hudson.security.UserMayOrMayNotExistException;
import jenkins.model.Jenkins;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
                try {
                    Jenkins.getInstance().getSecurityRealm().loadUserByUsername(username);
                } catch (UserMayOrMayNotExistException x) {
                    // OK, give them the benefit of the doubt.
                } catch (UsernameNotFoundException x) {
                    // Not/no longer a user; deny the API token. (But do not leak the information that this happened.)
                    chain.doFilter(request, response);
                    return;
                } catch (DataAccessException x) {
                    throw new ServletException(x);
                }