1.4 HTTP请求
客户端和服务器端之间关于“如何处理HTTP消息”的协议包括定义请求方法。请求方法指示了客户端请求的目的及客户端期望的成功结果。例如,在列表1-1中,我们向http://www.google.com/发送GET请求,暗示我们只期待返回http://www.google.com/网页的内容,无须执行其他操作。开发和实现请求方法是为了区分被调用的操作,因为互联网被设计成远程计算机之间的接口。
HTTP标准定义了以下请求方法:GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT和OPTIONS(PATCH在HTTP RFC中也有提到,但并不常用)。在撰写本书时,浏览器只会使用HTML发送GET和POST请求。任何PUT、PATCH或DELETE请求都是JavaScript调用HTTP请求的结果。在本书后面,当考虑应用程序中的漏洞示例时,应想到这些方法。
下面将简要介绍请求方法。
1.请求方法
GET方法通过请求统一资源标识符(URI)标识信息。URI通常与统一资源定位器(URL)一起使用。严格地说,URL是一种定义资源的URI类型,它包括通过网络位置来定位该资源的方法。例如,http://www.google.com/<example>/file.txt和/<example>/file.txt都是有效的URI,但是只有http://www.google.com/<example>/file.txt是有效的URL,因为它标识了如何通过域名http://www.google.com定位资源。尽管有细微差别,但整本书中在引用任何资源标识符时都使用URL。
虽然无法强制执行此要求,但GET请求不会更改数据,而只从服务器端检索数据并在HTTP消息体中返回内容。例如,在一个社交媒体网站上,GET请求只会返回你的配置文件名,却不会更新你的配置文件。这种行为对于第4章中讨论的跨站点请求伪造(CSRF)漏洞至关重要。访问任何URL或网站链接(除非由JavaScript调用),浏览器都会向目标服务器发送GET请求。这种特性对于第2章中讨论的开放重定向漏洞至关重要。
HEAD方法与GET方法相同,只是服务器不能在响应中返回消息体。
POST方法由服务器决定调用接收服务器上的某些函数。换句话说,其通常会执行某种类型的后端操作,例如创建评论、注册用户、删除账户等。服务器响应POST所执行的操作可能会有所不同。服务器有时可能根本不会返回响应。例如,POST请求可能会导致处理请求时发生错误,并且不会在服务器上保存记录。
PUT方法调用一些引用远程网站或应用程序上已存在的记录的函数。例如,在更新已存在的账户、博客文章或其他内容时可能会使用它。同样,执行的操作可能会有所不同,并可能导致服务器根本不执行任何操作。
DELETE方法请求远程服务器删除用URI标识的远程资源。
TRACE方法是另一种不常见的方法,用于将请求消息返回给请求者。它允许请求者查看服务器接收到的内容,并使用这些信息来测试和收集诊断信息。
被保留的CONNECT方法用于代理服务器。代理服务器可将请求转发到其他服务器。此方法可以启动与所请求资源的双向通信。例如,CONNECT方法可以通过代理访问HTTPS的网站。
OPTIONS方法从服务器请求有关可用通信选项的信息。例如,通过调用OPTIONS可以确定服务器是否接受GET、POST、PUT、DELETE和OPTIONS调用。此方法不会指示服务器是否接受HEAD或TRACE调用。浏览器会自动为特定的内容类型(如application/json)发送这种类型的请求。这种方法称为“飞行前的OPTIONS调用”(preflight OPTIONS call),我们将在第4章中更深入地讨论这种方法,因为它起到了CSRF漏洞保护的作用。
2.HTTP是无状态的
HTTP请求是无状态的,这意味着发送到服务器的每个请求都被视为一个全新的请求。服务器在接收请求时并不知道它以前与浏览器的通信。这对大多数网站来说都是一个问题,因为网站要记住你是谁。否则,每次发送HTTP请求时你都必须重新输入用户名和密码。这也意味着处理HTTP请求所需的所有数据都必须与客户端发送到服务器的每个请求一起重新加载。
为了解释这个令人困惑的内容,思考一下这样一个例子:如果你我之间有一个无状态的对话,在讲每一句话之前,我必须从“我是彼得·亚沃斯基,刚才讨论的是黑客攻击”开始。然后你必须重新载入我们讨论的关于黑客攻击的所有信息。想想在电影《初恋50次》中Henry Roth每天早上都为Lucy Whitmore做些什么(如果你没看过这部电影,你应该去看一看)。
为了避免每次发送HTTP请求时都必须重新发送用户名和密码,网站使用了cookie或基本身份验证,我们将在第4章详细讨论。
注意:使用base64对内容进行编码的细节超出了本书的范围,但在渗透时,你可能会遇到base64编码的内容。如果是这样,你应该解码该内容。搜索“base64解码”,你会找到大量的工具和方法来实现这一点。