Summary
Host-only cookies that are saved with CookieJar.save() and then restored later with CookieJar.load() lose their host-only status.
Impact
Host-only cookies that have been loaded from disk may get sent to subdomains that previously should have been disallowed.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/a329a7aacad5284f087af36103aff778746da0f2
Summary
An unbounded DNS cache could result in excessive memory usage possibly resulting in a DoS situation.
Impact
If an application makes requests to a very large number of hosts, this could cause the DNS cache to continue growing and slowly use excessive amounts of memory.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/c4d77c3533122be353b8afca8e8675e3b4cbda98
Summary
When following redirects to a different origin, aiohttp drops the Authorization header, but retains the Cookie and Proxy-Authorization headers.
Impact
The Cookie and Proxy-Authorizations headers could contain sensitive information which may be leaked to an unintended party after following a redirect.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/5351c980dcec7ad385730efdf4e1f4338b24fdb6
Summary
The C parser (the default for most installs) accepted null bytes and control characters is response headers.
Impact
An attacker could send header values that are interpreted differently than expected due to the presence of control characters. For example, request.url.origin() may return a different value than the raw Host header, or what a reverse proxy interpreted it as., potentially resulting in some kind of security bypass.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/9370b9714a7a56003cacd31a9b4ae16eab109ba4
Summary A zip bomb can be used to execute a DoS against the aiohttp server.
Impact An attacker may be able to send a compressed request that when decompressed by aiohttp could exhaust the host's memory.
------
Patch: https://github.com/aio-libs/aiohttp/commit/2b920c39002cee0ec5b402581779bbaaf7c9138a
Summary The Python HTTP parser may allow a request smuggling attack with the presence of non-ASCII characters.
Impact If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or AIOHTTPNOEXTENSIONS is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections.
------
Patch: https://github.com/aio-libs/aiohttp/commit/32677f2adfd907420c078dda6b79225c6f4ebce0
Summary
The parser allows non-ASCII decimals to be present in the Range header.
Impact
There is no known impact, but there is the possibility that there's a method to exploit a request smuggling vulnerability.
----
Patch: https://github.com/aio-libs/aiohttp/commit/c7b7a044f88c71cefda95ec75cdcfaa4792b3b96
Summary When assert statements are bypassed, an infinite loop can occur, resulting in a DoS attack when processing a POST body.
Impact If optimisations are enabled (-O or PYTHONOPTIMIZE=1), and the application includes a handler that uses the Request.post() method, then an attacker may be able to execute a DoS attack with a specially crafted message.
------
Patch: https://github.com/aio-libs/aiohttp/commit/bc1319ec3cbff9438a758951a30907b072561259
Summary A request can be crafted in such a way that an aiohttp server's memory fills up uncontrollably during processing.
Impact If an application includes a handler that uses the Request.post() method, an attacker may be able to freeze the server by exhausting the memory.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/b7dbd35375aedbcd712cbae8ad513d56d11cce60
Summary
Handling of chunked messages can result in excessive blocking CPU usage when receiving a large number of chunks.
Impact
If an application makes use of the request.read() method in an endpoint, it may be possible for an attacker to cause the server to spend a moderate amount of blocking CPU time (e.g. 1 second) while processing the request. This could potentially lead to DoS as the server would be unable to handle other requests during that time.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/dc3170b56904bdf814228fae70a5501a42a6c712 Patch: https://github.com/aio-libs/aiohttp/commit/4ed97a4e46eaf61bd0f05063245f613469700229
Summary Reading multiple invalid cookies can lead to a logging storm.
Impact If the cookies attribute is accessed in an application, then an attacker may be able to trigger a storm of warning-level logs using a specially crafted Cookie header.
----
Patch: https://github.com/aio-libs/aiohttp/commit/64629a0834f94e46d9881f4e99c41a137e1f3326
Summary
Insufficient restrictions in header/trailer handling could cause uncapped memory usage.
Impact
An application could cause memory exhaustion when receiving an attacker controlled request or response. A vulnerable web application could mitigate these risks with a typical reverse proxy configuration.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/0c2e9da51126238a421568eb7c5b53e5b5d17b36
Summary Improperly configuring static resource resolution in aiohttp when used as a web server can result in the unauthorized reading of arbitrary files on the system.
Details When using aiohttp as a web server and configuring static routes, it is necessary to specify the root path for static files. Additionally, the option 'followsymlinks' can be used to determine whether to follow symbolic links outside the static root directory. When 'followsymlinks' is set to True, there is no validation to check if a given file path is within the root directory.This can lead to directory traversal vulnerabilities, resulting in unauthorized access to arbitrary files on the system, even when symlinks are not present.
i.e. An application is only vulnerable with setup code like: app.router.addroutes([ web.static("/static", "static/", followsymlinks=True), # Remove followsymlinks to avoid the vulnerability ])
Impact This is a directory traversal vulnerability with CWE ID 22. When using aiohttp as a web server and enabling static resource resolution with followsymlinks set to True, it can lead to this vulnerability. This vulnerability has been present since the introduction of the followsymlinks parameter.
Workaround Even if upgrading to a patched version of aiohttp, we recommend following these steps regardless.
If using followsymlinks=True outside of a restricted local development environment, disable the option immediately. This option is NOT needed to follow symlinks which point to a location within the static root directory, it is only intended to allow a symlink to break out of the static directory. Even with this CVE fixed, there is still a substantial risk of misconfiguration when using this option on a server that accepts requests from remote users.
Additionally, aiohttp has always recommended using a reverse proxy server (such as nginx) to handle static resources and not to use these static resources in aiohttp for production environments. Doing so also protects against this vulnerability, and is why we expect the number of affected users to be very low.
-----
Patch: https://github.com/aio-libs/aiohttp/pull/8079/files
Summary
A response with an excessive number of multipart headers may be allowed to use more memory than intended, potentially allowing a DoS vulnerability.
Impact
Multipart headers were not subject to the same size restrictions in place for normal headers, potentially allowing substantially more data to be loaded into memory than intended. However, other restrictions in place limit the impact of this vulnerability.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/8a74257b3804c9aac0bf644af93070f68f6c5a6f
Summary
An attacker who controls the reason parameter when creating a Response may be able to inject extra headers or similar exploits.
Impact
In the unlikely situation that an application allows untrusted data to be used in the response's reason parameter, then an attacker could manipulate the response to send something different from what the developer intended.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/53b35a2f8869c37a133e60bf1a82a1c01642ba2b
Summary
For some multipart form fields, aiohttp read the entire field into memory before checking clientmaxsize.
Impact
If an application uses Request.post() an attacker can send a specially crafted multipart request to force significant temporary memory allocation even when the request is ultimately rejected.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/cbb774f38330563422ca0c413a71021d7b944145
Summary
An attacker who controls the contenttype parameter in aiohttp could use this to inject extra headers or similar exploits.
Impact
If an application allows untrusted data to be used for the multipart contenttype parameter when constructing a request, an attacker may be able to manipulate the request to send something other than what the developer intended.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/9a6ada97e2c6cf1ce31727c6c9fcea17c21f6f06
Summary
On Windows the static resource handler may expose information about a NTLMv2 remote path.
Impact
If an application is running on Windows, and using aiohttp's static resource handler (not recommended in production), then it may be possible for an attacker to extract the hash from an NTLMv2 path and then extract the user's credentials from there.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/0ae2aa076c84573df83fc1fdc39eec0f5862fe3d
Summary
Multiple Host headers were allowed in aiohttp.
Impact
Mostly this doesn't affect aiohttp security itself, but if a reverse proxy is applying security rules depending on the target Host, it is theoretically possible that the proxy and aiohttp could process different host names, possibly resulting in bypassing a security check on the proxy and getting a request processed by aiohttp in a privileged sub app when using Application.adddomain().
-----
Patch: https://github.com/aio-libs/aiohttp/commit/e00ca3cca92c465c7913c4beb763a72da9ed8349 Patch: https://github.com/aio-libs/aiohttp/commit/53e2e6fc58b89c6185be7820bd2c9f40216b3000
Summary Path normalization for static files prevents path traversal, but opens up the ability for an attacker to ascertain the existence of absolute path components.
Impact If an application uses web.static() (not recommended for production deployments), it may be possible for an attacker to ascertain the existence of path components.
------
Patch: https://github.com/aio-libs/aiohttp/commit/f2a86fd5ac0383000d1715afddfa704413f0711e
Summary Security-sensitive parts of the Python HTTP parser retained minor differences in allowable character sets, that must trigger error handling to robustly match frame boundaries of proxies in order to protect against injection of additional requests. Additionally, validation could trigger exceptions that were not handled consistently with processing of other malformed input.
Details These problems are rooted in pattern matching protocol elements, previously improved by PR #3235 and GHSA-gfw2-4jvh-wgfg:
1. The expression HTTP/(\d).(\d) lacked another backslash to clarify that the separator should be a literal dot, not just any Unicode code point (result: HTTP/(\d)\.(\d)).
2. The HTTP version was permitting Unicode digits, where only ASCII digits are standards-compliant.
3. Distinct regular expressions for validating HTTP Method and Header field names were used - though both should (at least) apply the common restrictions of rfc9110 token.
PoC GET / HTTP/1ö1 GET / HTTP/1.𝟙 GET/: HTTP/1.1 Content-Encoding?: chunked
Impact Primarily concerns running an aiohttp server without llhttp: 1. behind a proxy: Being more lenient than internet standards require could, depending on deployment environment, assist in request smuggling. 2. directly accessible or exposed behind proxies relaying malformed input: the unhandled exception could cause excessive resource consumption on the application server and/or its logging facilities.
-----
Patch: https://github.com/aio-libs/aiohttp/pull/8074/files
Summary
A memory leak can occur when a request produces a MatchInfoError. This was caused by adding an entry to a cache on each request, due to the building of each MatchInfoError producing a unique cache entry.
Impact
If the user is making use of any middlewares with aiohttp.web then it is advisable to upgrade immediately.
An attacker may be able to exhaust the memory resources of a server by sending a substantial number (100,000s to millions) of such requests.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/bc15db61615079d1b6327ba42c682f758fa96936
Summary The Python parser parses newlines in chunk extensions incorrectly which can lead to request smuggling vulnerabilities under certain conditions.
Impact If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or AIOHTTPNOEXTENSIONS is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/259edc369075de63e6f3a4eaade058c62af0df71
Summary Static routes which contain files with compressed variants (.gz or .br extension) were vulnerable to path traversal outside the root directory if those variants are symbolic links.
Details The server protects static routes from path traversal outside the root directory when followsymlinks=False (default). It does this by resolving the requested URL to an absolute path and then checking that path relative to the root. However, these checks are not performed when looking for compressed variants in the FileResponse class, and symbolic links are then automatically followed when performing Path.stat() and Path.open() to send the file.
Impact Servers with static routes that contain compressed variants as symbolic links, pointing outside the root directory, or that permit users to upload or create such links, are impacted.
----
Patch: https://github.com/aio-libs/aiohttp/pull/8653/files
Summary
A XSS vulnerability exists on index pages for static file handling.
Details
When using web.static(..., showindex=True), the resulting index pages do not escape file names.
If users can upload files with arbitrary filenames to the static directory, the server is vulnerable to XSS attacks.
Workaround
We have always recommended using a reverse proxy server (e.g. nginx) for serving static files. Users following the recommendation are unaffected.
Other users can disable showindex if unable to upgrade.
-----
Patch: https://github.com/aio-libs/aiohttp/pull/8319/files
Summary An attacker can send a specially crafted POST (multipart/form-data) request. When the aiohttp server processes it, the server will enter an infinite loop and be unable to process any further requests.
Impact An attacker can stop the application from serving requests after sending a single request.
-------
For anyone needing to patch older versions of aiohttp, the minimum diff needed to resolve the issue is (located in readchunkfromlength()):
diff diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py index 227be605c..71fc2654a 100644 --- a/aiohttp/multipart.py +++ b/aiohttp/multipart.py @@ -338,6 +338,8 @@ class BodyPartReader: assert self.length is not None, "Content-Length required for chunked read" chunksize = min(size, self.length - self.readbytes) chunk = await self.content.read(chunksize) + if self.content.ateof(): + self.ateof = True return chunk async def readchunkfromstream(self, size: int) -> bytes:
This does however introduce some very minor issues with handling form data. So, if possible, it would be recommended to also backport the changes in: https://github.com/aio-libs/aiohttp/commit/cebe526b9c34dc3a3da9140409db63014bc4cf19 https://github.com/aio-libs/aiohttp/commit/7eecdff163ccf029fbb1ddc9de4169d4aaeb6597 https://github.com/aio-libs/aiohttp/commit/f21c6f2ca512a026ce7f0f6c6311f62d6a638866
Summary
If an attacker sends large incomplete websocket frame payloads, it may be possible to bypass the usual size limits on memory use.
Impact
If a web application has WebSocket endpoints, it may be possible for an attacker to execute a DoS attack through excessive memory use.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/14b6ee851fb16ec199acb950de0c82d476799e7d
Summary The Python parser is vulnerable to a request smuggling vulnerability due to not parsing trailer sections of an HTTP request.
Impact If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or AIOHTTPNOEXTENSIONS is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections.
----
Patch: https://github.com/aio-libs/aiohttp/commit/e8d774f635dc6d1cd3174d0e38891da5de0e2b6a
Summary
An attacker can exhaust file descriptors with specially crafted multipart requests.
Impact
If a handler uses Request.post(), it may be possible for an attacker to use an unlimited number of file descriptors, potentially resulting in resource exhaustion.
Summary
DigestAuthMiddleware can send an authentication response after following a cross-origin redirect.
Impact
If the client follows a redirect (the default option) to an attacker controlled domain, the attacker may be able to extract the auth digest.
This likely requires an open redirect vulnerability or similar on the target domain for an attacker to be able to execute. Further, the attacker is only receiving the digest, so should only be able to extract the user's credentials if the cryptography is weak or there is some kind of password reuse.
Workaround
Disable followredirects if this is a concern.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/38d16060037e1bfcd6d677abababa3c2a4bb58fa