| id: GO-2023-1569 |
| modules: |
| - module: std |
| versions: |
| - fixed: 1.19.6 |
| - introduced: 1.20.0-0 |
| - fixed: 1.20.1 |
| vulnerable_at: 1.20.0 |
| packages: |
| - package: mime/multipart |
| symbols: |
| - Reader.ReadForm |
| summary: Excessive resource consumption in mime/multipart |
| description: |- |
| A denial of service is possible from excessive resource consumption in net/http |
| and mime/multipart. |
| |
| Multipart form parsing with mime/multipart.Reader.ReadForm can consume largely |
| unlimited amounts of memory and disk files. This also affects form parsing in |
| the net/http package with the Request methods FormFile, FormValue, |
| ParseMultipartForm, and PostFormValue. |
| |
| ReadForm takes a maxMemory parameter, and is documented as storing "up to |
| maxMemory bytes +10MB (reserved for non-file parts) in memory". File parts which |
| cannot be stored in memory are stored on disk in temporary files. The |
| unconfigurable 10MB reserved for non-file parts is excessively large and can |
| potentially open a denial of service vector on its own. However, ReadForm did |
| not properly account for all memory consumed by a parsed form, such as map entry |
| overhead, part names, and MIME headers, permitting a maliciously crafted form to |
| consume well over 10MB. In addition, ReadForm contained no limit on the number |
| of disk files created, permitting a relatively small request body to create a |
| large number of disk temporary files. |
| |
| With fix, ReadForm now properly accounts for various forms of memory overhead, |
| and should now stay within its documented limit of 10MB + maxMemory bytes of |
| memory consumption. Users should still be aware that this limit is high and may |
| still be hazardous. |
| |
| In addition, ReadForm now creates at most one on-disk temporary file, combining |
| multiple form parts into a single temporary file. The mime/multipart.File |
| interface type's documentation states, "If stored on disk, the File's underlying |
| concrete type will be an *os.File.". This is no longer the case when a form |
| contains more than one file part, due to this coalescing of parts into a single |
| file. The previous behavior of using distinct files for each form part may be |
| reenabled with the environment variable GODEBUG=multipartfiles=distinct. |
| |
| Users should be aware that multipart.ReadForm and the http.Request methods that |
| call it do not limit the amount of disk consumed by temporary files. Callers can |
| limit the size of form data with http.MaxBytesReader. |
| credits: |
| - Arpad Ryszka |
| - Jakob Ackermann (@das7pad) |
| references: |
| - report: https://go.dev/issue/58006 |
| - fix: https://go.dev/cl/468124 |
| - web: https://groups.google.com/g/golang-announce/c/V0aBFqaFs_E |
| cve_metadata: |
| id: CVE-2022-41725 |
| cwe: 'CWE-400: Uncontrolled Resource Consumption' |
| references: |
| - https://security.gentoo.org/glsa/202311-09 |
| review_status: REVIEWED |