| 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: 'TODO(https://go.dev/issue/56443): fill in summary field' |
| 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' |