60

How can I test for HTTP TRACE on my web-server?

I need to train a Tester how to verify that the HTTP TRACE method is disabled.

Ideally I need a script to paste into Firebug to initiate a https connection to return the web server response to a HTTP TRACE command.

Background:

Our security Pen Testers identified a HTTP TRACE vulerability and we need to prove that it is fixed.

References:

AviD
  • 72,138
  • 22
  • 136
  • 218
Andrew Russell
  • 3,633
  • 1
  • 20
  • 29

7 Answers7

63

Simplest way I can think of is using cURL (which is scriptable).

 curl -v -X TRACE http://www.yourserver.com

Running it against an Apache server with TraceEnable Off correctly returns HTTP/1.1 405 Method Not Allowed (just tested on an Apache 2.2.22)

This also works on HTTPS sites, provided that cURL has the correct information supplied to the SSL layer. This is the lazy man's check of Google

curl --insecure -v -X TRACE https://www.google.com/

...it negotiates the connection (does not verify the certificate chain, but that's not the issue here since we want to check on TRACE status), and responds 405:

* Server certificate:
*        subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*        start date: 2013-02-20 13:34:56 GMT
*        expire date: 2013-06-07 19:43:27 GMT
*        subjectAltName: www.google.com matched
*        issuer: C=US; O=Google Inc; CN=Google Internet Authority
*        SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> TRACE / HTTP/1.1
> User-Agent: curl/7.25.0 (x86_64-suse-linux-gnu) libcurl/7.25.0 OpenSSL/1.0.1c zlib/1.2.7 libidn/1.25 libssh2/1.4.0
> Host: www.google.com
> Accept: */*

< HTTP/1.1 405 Method Not Allowed
LSerni
  • 22,521
  • 4
  • 51
  • 60
  • While probably being the simplest solution over plain HTTP, this doesn't work over HTTPS. – Gurzo Feb 28 '13 at 06:02
  • I've tried with Google (trace disabled) and another server (trace enabled) and it seems to work to me. Updating answer... – LSerni Feb 28 '13 at 09:59
  • 2
    Thanks everyone for the great answers, but this answer was the most user friendly of the lot. – Andrew Russell Mar 01 '13 at 01:21
  • I was getting **Empty reply from server** when running this remotely. SSHing into the server and doing `curl -v -X TRACE http://127.0.0.1` worked for me. – storm_m2138 Sep 14 '18 at 22:21
6

There are two ways:

STEP 1: openssl s_client -connect example.com:443

STEP2 :

TRACE / HTTP/1.1
host: example.com

(press enter twice)

or

OPTIONS / HTTP/1.1
host: example.com

(press enter twice) (you might need to paste these rapidly so copy paste them rather by typing out) STEP 3: Verify if the output, it should give error 400 if I'm not mistaking.

Another tool you can use is gnutls.

Lucas Kauffman
  • 54,169
  • 17
  • 112
  • 196
  • 1
    If they aren't using HTTPS, you can replace your step 1 (`openssl s_client -connect example.com:443`) with `telnet example.com 80`. – dr jimbob Feb 28 '13 at 01:41
  • On Unix these send LF for line terminator not CRLF as specified by 1945/2068/2616/7230 and _might_ be rejected, ignored, or handled differently by a server; to be safe use `s_client` with `-crlf` or redirect the input from a file created with `unix2dos` or ctl-V ctl-M or equivalents, or a pipeline that uses e.g. `printf '%s\r\n' "GET / HTTP/1.1" "Host: whatever" ""` – dave_thompson_085 Aug 11 '21 at 01:26
5

You could use a proxy, like Burp Suite or Zap, and follow some simple steps:

  1. set up your browser to pass through the chosen proxy;
  2. make a normal HTTP request (e.g. GET /index.php HTTP/1.1) and intercept it;
  3. change the HTTP method to TRACE and send the request to the server;
  4. check the HTTP response.

If the response includes the whole request, then TRACE is enabled and working properly.

Gurzo
  • 1,117
  • 6
  • 18
4

What everyone else said was accurate as far as sending the test however no one has given a correct identification for whether it's vulnerable. Different servers will respond differently, not to mention any mod rewrites on a TRACE/TRACK request. There are two ways of identifying both the TRACE and TRACK vulnerabilities which seem to work without giving false positives or false negatives (that i've been made aware of).

1) The target returns any status code < 400 or >= 600

2) The target returns the headers which you passed in.

Eric
  • 451
  • 2
  • 4
3

It can be done using netcat

nc www.myhost.com 80
TRACE /mypage.html HTTP/1.1
Host: www.myhost.com

An example of output is

HTTP/1.1 405 Method Not Allowed
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1
Set-Cookie: JSESSIONID=rfyji7QBFFld7HwMGLVM+F8s.undefined; Path=/
Content-Type: text/html;charset=utf-8
Content-Length: 1125
Date: Fri, 06 Mar 2015 06:06:29 GMT
Anonymous Platypus
  • 1,392
  • 3
  • 18
  • 33
2

I appreciate all the great answers provided by the skilled users of the website. I saw your questions reference and you mentioned about OWASP. I'm considering you are familar with the use of owasp and esp owasp live cd.

CAL9000. The tool has a http request field actually its more then a field its allow the custom generation of entire http header. You can select trace define the header options and simply click go. The response would be seen in the text below.

The reason I would recommend this tool more then the other, is this tool is provided by a community which is more reversed in concepts of application security then any other. These tools are tested and verified by experts. More info owasp ref

ALTERNATE METHOD

http://yehg.net/pentest/CAL9000/#httpRequests

its an online version of the tool.

NOTE ON TRACE

Firefox does not currently support the TRACE function (via xmlHttpRequest). CAL9000 gets the TRACE info from a server-side script. Also, a reminder that any request directed at a resource (http://www.blah.com/index.html) is not necessarily going to generate the same response as one directed at a directory (http://www.blah.com/js/), even though they are on the same site.

Saladin
  • 1,547
  • 3
  • 14
  • 23
1

Use Python

>>> from requests import request
>>> method_list = ['get', 'post', 'trace']
>>> for method in method_list:
...     req = request(method, 'http://example.com')
...     print(method, req.status_code, req.reason)
... 
get 200 OK
post 200 OK
trace 405 Method Not Allowed
>>> 

As you can see trace is not allowed for example.com

Wolf
  • 347
  • 2
  • 3
  • 15