TeslaGov / ngx-http-auth-jwt-module

Secure your NGINX locations with JWT
MIT License
308 stars 118 forks source link

Authorization header gets modified on proxy #105

Closed penumbra23 closed 11 months ago

penumbra23 commented 11 months ago

Description

When Nginx proxies the request to an upstream, the Authorization header gets modified.

Basically, if the request holds Authorization: Bearer ey... the server cuts the Bearer part, which is kinda odd if the upstream expects the Bearer. Imho, the request shouldn't be modified by the auth plugin.

Test case

Here's a Docker compose file to test it:

version: '3.7'

services:
  nginx:
    image: teslagovnginx:latest
    ports:
    - 8080:8080
    volumes:
    - ./key.pem:/app/keys/ssh-publickey
    - ./nginx_main.conf:/etc/nginx/nginx.conf
    - ./nginx.conf:/etc/nginx/conf.d/nginx.conf

  echo:
    image: jmalloc/echo-server

nginx_main.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log info;
pid        /var/run/nginx.pid;

load_module /usr/lib64/nginx/modules/ngx_http_auth_jwt_module.so;

events {
    worker_connections  1024;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  upstream_time  '$remote_addr $sent_http_x_userid [$time_local] "$request" '
          '$status $body_bytes_sent "$http_referer" '
          '"$http_user_agent" "$http_x_forwarded_for" '
          'rt="$request_time" uct="$upstream_connect_time" '
          'uht="$upstream_header_time" urt="$upstream_response_time" '
          '$sent_http_x_email';

  access_log  /var/log/nginx/access.log  upstream_time;

  sendfile        on;

  client_body_timeout 12;
  client_header_timeout 12;
  send_timeout 10;
  keepalive_timeout  30;

  client_body_buffer_size 10K;
  client_header_buffer_size 1k;

  proxy_set_header Host                  $host;
  proxy_set_header X-Forwarded-For       $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto     $scheme;
  proxy_set_header X-Forwarded-Server    $remote_addr;

  include /etc/nginx/conf.d/*.conf;
}

nginx.conf:

server {
    listen       8080;
    server_name  _;
    client_max_body_size 50m;

    location / {
        auth_jwt_enabled on;
        auth_jwt_location HEADER=Authorization;
        auth_jwt_algorithm RS256;
        auth_jwt_use_keyfile on;
        auth_jwt_keyfile_path "/app/keys/ssh-publickey";

        proxy_pass    http://echo:8080;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
    }
}

Then if you run: curl localhost:8080 -H 'Authorization: Bearer eyJhbGc...'

the response is:

GET / HTTP/1.0

Host: localhost
Accept: */*
Authorization: eyJhbGc...

Possible solution:

I've created a possible fix on my branch. It was editing the pointer value which is a string, which means it modifies the header value directly.

Let me know what you think.

JoshMcCullough commented 11 months ago

Good catch, will fix!

JoshMcCullough commented 11 months ago

@penumbra23 feel free to review the attached PR, then we'll get this merged and new binaries released.

penumbra23 commented 11 months ago

Tested it locally on your branch, works!