Open motoyasu-saburi opened 11 months ago
@motoyasu-saburi Hey, thank you so much for the update on the vulnerability! I'm a little bit busy with my new project at the moment but I can take a look on the fix next week. If you have time, please also feel free to send PR. For v2, bug fix (and others that are not feature updated) will always be supported.
I have contacted the maintainer several times and have not received a response in six months, so I will describe the details of the vulnerability here.
Summary
fuel (<= 2.3.1)
is vulnerable to "multipart/form-data Request tampering" caused by Content-Disposition filename lack of escaping. (fuel v3 is not affected)fuel
>core
>DataPart.kt
>[InlineDataPart, FileDataPart, BlobDataPart]
>contentDisposition
contains a vulnerability that allows the lack of escape filename.https://github.com/kittinunf/fuel/blob/105d3111d71623cb831af3f411ea253db766f369/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/DataPart.kt#L100
https://github.com/kittinunf/fuel/blob/105d3111d71623cb831af3f411ea253db766f369/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/DataPart.kt#L176
https://github.com/kittinunf/fuel/blob/105d3111d71623cb831af3f411ea253db766f369/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/DataPart.kt#L272
By exploiting this problem, the following attacks are possible
For example, this vulnerability can be exploited to generate the following Content-Disposition.
input filename:
generated header in multipart/form-data:
The tampering header
*.txt
to*.sh
.dummy=".txt"
) .The cause of this problem is the lack of escaping of the
"
(Double-Quote) character &CRLF (\r \n)
in Content-Disposition > filename.WhatWG's HTML spec has an escaping requirement. https://html.spec.whatwg.org/#multipart-form-data
On the other hand, there is no clear requirement in the RFC.
Since filename is a field that may reflect user input values as they are, it may be used in attacks. (For example, the value may be retrieved from a DB, or a parameter may be used directly.)
The
name
field is unaffected because it is often a fixed value specified by the developer.My calculations CVSS (v3):
However, I think is that this is a limited problem and an example of CVSS not matching the actual risk.
Comprehensive report on this issue:
https://gist.github.com/motoyasu-saburi/1b19ef18e96776fe90ba1b9f910fa714
Cause & Fix
As noted at the beginning of this section, encoding must be done as described in the HTML Spec.
https://html.spec.whatwg.org/#multipart-form-data
Therefore, it is recommended that Content-Disposition be modified by either of the following
e.g.
or
reference: Golang escape code:
https://github.com/golang/go/blob/561a5079057e3a660ab638e1ba957a96c4ff3fd1/src/mime/multipart/writer.go#L132-L136
PoC
Create Kotlin Project
Edit gradle file
Create dummy file
Create PoC code
Use a logging server of your choice, etc. (e.g. Python)
Run PoC code
View logging server
Request multipart/form-data > Part:
Impact
Attack Scenario:
For example, the following may be considered
Validation Bypass
Tampering with hidden requests
Reference:
Relate RFC: https://datatracker.ietf.org/doc/html/rfc2231 https://datatracker.ietf.org/doc/html/rfc2616 https://datatracker.ietf.org/doc/html/rfc5987 https://datatracker.ietf.org/doc/html/rfc6266 https://datatracker.ietf.org/doc/html/rfc7578 https://datatracker.ietf.org/doc/html/rfc8187
WhatWG HTML Spec > multipart/form-data escape requirements: https://html.spec.whatwg.org/#multipart-form-data
Golang Impliments: https://github.com/golang/go/blob/561a5079057e3a660ab638e1ba957a96c4ff3fd1/src/mime/multipart/writer.go#L132-L136
Symphony (PHP Webframework) Impliments: https://github.com/symfony/symfony/blob/123b1651c4a7e219ba59074441badfac65525efe/src/Symfony/Component/Mime/Header/ParameterizedHeader.php#L128-L133
Spring (Java Webframework) Impliments: https://github.com/spring-projects/spring-framework/blob/4cc91e46b210b4e4e7ed182f93994511391b54ed/spring-web/src/main/java/org/springframework/http/ContentDisposition.java#L259-L267
Similar problem with another HTTP Client:
OWASP ASVS v5 > Content-Disposition escape disscussion: https://github.com/OWASP/ASVS/issues/1390