Boa Web Server缺陷报告及其修正方法
作者:网络转载 发布时间:[ 2015/1/16 13:52:20 ] 推荐标签:软件测试管理 缺陷管理
综述
Boa 作为一种轻巧实用的 WEB 服务器广泛应用于嵌入式设备上,
但 Boa 对实现动态网页的 CGI 的支持上仍存在一些缺陷,
本文描述了 Boa 对 CGI 的 Status/Location 的支持的缺陷及其修正方法.
版本: 所有版本 (0.94.13)
缺陷: BOA 解析 CGI 应答头时不能完整处理 Status 和 Location
缺陷描述:
CGI/1.1 标准规定, CGI 脚本可以通过 Status 设置 HTTP 应答状态(如, Status: 500 Internal Error) 和
Location 进行地址重定向 (如, Location: www.xxx.com), 而不管它们在应答头中的位置.
Boa 支持 Stauts 和 Location 两种应答头, 但它的实现仅能正确处理 Stauts 和 Location 在应答第一行的
CGI 应答. 这将给 CGI 程序的移植带来很多不便, 进而影响 Boa 作为Web Server 的功能的发挥.
影响功能:
ASP/PHP/JSP/Perl/... 等的 header, redirect, ... 等都会应用到 Stauts/Location 进行设置应答状态和
地址重定向. Boa 的该实现将影响 CGI 脚本正常功能的使用.
缺陷功能对比(对Status/Location的支持程序):
Apache 1.3.x/2.x IIS 4.x/5.x/6.X Boa 0.9x thttpd mini-httpd
完全支持 完全支持 * 部分支持 完全支持 完全支持
缺陷分析
缺陷分析
CGI 应用程序进行应答时, 可以 HTTP 头进行有限的控制. 如,设置客户端不缓存页面可用下面的 C 脚本,
HTTP/1.0: printf("Pragma: no-cache
"); 或
HTTP/1.1: printf("Cache-Control: no-cache; no-store
");
如果, 同时还需要告诉浏览器进行设置 Cookie 和控制相应状态(200 OK) 或地址重定向,
那么必须输出多行 http 头控制语句, CGI 支持两个解析头 "Status: " 和 "Loction: ",
即协议规定, Web 服务器支持解析头时能使用 "Status: " 进行应答状态控制, 使用 "Location: " 进行地址重定向,
并为应答添加状态头 "HTTP/1.0 302 Moved Temporarily
" 或 "HTTP/1.1 302 Found
".
而不管它们在 CGI 应答头的什么位置.
分析 Boa Source Code:
cgi_header.c Line 82-136 容易发现, Boa 只解析 CGI 应答的第一行, 是否为 "Status: ", "Location: ", 如下所示
23
24 int process_cgi_header(request * req)
25 {
26 char *buf;
27 char *c;
28
29 if (req->cgi_status != CGI_DONE)
30 req->cgi_status = CGI_BUFFER;
31
32 buf = req->header_line;
33
34 c = strstr(buf, "
");
35 if (c == NULL) {
36 c = strstr(buf, "
");
37 if (c == NULL) {
38 log_error_time();
39 fputs("cgi_header: unable to find LFLF
", stderr);
40 #ifdef FASCIST_LOGGING
41 log_error_time();
42 fprintf(stderr, ""%s"
", buf);
43 #endif
44 send_r_bad_gateway(req);
45 return 0;
46 }
47 }
48 if (req->simple) {
49 if (*(c + 1) == '
')
50 req->header_line = c + 2;
51 else
52 req->header_line = c + 1;
53 return 1;
54 }
55 if (!strncasecmp(buf, "Status: ", 8)) {
56 req->header_line--;
57 memcpy(req->header_line, "HTTP/1.0 ", 9);
58 } else if (!strncasecmp(buf, "Location: ", 10)) { /* got a location header */
59 #ifdef FASCIST_LOGGING
60
61 log_error_time();
62 fprintf(stderr, "%s:%d - found Location header "%s"
",
63 __FILE__, __LINE__, buf + 10);
64 #endif
65
66
67 if (buf[10] == '/') { /* virtual path */
68 log_error_time();
69 fprintf(stderr,
70 "server does not support internal redirection: "
71 ""%s"
", buf + 10);
72 send_r_bad_request(req);
73
74 /*
75 * We (I, Jon) have declined to support absolute-path parsing
76 * because I see it as a major security hole.
77 * Location: /etc/passwd or Location: /etc/shadow is not funny.
78 *
79 * Also, the below code is borked.
80 * request_uri could contain /cgi-bin/bob/extra_path
81 */
82
83 /*
84 strcpy(req->request_uri, buf + 10);
85 return internal_redirect(req);
86 */
87 } else { /* URL */
88 char *c2;
89 c2 = strchr(buf + 10, '
');
90 /* c2 cannot ever equal NULL here because we already have found one */
91
92 --c2;
93 while (*c2 == '
')
94 --c2;
95 ++c2;
96 /* c2 now points to a '
' or the '
' */
97 *c2++ = '