HTTP 请求欺骗

一个更加强大,但是不太方便的方法是伪造 HTTP 请求。在前面讨论的表单例子中,当用户选择了颜色,HTTP 请求的结果应当如下所示(假设选择了 red):

        POST /process.php HTTP/1.1
        Host: example.org
        Content-Type: application/x-www-form-urlencoded
        Content-Length: 9

        color=red
    

telnet 工具可以用于执行类似的测试。下面的例子简单演示了用 GET 请求 http://www.php.net/

        $ telnet www.php.net 80
        Trying 64.246.30.37...
        Connected to rs1.php.net.
        Escape character is '^]'.
        GET / HTTP/1.1
        Host: www.php.net

        HTTP/1.1 200 OK
        Date: Wed, 21 May 2004 12:34:56 GMT
        Server: Apache/1.3.26 (Unix) mod_gzip/1.3.26.1a PHP/4.3.3-dev
        X-Powered-By: PHP/4.3.3-dev
        Last-Modified: Wed, 21 May 2004 12:34:56 GMT
        Content-language: en
        Set-Cookie: COUNTRY=USA%2C12.34.56.78; expires=Wed,28-May-04 12:34:56 GMT; path=/; domain=.php.net
        Connection: close
        Transfer-Encoding: chunked
        Content-Type: text/html;charset=ISO-8859-1

        2083
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN">
        ...
    

当然,可以编写自己的客户端代替在 telnet 中手工输入请求。下面的例子演示了如何用 PHP 工造类似的请求。

        <?php

        $http_response = '';

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

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

        fclose($fp);

        echo nl2br(htmlentities($http_response));

        ?>
    

构造自己的 HTTP 请求带来了相当的灵活性,这也说明为什么服务器端数据过滤显得如此必要。没有服务器端数据过滤的话,任何来自外部的数据都是没有保证的。