【HTTP协议】multipart/form-data与application-x-www-form-urlencoded

作者 Yuppie001
作者主页 传送
本文专栏 Web漏洞篇
🌟🌟🌟🌟🌟🌟🌟🌟

  在 HTTP 协议的 POST 请求中,提交参数和文件至服务器时,会使用不同的字段值。Content-Type 字段的 application/x-www-form-urlencodedmultipart/form-data 是两种常见的表单编码类型。


application/x-www-form-urlencoded

  • 这种编码方式将所有的表单数据编码为一个 URL 编码后的字符串。表单字段名和值会被序列化为 key1=value1&key2=value2 的格式,并且特殊字符会被编码(比如空格会被编码为 +,& 和 = 会被编码为 %26 和 %3D 等等)。
  • 适用于普通的键值对数据传输,不适合上传文件。
  • 适合用于小量数据提交和不需要文件上传的情况。

数据包如下:

POST /submit HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Referer: http://example.com/form
Origin: http://example.com

field1=value1&field2=value2


multipart/form-data

  • 这种编码方式将每个表单字段分开处理,每个字段都包含在一个独立的部分(part)中。每个部分都有自己的内容类型(Content-Type),如果上传的是文件,还会包含文件的文件名。
  • 适用于包含文件上传的表单和混合提交文本和二进制数据,因为它能携带二进制数据。

  这里所说的“能携带二进制数据”是指 multipart/form-data 编码能够处理和传输非文本数据,如图像、音频、视频、PDF 文件等。这些文件内容并不需要进行特殊编码,可以直接在请求体中传输。这使得它非常适合用于文件上传和其他需要传输非文本数据的场景

以下是一个文件上传数据包的例子:

POST /file/upload.php HTTP/1.1
Host: 192.168.58.130
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------121362204533093779961666926442
Content-Length: (根据body计算)
Origin: http://192.168.58.130
Connection: close
Referer: http://192.168.58.130/file/upload.php
Upgrade-Insecure-Requests: 1

-----------------------------121362204533093779961666926442
Content-Disposition: form-data; name="upload"; filename="随便写写.txt"
Content-Type: text/plain

这是我上传的文字:你好!
-----------------------------121362204533093779961666926442--

分析与解释
Content-Type
  首先,Content-Type 的内容变为了 multipart/form-data; boundary=---------------------------121362204533093779961666926442。分号前指定了本次请求的内容类型是 multipart/form-data,后面的 boundary 定义了请求体中的分界线。boundary 用于分隔每一块内容,确保上传的文件内容与其他 POST 数据互不干扰。

Body结构
  boundary 分界线后的第一行通常是 Content-Disposition 头。其值包含 form-data,表示这是表单数据。后面是 name 属性,指定了传输的参数名。如果是文件上传,还会有 filename 属性,指明上传的文件名。

文件上传
  在文件上传部分,Content-Disposition 头中除了 name 属性外,还包含 filename 属性。紧跟其后的是 Content-Type 头,用于指定文件的 MIME 类型。

多部分数据提交

  虽然 multipart/form-data 类型主要用于文件上传但它也可以用于提交多个数据块,包括普通表单字段和文件。要区分文件和普通表单字段,可以检查 Content-Disposition 头中是否包含 filename 属性。如果存在 filename 属性,则该部分为文件上传;否则为普通表单字段。

这里以传输了包含多种类型数据的表单举例:

<form action="/submit" method="post" enctype="multipart/form-data">
  <input type="text" name="username">
  <input type="password" name="password">
  <textarea name="description"></textarea>
  <input type="submit">
</form>

在这种情况下,提交的表单数据可能会被编码为:

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="username"

example_user
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="password"

example_password
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="description"

This is an example description.
------WebKitFormBoundary7MA4YWxkTrZu0gW--

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值