| 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 |