Disable Trace and Track for Better Security

Posted on September 6, 2009 in Function by

The shared server on which I host Perishable Press was recently scanned by security software that revealed a significant security risk. Namely, the HTTP request methods TRACE and TRACK were found to be enabled on my webserver. The TRACE and TRACK protocols are HTTP methods used in the debugging of webserver connections.

Although these methods are useful for legitimate purposes, they may compromise the security of your server by enabling cross-site scripting attacks (XST). By exploiting certain browser vulnerabilities, an attacker may manipulate the TRACE and TRACK methods to intercept your visitors’ sensitive data. The solution, of course, is disable these methods on your webserver.

How to disable the TRACE and TRACK methods

To disable TRACE and TRACK HTTP methods on your Apache-powered webserver, add the following directives to either your main configuration file or root HTAccess file:

RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]

These directives disable the TRACE and TRACK methods via the following process:

  • RewriteEngine on — enables Apache’s rewrite module (this directive is not required if already present in your htaccess file)
  • RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) — targets all TRACE and TRACK request methods for the following rule
  • RewriteRule .* - [F] — return a 403 Forbidden error response for all matched conditions (i.e., all TRACE and TRACK methods)

With these rules in place, your site is protected against one more potential security vulnerability :)

Related articles

26 Responses

  1. [ Gravatar Icon ] Dean says:

    Hey Jeff,

    Is the below code best practice for .htaccess files?

    RewriteEngine on
    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
    RewriteRule .* - [F]

    Regards,

    - Dean (Sydney, Australia)

  2. [ Gravatar Icon ] Jeff Starr says:

    Hi Dean,

    As far as I know.. I certainly try to post only “best-practice” code, but I have been known to make mistakes, from time to time. Is there something specific that causes you to question?

  3. [ Gravatar Icon ] Rick Beckman says:

    Hey, Jeff, thanks for the code. I’m running on Dreamhost, and they provide the ability to have an account-wide .htaccess file — an .htaccess file that is processed for every domain on a user’s account — and some things work in this file, others don’t.

    This code at least doesn’t crash my site — some perfectly valid code, when used in the account-wide file, does crash things — but I’m not sure if it’s actually working.

    Do you know of a way to test those request methods against a site?

  4. [ Gravatar Icon ] Rick Beckman says:

    Oh, never mind, I’m just dense. I tested it by adding in the GET method as well. It didn’t block requests, so I’ll have to do this the long way, adding to each of my domain’s .htaccess files.

    Here’s a request: Work up a tutorial on how to modify one .htaccess file and have it reflected across as many other files as desired (via Shell/cron/whatever), making sure that site-specific code (such as WP’s permalink code) isn’t touched. So, for example, a “# Account-wide declarations” block could be copied to each file automatically. That sure would be handy!

  5. [ Gravatar Icon ] duck says:

    How do you check whether TRACE and TRACK are enabled or disabled?

  6. I recommend to add DELETE to the list:

    RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK)

  7. [ Gravatar Icon ] Jeff Starr says:

    @Rick: Good idea, but remember that .htaccess functions in cascading fashion, such that placing any directives in your root directory will — unless told otherwise — be applied to all subsequent subdirectories.

    @duck: You could either ask your host or telnet to your domain with the following commands:

    TRACE / HTTP/1.1 [enter]
    Host: yourdomain.tld [enter]
    [enter]

    The first line of the result will be the response code.

    @Thomas: Good call. I will update the article.

  8. [ Gravatar Icon ] Rick Beckman says:

    I know that, Jeff. What I’d like to be able to do is apply a variety of security functions to all of my domains (each reside in its own directory within my home directory), and manually updating each domain’s .htaccess to account for new security rules is tedious. Being able to update them all in one go would be awesome.

  9. [ Gravatar Icon ] Jeff Starr says:

    Ah, gotcha. On some server setups you can apply .htaccess directives to directories above the web root. So for example, if you have the following directory tree:

    home
           public_html
                  domain1
                  domain2
                  domain3
                  domain4
                  domain5

    You would simply create an .htaccess file in your /home/ or /public_html/ directory to have it’s rules applied to all subdirectories (i.e., your different domains).

    Alternately, if you have access to your server configuration file, you could place your directives there and have them applied to everything in one fell swoop.

  10. [ Gravatar Icon ] Rick Beckman says:

    I can create such an .htaccess file — it works with the allow/deny rules and various other things, but mod_rewrite doesn’t work for it.

    And unfortunately, on Dreamhost regular hosting, no access to real config files. :S

  11. [ Gravatar Icon ] Jeff Starr says:

    Okay, one more thing to try that may help. Many shared hosts have their accounts setup with a primary domain, which is generally the one specified during account creation. In many cases, the root folder for the primary domain is the /public_html/ (or equivalent) directory itself, such that its .htaccess file applies to all domains.

    I’m guessing that you may have already tried this, but if not, mod_rewrite should work in the .htaccess file of that directory.

    Otherwise, a script that updates server-wide .htaccess files would be difficult to create, especially because you only want to target the .htaccess files in each root directory. This is certainly possible with even PHP or something, however it would require your .htaccess files to be writable, which may not be the best strategy.

  12. [ Gravatar Icon ] Rick Beckman says:

    Nah, there isn’t a primary domain. The structure of my account looks like this when I log in via FTP:

    /

    domain.com
    domain2.com
    domain3.com

    Each individual domain’s folder is the root folder for that domain (i.e., there isn’t a child public_html/ or www/ or anything of that nature), and each domain’s folder (and all subsequent children) can have fully-functional .htaccess files.

    The / directory itself, though, is a bit limited. It’s above the Web root, so mod_rewrite doesn’t seem to work — either that’s the reason, or it just isn’t enabled that high up.

    I do, however, maintain all of my configuration files (wp-config.php files, for example) in the / directory, so what I may end up doing is writing a security PHP script that checks user-agents, IPs, requests, and so on. Then all I’d need to do is include it at the top of the wp-config.php file.

    That method likely won’t be *as* quick as .htaccess (and definitely not as quick as the http.conf file), but it will be slightly quicker than maintaining it all as an actual WordPress plugin as the included security file would launch almost immediately on page access.

    That’ll be a stop-gap. I’m going to look at how WordPress generates .htaccess rules, modifying.htaccess files in such a way as to not modify any other custom-added content… I might be able to write a PHP script that, when one, copies one .htaccess file to as many others as I want.

    By default on my server, PHP can modify just about any files — I rarely have to CHMOD anything — and whether that’s a bad thing or not, I dunno. It is danged convenient for me, though. If I ever get something workable, I’ll share the code.

  13. [ Gravatar Icon ] Jeff Starr says:

    Yes, definitely share the code if you end up with something. If I had the time, I would try to script something that did the job, but my free time is unbelievably scarce these days. It is difficult to choose among the many opportunities and possibilities that are available on the Web. If only I could clone myself..

  14. Looks like this is in the 4G Blacklist. I just checked my .htaccess file and there it was. Cool.

    Thanks - sent out a tweet.

  15. [ Gravatar Icon ] Jordan Ogren says:

    I have the following in my .htaccess from the 4G Blacklist:

    # FILTER REQUEST METHODS
    <IfModule mod_rewrite.c>
     RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC]
     RewriteRule ^(.*)$ - [F,L]
    </IfModule>

    I am assuming, like John Hoff, that this has me covered. Am I correct?

  16. [ Gravatar Icon ] Jeff Starr says:

    Hi John, yep the 4G Blacklist includes these directives, so you’re covered. Thanks for the tweet :)

    Hi Jordan, yes you are good to go. The reason for this article was to help those who may not have the 4G installed.

  17. Jordan, remove HEAD from your list. This is a Good Thing.

    Let’s say, someone checks the links on his website to find and remove outdated URLs: His script will use HEAD to verify that the linked pages are still there. If your response code isn’t 200 the link will probably be removed.

    Forbidding HEAD means forbidding links from well maintained web sites.

  18. [ Gravatar Icon ] Jeff Starr says:

    I may have to agree with Thomas here. The HEAD request method was blocked in the 4G Blacklist to help thwart referrer spam and other malicious exploits. At the time, there seemed to be no benefits to keeping the HEAD method, so it was blocked.

    With Thomas’ hypothetical link-checking scenario, there may be reason to permit HEAD requests after all. This was something that I hadn’t thought of, but it certainly seems like a valid scenario. I will probably remove the HEAD block from the next, 5G Blacklist.

    In this case, I think the pros of allowing outweigh the pros of blocking.

  19. [ Gravatar Icon ] Jordan Ogren says:

    @Jeff and @Thomas,

    Thanks guys, I really appreciate your shared knowledge.

  20. [ Gravatar Icon ] Greg says:

    Pretty agree with Thomas too, for the HEAD.
    But HEAD can also help to find the server version, if the owner set the server signature off.

  21. [ Gravatar Icon ] Nan says:

    Hi Jeff! I would like to add this to my htaccess:

    # FILTER REQUEST METHODS

    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
    RewriteRule ^(.*)$ - [F,L]

    But I have already:

    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    # END WordPress

    Can I have 2 or 3 different in the same htaccess?

    Also, you say to put: RewriteRule .* - [F] and Jordan put: RewriteRule ^(.*)$ - [F,L] So what does the L stand for? Should I put it or not?

    Thank you so much for your tips!!

  22. [ Gravatar Icon ] Jeff Starr says:

    Hi Nan, you can definitely add multiple blocks of HTAccess code into the same .htaccess file. It should work perfectly fine.

    For the [L] flag, it simply means that the rule is the “Last” rule for that particular set of directives. This is one way of keeping the different rulesets separate and distinct from one another.

    So yes, if you have multiple sets of rules, as in your case, you would want to include the [L] flag to keep everything distinct.

    I hope this helps!

  23. [ Gravatar Icon ] Abraham says:

    Limiting the allowed HTTP methods is great, but I think a whitelist approach is better :

    RewriteCond %{REQUEST_METHOD} !^(HEAD|OPTIONS|GET|POST)$ [NC]
    RewriteRule .* - [F,L]

    If a developer then specifically requires another method in his program (eg. PUT), deliberate action is required to enable it, which he should only take if he understands the need and implications.

  24. [ Gravatar Icon ] Abraham says:

    I ran some tests on (the servers of) my preferred hosting provider, and discovered that the TRACE method still isn’t being disabled, even though a whitelist approach disables everything else (except the whitelisted methods of course)!!

    I’ve contacted them about it but thought I’d leave a comment here just to remind everyone to test (any and all) code once it’s in place, to make sure the code does what it’s supposed to!

    Hope it helps someone.

  25. [ Gravatar Icon ] Jeff Starr says:

    Thanks for the information, Abraham – it definitely helps :)

  26. [ Gravatar Icon ] C0nw0nk says:

    Did you guys know if you have root access to your servers you can disable trace with a command.

    TraceEnable Off

    Thought i would just share it with you incase you are not aware.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Please use basic markup. Wrap code with <code> tags!