Search code examples
nginxloggingrate-limiting

Hide password query param from Nginx error_log


I use Oauth2 password grant to generate access tokens for my clients. That means the user's password is sent as a query param:

example.com/oauth/token?grant_type=password&username=MyUsername&password=MyPassword

I use the following log_filter in order to mask the password for authentication attempts from the Nginx access_log:

http {
    log_format hide_password '$remote_addr $remote_user [$time_local] "$request_without_password" $status $body_bytes_sent "$http_referer" "$http_user_agent"';

    ...

    server {
        set $request_without_password $request;
        if ($request_without_password ~ (.*)password=[^&]*(.*)) {
            set $request_without_password $1password=****$2;
        }
        access_log /var/log/nginx/access.log hide_password;

        ....
    }
}

I have now introduced rate limiting using Nginx's limit_req. All rate limited requests are logged to the Nginx error_log. The problem is that It does not seem possible to use a log_filter on the error_log, meaning a rate limited authentication request will be logged with the user's password visible, which of course is unacceptable. Since I want to keep track of rate limited requests, I don't want to disable the error_log.

Is there a way to log rate limited requests in Nginx without the password visible as a query param?


Solution

  • It does not mean that the password needs to be sent as a query parameter, and the password should not be sent as a query parameter. The values should be sent in the body, exactly as it is specified in the Oauth protocol:

    The client makes a request to the token endpoint by adding the
    following parameters using the "application/x-www-form-urlencoded"
    format per Appendix B with a character encoding of UTF-8 in the HTTP
    request entity-body:

    grant_type REQUIRED. Value MUST be set to "password".

    username REQUIRED. The resource owner username.

    password REQUIRED. The resource owner password.

    scope OPTIONAL. The scope of the access request as described by Section 3.3.

    See also the example in the same section of the Oauth specification:

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded
    
     grant_type=password&username=johndoe&password=A3ddj3w
    

    So, follow the standard -- don't put it in the query parameter, and you don't have this problem.