Приглашаем посетить
Романтизм (19v-euro-lit.niv.ru)

Section 2.7.  Spoofed HTTP Requests

Previous
Table of Contents
Next

2.7. Spoofed HTTP Requests

A more sophisticated attack than spoofing forms is spoofing a raw HTTP request. This gives an attacker complete control and flexibility, and it further proves how no data provided by the user should be blindly trusted.

To demonstrate this, consider a form located at http://example.org/form.php:

    <form action="process.php" method="POST">
    <p>Please select a color:
    <select name="color">
      <option value="red">Red</option>
      <option value="green">Green</option>
      <option value="blue">Blue</option>
    </select><br />
    <input type="submit" value="Select" /></p>
    </form>

If a user chooses Red from the list and clicks Select, the browser sends an HTTP request:

    POST /process.php HTTP/1.1
    Host: example.org
    User-Agent: Mozilla/5.0 (X11; U; Linux i686)
    Referer: http://example.org/form.php
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 9

    color=red

Seeing that most browsers include the referring URL this way in the request, you may be tempted to write logic that checks $_SERVER['HTTP_REFERER'] to prevent form spoofing. This would indeed prevent an attack that is mounted with a standard browser, but an attacker is not necessarily hindered by such minor inconveniences. By modifying the raw HTTP request, an attacker has complete control over the value of HTTP headers, GET and POST data, and quite literally, everything within the HTTP request.

How can an attacker modify the raw HTTP request? The process is simple. Using the telnet utility available on most platforms, you can communicate directly with a remote web server by connecting to the port on which the web server is listening (typically port 80). The following is an example of manually requesting the front page of http://example.org/ using this technique:

    $ telnet example.org 80
    Trying 192.0.34.166...
    Connected to example.org (192.0.34.166).
    Escape character is '^]'.
    GET / HTTP/1.1
    Host: example.org

    HTTP/1.1 200 OK
    Date: Sat, 21 May 2005 12:34:56 GMT
    Server: Apache/1.3.31 (Unix)
    Accept-Ranges: bytes
    Content-Length: 410
    Connection: close
    Content-Type: text/html

    <html>
    <head>
    <title>Example Web Page</title>
    </head>
    <body>
    <p>You have reached this web page by typing &quot;example.com&quot;,
    &quot;example.net&quot;, or &quot;example.org&quot; into your web browser.</p>
    <p>These domain names are reserved for use in documentation and are not
    available for registration. See
    <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 2606</a>, Section
    3.</p>
    </body>
    </html>

    Connection closed by foreign host.
    $

The request shown is the simplest request possible with HTTP/1.1 because Host is a required header. The entire HTTP response appears on the screen as soon as you enter two newlines because this indicates the end of the request.

The telnet utility isn't the only way to communicate directly with a web server, but it's often the most convenient. However, if you make the same request with PHP, you can automate your experimentation. The previous request can be made with the following PHP code:

    <?php

    $http_response = '';

    $fp = fsockopen('example.org', 80);
    fputs($fp, "GET / HTTP/1.1\r\n");
    fputs($fp, "Host: example.org\r\n\r\n");

    while (!feof($fp))
    {
      $http_response .= fgets($fp, 128);
    }

    fclose($fp);

    echo nl2br(htmlentities($http_response, ENT_QUOTES, 'UTF-8'));

    ?>

There are, of course, multiple ways to do this, but the point is that HTTP is a well-known and open standardany moderately experienced attacker is going to be intimately familiar with the protocol and how to exploit common security mistakes.

As with spoofed forms, spoofed HTTP requests are not a concern. My reason for demonstrating these techniques is to better illustrate how easy it is for an attacker to provide malicious input to your applications. This should reinforce the importance of input filtering and the fact that nothing provided in an HTTP request can be trusted.


Previous
Table of Contents
Next