HTTP Note #3: HTTP request message method (cont'd)

Method token (cont’d)

  • POST: 用于向指定的资源提交要被处理的数据,被设计用于实现如下功能:

    • 对现有资源的注释
    • 向电子公告栏、新闻组,邮件列表或类似讨论组发送消息
    • 提交数据块,如将表格(form)的结果提交给数据处理过程
    • 通过附加操作来扩展数据库

    POST 的数据实体与提交至的 URI 紧密相关,因为数据发送出去,需要服务端解析成功才有意义。且 POST 方法的响应是不可缓存的,因并没有办法知道服务器在未来的请求中将会如何回应,除非响应里有合适的 Cache-Control 或者 Expires 头域。

    响应状态码:

    • 200 (OK) or 204 (No Content): 执行的动作可能不会对 URI 指定的资源起作用
    • 201 (Created): 资源被服务器创建

    由于协议并没有规定 POST 数据必须使用什么编码方式,因此开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。而服务端通常是根据请求头中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。

    常用的编码方式:

    • application/x-www-form-urlencoded: 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以此方式提交数据。
    • multipart/form-data: 使用表单上传文件时,必须让 form 的 enctyped 等于这个值。
    • application/json: 非浏览器原生支持,但被广泛应用,方便提交复杂的结构化数据,特别适合 RESTful 的接口。
  • PUT: 允许客户端传送请求实体(最有可能是文件)存储至服务器特定的 URI 下。

    如果 URI 下已存在资源,那么 PUT 请求的实体应该被作为该资源的最新修改版本。否则服务器应该为其创建一个新资源。

    有可能返回的响应状态码:

    • 201 (Created):创建新资源
    • 200 (OK) or 204 (No Content):已修改已存在的资源
    • 501 (Not Implemented):
  • DELETE: 请求服务器删除 URI 指定的资源。

    当然,客户端发送请求就能删除服务器资源这件事儿比较危险,所以服务器可以干涉请求,即便返回了成功的状态码,也不能保证删除操作已经被执行。

    一条成功响应会返回:

    • 200 (OK):删除成功,同时返回描述该状态的实体
    • 202 (Accepted):请求已被接受,但删除该资源的操作还未被执行
    • 204 (No Content):删除资源操作已经执行,但响应中并无实体
  • TRACE: 让客户端测试到服务器的网络通路,使得服务器原样返回任何客户端请求的内容,主要用于测试和诊断。最后的接收者也许是源服务器,也许是接收到包含 Max-Forwards 头域值为 0 请求的代理或网关。TRACE 请求不可包含实体。

  • CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。这个方法的作用就是把服务器作为跳板,让服务器代替用户去访问其它网页,之后把数据原原本本的返回给用户。

关于测试

对于以上几个方法,自己测试了许多网址,除了毫无疑问肯定成功的 POST 方法,其他都失败了。很容易明白是因为安全性的问题,服务器不太可能支持 PUT & DELETE( 但是 REST Web Services 有可能根据自己的需求支持这两个方法 ),另外两种基本上不被支持的方法是 CONNECT & TRACE,具体见 OWASP 官方 wiki

  • PUT: This method allows a client to upload new files on the web server. An attacker can exploit it by uploading malicious files (e.g.: an asp file that executes commands by invoking cmd.exe), or by simply using the victim’s server as a file repository
  • DELETE: This method allows a client to delete a file on the web server. An attacker can exploit it as a very simple and direct way to deface a web site or to mount a DoS attack
  • CONNECT: This method could allow a client to use the web server as a proxy
  • TRACE: This method simply echoes back to the client whatever string has been sent to the server, and is used mainly for debugging purposes. This method, originally assumed harmless, can be used to mount an attack known as Cross Site Tracing, which has been discovered by Jeremiah Grossman (see links at the bottom of the page)

拓展

何为 XST (Cross Site Tracing)?

要理解 XST,首先需要知道何为 XSS:

XSS (Cross Site Scripting) 是最普遍的 web 应用安全漏洞。当应用程序发送给浏览器的页面中包含用户提供的数据,而这些数据没有经过适当的验证或转义(escape),就会导致跨站脚本漏洞。

» 参考 2013 OWASP Top 10 中文版

比如一个典型的 XSS 攻击如:

    http://www.example.com/search.php?query=<script>alert(document.cookie)</script>

当 query 数据没有经过正确转义时,这段脚本就会被执行,所以浏览器会弹出窗口显示当前 cookie。现在为止,虽然有不安全因素,但是这段脚本还是无害的,cookie 尚未被利用。

大概了解了 XSS 后,重新回到 XST。一句话概括 XST,就是利用 XSS 和 HTTP TRACE 方法的组合。当 attacker 知道某个网页服务器支持 TRACE 方法,他/她就会非常开心滴把脚本改成这样:

 <script type="text/javascript">
 var x = new ActiveXObject("Microsoft.XMLHTTP");
 // var x = new XMLHttpRequest();
 x.open("TRACE", "http://example.com",false);
 x.send();
 //x.send("");
 cookie=x.responseText;
 alert(cookie);
 </script>

然后,attacker 将这段恶意代码嵌入已经被其控制的主机上的 web 文件之中,当 victim 一个不小心点击并下载了这个 web 文件,这段代码就会在 victim 的浏览器中运行,并发送了一个 TRACE 请求至目标服务器。别忘了,这个 TRACE 请求的最后接收者很有可能是源服务器。于是,attacker 轻轻松松收到了 victim 的 cookie。

用图举栗子:

» 以上参考 Securing Apache, Part 4: Cross-site Tracing (XST) & Cross-site History Manipulation (XSHM)

URI & URL

» 参考 WIKIPEDIA

  • URI (Uniform Resource Identifier)

    标识网页资源的字符串

    • 通用文法

      <scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ]
      
    • URL 编码:也被称为百分号编码 (Percent-encoding),其字符集可分为

      • 保留字符:有时必须被编码,用 %(转义字符)加上其十六进制 ASCII 值,如下表第二行

          !	#	$	&	'	(	)	*	+	,	/	:	;	=	?	@	[	]
          %21	%23	%24	%26	%27	%28	%29	%2A	%2B	%2C	%2F	%3A	%3B	%3D	%3F	%40	%5B	%5D
        
      • 非保留字符:无需被编码

          A	B	C	D	E	F	G	H	I	J	K	L	M	N	O	P	Q	R	S	T	U	V	W	X	Y	Z
          a	b	c	d	e	f	g	h	i	j	k	l	m	n	o	p	q	r	s	t	u	v	w	x	y	z
          0	1	2	3	4	5	6	7	8	9	-	_	.	~
        
  • URL (Uniform / Universal Resource Locator)

    URL 是一种 URI,由于其经常被用于标识网络资源,因此一个典型的 URL 形如:

    http://en.example.org/wiki/Main_Page
    

    URL 格式在 URI 文法基础上有些微扩展,主要部分是在 <hierarchical part>,该部分需要写上 domain name 和 file path,因此要用斜杠 & 双斜杠将目录分隔开:

    scheme://domain:port/path?query_string#fragment_id
    
  • 二者关系:URL ∈ URI

    更确切地说 URI 的分类如下图所示: 其中,URN (Uniform resource name) (一个典型的 URN 实现是用于标识唯一书目的 ISBN 体系)如同一个人的名字,而 URL 如同一个人的地址。


问题

  • URL 的编码格式采用的是 ASCII 码,也就意味着不能在 URL 中包含任何非 ASCII 字符,例如中文。那么比如在 google 中输入“中文”,其 URL 为:

    https://www.google.com.hk/#q=%E4%B8%AD%E6%96%87&safe=strict
    

    q 的 key-value 对中的值就能将中文编码,这是为什么呢?

    自问自答:

    其实该 URL 还是遵循着百分号编码,由于 RFC 1738 并没有规定中文的编码方法,而是交给应用程序(浏览器)自己决定,通常情况下,浏览器会使用 UTF-8 编码。“中文” 的 UTF-8 值为 E4B8AD E69687,因此 URL 编码过后变成 %E4%B8%AD%E6%96%87。


计划

Status Code 看起来 ~ 这一部分自己已经好奇很久了。