6

Apache 2 by default logs the entire request URI including query string of every request.

What is a straight forward way to prevent an Apache 2 web server from logging sensitive data, for example passwords, credit card numbers, etc., but still log the rest of the request?

I would like to log all log-in attempts including the attempted username as Apache does by default, and prevent Apache from logging the password directly.

I have looked through the Apache 2 documentation and there doesn't appear to be an easy way to do this other than completely preventing logging of these requests (using SetEnvIf).

How can I accomplish this?

4 Answers 4

6

Apache 2 by default logs the entire request URI including query string of every request.

What is a straight forward way to prevent an Apache 2 web server from logging sensitive data, for example passwords, credit card numbers, etc., but still log the rest of the request?

Am I reading right, that you are sending sensitive information in URI as QueryString ? I would suggest changing the application so it does do so in the first place.

Then, there would be no requirement to change apache, since, it does not do any such thing by default.

1
  • 12
    I don't believe this really answers the question. Whilst the advice is sound, "you're doing it wrong" is not a complete answer and it's wrong to assume that the question is posed through ignorance rather than through necessity (e.g. maybe jstr does not have any control over the applications / design and is simply trying to implement a better logging practice for them as a responsible sysadmin). Sep 6, 2016 at 10:37
16

You can mask the passwords before they end up in access.log by combining a CustomLog directive with a bit of sed magic (as instructed in https://stackoverflow.com/a/9473943/102170):

This would replace every occurrence of password=secret with password=[FILTERED] in /your/path/access.log:

CustomLog "|/bin/sed -u -E s/'param=[^& \t\n]*'/'param=\[FILTERED\]'/g >> /your/path/access.log" combined

That being said, it would be best to avoid putting sensitive data in the query strings if possible.

3
  • 1
    Good answer - sometimes passing sensitive info in the URL is necessary, such as if you must use JSONP results. An SSL connection will still encrypt that entire URL, but the query must be sanitized before logging.
    – Matt H
    Feb 21, 2014 at 20:13
  • 2
    Great Solution. Thanks for it. I found that sed does not flush the logs immediately , initially I thought that log was not written but when I reloaded Apache Service, I could see the logs. So I solved the flush issue by adding '-u' switch. CustomLog "|/bin/sed -u -E s/'param=[^& \t\n]*'/'param=[FILTERED]'/g >> /your/path/access.log" combined
    – user322604
    Nov 17, 2015 at 4:19
  • our access log file is generated by this line in apache config, "CustomLog "|/usr/sbin/cronolog -z EST -H /opt/cc/logs/my-access_current /opt/cc/logs/my-access.%Y-%m-%d-00_00_00.log" common env=!dontlog". And I cannot connect sed command to the cronolog command, before or after. If I just echo a line as outputted by apache and pipe through my sed command, it works.
    – gigi2
    Mar 7 at 20:04
3

You read up on the difference between GET and POST and rewrite your applications to stop putting passwords and info in GET parameters.

1

You may modify some request parameters during the log phase with LuaHookLog (mod_lua). Although the request line (%r in the 'combined' log format) is read-only, you may mask query string directly, and then fine-tune all your log formats to use it. To mask password=XXX in the query string do the following:

  1. Create /etc/apache2/log_mask.lua:

    function log_mask_password(r)
      if r.args then
        r.args = r.args:gsub("([pP][aA][sS][sS][wW][oO][rR][dD])=[^&=]*(&?)", "%1=XXX%2")
      end
      return apache2.OK
    end
    
  2. enable mod_lua in apache with a2enmod lua

  3. set up lua log hook somewhere in your apache config:

    <IfModule lua_module>
        LuaHookLog /etc/apache2/log_mask.lua log_mask_password
    </IfModule>
    
  4. fix your LogFormat to use "%m %U%q %H" instead of "%r". e.g.:

    LogFormat "%a %l %u %t \"%m %U%q %H\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
    

Don't forget to fix all your other log formats too to prevent password leak in all of them!

Also, you can just do return apache2.DONE in lua code to drop the log message completely (this would be another code with some if and sensitive data pattern matching).

Warning: It is not recommended that you use lua module on a server that is shared with users you do not trust (and who has permissions to modify apache config files), as it can be abused to change the internal workings of httpd.

1
  • This seems to be a standard Apache tool that addresses the issue being asked about by the OP. Thank you for posting this!
    – gillytech
    Apr 20, 2020 at 22:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .