{"record":{"id":"f2d5b66d08cc7af9","repo":"apache/hadoop","slug":"malformed-gss-token","errorCode":null,"errorMessage":"Malformed gss token","messagePattern":"Malformed gss token","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":401,"severity":"error","filePath":"hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosUtil.java","lineNumber":320,"sourceCode":"    // DER encoding that will be extracted.\n    DER token = new DER(rawToken);\n    // InitialContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {\n    //     mech   OID\n    //     mech-token  (NegotiationToken or InnerContextToken)\n    // }\n    DER oid = token.next();\n    if (oid.equals(DER.SPNEGO_MECH_OID)) {\n      // NegotiationToken ::= CHOICE {\n      //     neg-token-init[0] NegTokenInit\n      // }\n      // NegTokenInit ::= SEQUENCE {\n      //     mech-token[2]     InitialContextToken\n      // }\n      token = token.next().get(0xa0, 0x30, 0xa2, 0x04).next();\n      oid = token.next();\n    }\n    if (!oid.equals(DER.KRB5_MECH_OID)) {\n      throw new IllegalArgumentException(\"Malformed gss token\");\n    }\n    // InnerContextToken ::= {\n    //     token-id[1]\n    //     AP-REQ\n    // }\n    if (token.next().getTag() != 1) {\n      throw new IllegalArgumentException(\"Not an AP-REQ token\");\n    }\n    // AP-REQ ::= [APPLICATION 14] SEQUENCE {\n    //     ticket[3]      Ticket\n    // }\n    DER ticket = token.next().get(0x6e, 0x30, 0xa3, 0x61, 0x30);\n    // Ticket ::= [APPLICATION 1] SEQUENCE {\n    //     realm[1]       String\n    //     sname[2]       PrincipalName\n    // }\n    // PrincipalName ::= SEQUENCE {\n    //     name-string[1] SEQUENCE OF String","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosUtil.java#L302-L338","documentation":"KerberosUtil.getTokenServerName() walks the DER structure of a raw GSS token to extract the TGS server principal. After unwrapping an SPNEGO NegotiationToken the mechanism OID must be the Kerberos v5 OID; if the effective mechanism is not KRB5 (or the bytes do not decode as a Kerberos InitialContextToken), this IllegalArgumentException is thrown.","triggerScenarios":"Calling getTokenServerName(rawToken) with a Negotiate token whose inner mechanism is NTLM or another non-Kerberos mech; feeding arbitrary bytes or an SPNEGO negTokenResp (response) instead of negTokenInit; a truncated token buffer.","commonSituations":"Browsers authenticating with NTLM over Negotiate hitting an SPNEGO endpoint that assumes Kerberos; custom GSS clients sending raw non-Kerberos contexts; middleware dropping trailing bytes of the Authorization header payload.","solutions":["Ensure the client actually performs Kerberos (SPNEGO with KRB5 inner mech), e.g. configure the browser/client and disable NTLM fallback","Before calling, sniff the token type: non-Negotiate or NTLMSSP signatures ('NTLMSSP\\0') should be rejected early","Verify the raw bytes are passed unmodified (correct base64 decoding of the Authorization header)"],"exampleFix":"// before\nString server = KerberosUtil.getTokenServerName(rawToken); // may throw for NTLM\n\n// after: only attempt Kerberos extraction for Kerberos tokens\nif (rawToken.length > 7 && new String(rawToken, 0, 7, US_ASCII).equals(\"NTLMSSP\")) {\n  throw new AuthenticationException(\"NTLM not supported\");\n}\nString server = KerberosUtil.getTokenServerName(rawToken);","handlingStrategy":"try-catch","validationCode":"boolean probablyKerberosNegotiate(byte[] raw) {\n  if (raw == null || raw.length < 2) return false;\n  if (raw.length > 7 && (raw[0]&0xff)=='N' && (raw[1]&0xff)=='T' && (raw[2]&0xff)=='L') return false; // NTLMSSP\n  return (raw[0] & 0xff) == 0x60 || (raw[0] & 0xff) == 0xa0; // InitialContextToken / negTokenInit\n}","typeGuard":null,"tryCatchPattern":"try { server = KerberosUtil.getTokenServerName(rawToken); } catch (IllegalArgumentException e) { /* non-Kerberos or undecodable: respond 401 with Negotiate header */ }","preventionTips":["Ensure clients use real Kerberos (no NTLM fallback) before SPNEGO endpoints","Pass the Authorization header payload base64-decoded and unmodified","Reject NTLMSSP-prefixed tokens before any Kerberos parsing"],"tags":["kerberos","spnego","gss-api","token-parsing"],"backgroundTag":"malformed-spnego-token","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}