{"id":15660499,"url":"https://github.com/nickstenning/nginx-multiauth","last_synced_at":"2025-05-05T21:13:20.362Z","repository":{"id":19270174,"uuid":"22506535","full_name":"nickstenning/nginx-multiauth","owner":"nickstenning","description":"I am a terrible person.","archived":false,"fork":false,"pushed_at":"2014-08-01T12:33:56.000Z","size":151,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-05T21:13:15.052Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickstenning.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-01T11:19:13.000Z","updated_at":"2021-06-28T13:43:00.000Z","dependencies_parsed_at":"2022-07-27T00:16:11.493Z","dependency_job_id":null,"html_url":"https://github.com/nickstenning/nginx-multiauth","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickstenning%2Fnginx-multiauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickstenning%2Fnginx-multiauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickstenning%2Fnginx-multiauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickstenning%2Fnginx-multiauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickstenning","download_url":"https://codeload.github.com/nickstenning/nginx-multiauth/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252577022,"owners_count":21770721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T13:22:01.846Z","updated_at":"2025-05-05T21:13:20.336Z","avatar_url":"https://github.com/nickstenning.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"Hi. You look like a nice person.\n\nYou should probably leave. Seriously, you don't want to read this. Turn around.\n\nReally.\n\nIf you're still here, you're probably one of those people drawn inextricably to\ntechnological disasters because you want to understand exactly what set of\ncircumstances conspired to balance that train carriage perfectly on end atop the\npink Mini Cooper. Do you work in operations, by any chance?\n\nAnyway, this is a small experiment to discover if it is possible to host an API\nwhich requires bearer token auth, supplied in the HTTP \"Authorization\" header,\nbehind HTTP Basic authentication provided by nginx.\n\nWhy is this a problem? Well, because the standard mechanism for doing bearer\ntoken auth is to require the provision of a request header like\n\n    Authorization: Bearer abcdef123\n\nBut HTTP Basic authentication says that you should send\n\n    Authorization: Basic Zm9vOmJhcg==\n\nwhere the gibberish on the right hand side is\n\n    b64encode(username + \":\" + password)\n\nNow, this wouldn't be a problem but for two things:\n\n1. The specs (RFC2616, RFC2617) aren't clear on whether multiple Authorization\n   headers are allowed. In practice, nginx will reject a request with multiple\n   Authorization headers with an HTTP 400 (Bad Request).\n\n2. The \"Authorization\" header has no normative form, as far as I can tell. There\n   is no specified mechanism for providing multiple claims for auth in a single\n   header.\n\nWe would appear to have arrived at an impasse, except for the fact that nginx\n(at least the version I'm testing with, 1.4.6) appears to *ignore* trailing data\nat the end of a valid HTTP Basic auth header. That is, if\n\n    Authorization: Basic Zm9vOmJhcg==\n\nwill allow you through nginx's auth check, then so will\n\n    Authorization: Basic Zm9vOmJhcg== More Data!\n\nand even\n\n    Authorization: Basic Zm9vOmJhcg==AllKindsOfGibberish\n\nThis is, without question, a slightly worrying feature. But hey, it helps us\nwith our original problem. The solution is in sight! Simply ask nginx to strip\noff the start of the authorization header when passing a request upstream,\nleaving only that part of the Authorization header it doesn't know what to do\nwith:\n\n    map $http_authorization $auth_passthru {\n      default \"\";\n      \"~Basic \\S+\\s+(?P\u003cauthsuffix\u003e.+)$\" \"$authsuffix\";\n    }\n\nThis declaration makes nginx define a new variable, $auth_passthru, which\ncontains nothing if there is no trailing data on the Authorization header, or if\nthere is no Authorization header at all, but which contains only the trailing\ndata (after any whitespace) otherwise.\n\nSo, make a request with\n\n    Authorization: Basic Zm9vOmJhcg==, Bearer abcdef123\n\nand the proxy will see\n\n    Authorization: Bearer abcdef123\n\nBeautiful!\n\nBut seriously? Don't do this.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickstenning%2Fnginx-multiauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickstenning%2Fnginx-multiauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickstenning%2Fnginx-multiauth/lists"}