{"record":{"id":"defa7337f37d9d9f","repo":"signalapp/Signal-Server","slug":"blank-header","errorCode":null,"errorMessage":"Blank header","messagePattern":"Blank header","errorType":"http","errorClass":"InvalidAuthorizationHeaderException","httpStatus":401,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java","lineNumber":26,"sourceCode":"import org.apache.commons.lang3.StringUtils;\nimport org.whispersystems.textsecuregcm.util.Pair;\n\npublic class BasicAuthorizationHeader {\n\n  private final String username;\n  private final byte deviceId;\n  private final String password;\n\n  private BasicAuthorizationHeader(final String username, final byte deviceId, final String password) {\n    this.username = username;\n    this.deviceId = deviceId;\n    this.password = password;\n  }\n\n  public static BasicAuthorizationHeader fromString(final String header) throws InvalidAuthorizationHeaderException {\n    try {\n      if (StringUtils.isBlank(header)) {\n        throw new InvalidAuthorizationHeaderException(\"Blank header\");\n      }\n\n      final int spaceIndex = header.indexOf(' ');\n\n      if (spaceIndex == -1) {\n        throw new InvalidAuthorizationHeaderException(\"Invalid authorization header: \" + header);\n      }\n\n      final String authorizationType = header.substring(0, spaceIndex);\n\n      if (!\"Basic\".equals(authorizationType)) {\n        throw new InvalidAuthorizationHeaderException(\"Unsupported authorization method: \" + authorizationType);\n      }\n\n      final String credentials;\n\n      try {\n        credentials = new String(Base64.getDecoder().decode(header.substring(spaceIndex + 1)));","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java#L8-L44","documentation":"BasicAuthorizationHeader.fromString parses a Basic Authorization header and throws InvalidAuthorizationHeaderException(\"Blank header\") when the header value is null, empty, or whitespace only. The library requires a non-blank header string before any parsing.","triggerScenarios":"Calling BasicAuthorizationHeader.fromString(null), fromString(\"\"), or fromString(\"   \"); a client sending an Authorization header with no value after the header name.","commonSituations":"Reverse proxies stripping the Authorization header; HTTP clients that send the header name with an empty value; code reading the wrong header name and getting null.","solutions":["Ensure the client sends 'Authorization: Basic <base64(user:pass)>' with a non-empty value","Check the server filter/extractor reads the correct header name","Return HTTP 401 to prompt the client to resend credentials instead of crashing on parse"],"exampleFix":"// before\nBasicAuthorizationHeader.fromStrings(request.getHeader(\"Auth\"));\n// after\nString h = request.getHeader(HttpHeaders.AUTHORIZATION);\nif (h == null || h.isBlank()) throw new NotAuthorizedException(\"Basic\");\nBasicAuthorizationHeader.fromString(h);","handlingStrategy":"validation","validationCode":"if (header == null || header.isBlank()) { throw new NotAuthorizedException(\"Basic realm=\\\"signal\\\"\"); }","typeGuard":null,"tryCatchPattern":"try { BasicAuthorizationHeader.fromString(header); } catch (InvalidAuthorizationHeaderException e) { throw new NotAuthorizedException(\"Basic\"); }","preventionTips":["Always check the raw Authorization header is non-blank before parsing","Configure HTTP clients to fail fast on empty auth credentials","Verify proxies do not strip Authorization"],"tags":["http-header","basic-auth","validation"],"backgroundTag":"empty-required-field","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}