See how aiohttp compares to other vendors in security performance
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
Using CookieJar.load() with untrusted input may allow arbitrary code execution.
Impact
Most applications using this function will be doing so with the user's own data, so this is unlikely to affect many applications.
Workaround
If an application does allow attacker controlled files to be loaded, a workaround on older releases would be to sanitise the files before loading.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/dcf40f30637e8752c76781cf6703b5a236749a00
Impact
aiohttp v3.8.4 and earlier are bundled with llhttp v6.0.6 which is vulnerable to CVE-2023-30589. The vulnerable code is used by aiohttp for its HTTP request parser when available which is the default case when installing from a wheel.
This vulnerability only affects users of aiohttp as an HTTP server (ie aiohttp.Application), you are not affected by this vulnerability if you are using aiohttp as an HTTP client library (ie aiohttp.ClientSession).
Reproducer
python from aiohttp import web
async def example(request: web.Request): headers = dict(request.headers) body = await request.content.read() return web.Response(text=f"headers: {headers} body: {body}")
app = web.Application() app.addroutes([web.post('/', example)]) web.runapp(app)
Sending a crafted HTTP request will cause the server to misinterpret one of the HTTP header values leading to HTTP request smuggling.
console $ printf "POST / HTTP/1.1\r\nHost: localhost:8080\r\nX-Abc: \rxTransfer-Encoding: chunked\r\n\r\n1\r\nA\r\n0\r\n\r\n" \ | nc localhost 8080
Expected output: headers: {'Host': 'localhost:8080', 'X-Abc': '\rxTransfer-Encoding: chunked'} body: b''
Actual output (note that 'Transfer-Encoding: chunked' is an HTTP header now and body is treated differently) headers: {'Host': 'localhost:8080', 'X-Abc': '', 'Transfer-Encoding': 'chunked'} body: b'A'
Patches
Upgrade to the latest version of aiohttp to resolve this vulnerability. It has been fixed in v3.8.5: pip install aiohttp >= 3.8.5
Workarounds
If you aren't able to upgrade you can reinstall aiohttp using AIOHTTPNOEXTENSIONS=1 as an environment variable to disable the llhttp HTTP request parser implementation. The pure Python implementation isn't vulnerable to request smuggling:
console $ python -m pip uninstall --yes aiohttp $ AIOHTTPNOEXTENSIONS=1 python -m pip install --no-binary=aiohttp --no-cache aiohttp
References
https://nvd.nist.gov/vuln/detail/CVE-2023-30589 https://hackerone.com/reports/2001873
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
aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. Prior to version 3.10.11, the Python parser parses newlines in chunk extensions incorrectly which can lead to request smuggling vulnerabilities under certain conditions. 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. Version 3.10.11 fixes the issue.
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 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 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
AIOHTTP is an asynchronous HTTP client/server framework for asyncio and Python. Prior to version 3.14.0, using CookieJar.load() with untrusted input may allow arbitrary code execution. Most applications using this function will be doing so with the user's own data, so this is unlikely to affect many applications. Version 3.14.0 patches the issue. If an application does allow attacker controlled files to be loaded, a workaround on older releases would be to sanitize the files before loading.
Summary
An out-of-bounds heap read could occur in the C response parser while building an error message for a malformed response.
Impact
An attacker controlled server, or possibly an accidental response could trigger a DoS in the client.
Workaround
If unable to upgrade, the Python parser is unaffected and can be used with AIOHTTPNOEXTENSIONS=1.
---
Patch: https://github.com/aio-libs/aiohttp/commit/49f65d54150397892f7bcc4aae887767d51c322d
Summary
The client accepts and decompresses frames with the RSV1 bit set even when the permessage-deflate extension was not negotiated.
Impact
A client may unexpectedly decompress WebSocket frames when explicitly opted out. This could lead to additional CPU/memory consumption, but is unlikely to be a significant issue unless a zip bomb vulnerability or similar is also present.
---
Patch: https://github.com/aio-libs/aiohttp/commit/47fb6ae354d4fa22048f4dbe7dbf82b625f0a2f6
Summary
Cookies set with the cookies parameter on requests are sent after following a cross-origin redirect.
Impact
If a developer uses the cookies parameter on a per-request basis then sensitive data might be leaked to an attacker if they manage to control a redirect.
Workaround
If unable to upgrade, using a Cookie header in the headers parameter is not vulnerable.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/f54c40851b0d6c4bbdab97ba518a223adda32478
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 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 Improper validation makes it possible for an attacker to modify the HTTP request (e.g. insert a new header) or even create a new HTTP request if the attacker controls the HTTP method.
Details The vulnerability occurs only if the attacker can control the HTTP method (GET, POST etc.) of the request.
Previous releases performed no validation on the provided value. If an attacker controls the HTTP method it will be used as is and can lead to HTTP request smuggling.
PoC A minimal example can be found here: https://gist.github.com/jnovikov/7f411ae9fe6a9a7804cf162a3bdbb44b
Impact If the attacker can control the HTTP version of the request it will be able to modify the request (request smuggling).
Workaround If unable to upgrade and using user-provided values for the request method, perform manual validation of the user value (e.g. by restricting it to a few known values like GET, POST etc.).
Patch: https://github.com/aio-libs/aiohttp/pull/7806/files
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
Summary
It is possible to bypass the maxlinesize check in parts of an HTTP request in the C parser.
Impact
If using the optimised C parser (the default in pre-built wheels), then an attacker may be able to send oversized lines through the HTTP parser and use an excessive amount of memory, potentially leading to DoS.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/5ab61bb4cd88f19b712f12c7c9295fe262bf804d
Summary
Attacker-controlled input included into multipart/payload headers can be used to modify a request to inject additional headers or similar.
Impact
In the unlikely situation that an application is passing user-controlled strings into MultipartWriter.append(headers=...) or Payload.headers, then an attacker may be able to modify the request to inject headers or change the contents of the request.
Workaround
Sanitise such user input.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/bf88077ebb14f4c29924b8e8904cba20c55c28b8
Summary
No limit was present on the number of pipelined requests that could be queued.
Impact
An attacker may be able to use pipelined requests to use excessive amounts of memory, potentially leading to DoS.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/dfdfa9d5aad5d21f91c79fb2ceeba0f8046cb6cf
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 serverhostname TLS SNI check can be bypassed when an existing connection is reused.
Impact
If an application makes multiple requests to the same domain, but with different per-request serverhostname parameters, then the later calls may succeed by reusing the existing connection when they should have been rejected due to the TLS SNI check.
Workaround
Disable keepalive if you need to change the serverhostname check between requests.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0
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
Payload resources are not closed correctly when a client disconnects in the middle of a write.
Impact
If a payload is using an open file or similar limited resource, then an attacker may be able to cause resource starvation temporarily until garbage collection or similar closes the file.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/a762eda5242f6490d6ba667533193f8b473ad587
Summary
During cleanup it is possible for a compressed request body to be decompressed into memory in one chunk.
Impact
An attacker may be able to send a compressed payload in specific situations that could be decompressed into memory, potentially leading to DoS (a zip bomb edge case).
Workaround
Disable compression if unable to upgrade.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/4f7480e474cccc6a8cc2c92ad3f17a31dedf8232
Summary Improper validation make it possible for an attacker to modify the HTTP request (e.g. to insert a new header) or even create a new HTTP request if the attacker controls the HTTP version.
Details The vulnerability only occurs if the attacker can control the HTTP version of the request (including its type). For example if an unvalidated JSON value is used as a version and the attacker is then able to pass an array as the version parameter. Furthermore, the vulnerability only occurs when the Connection header is passed to the headers parameter.
At this point, the library will use the parsed value to create the request. If a list is passed, then it bypasses validation and it is possible to perform CRLF injection.
PoC The POC below shows an example of providing an unvalidated array as a version: https://gist.github.com/jnovikov/184afb593d9c2114d77f508e0ccd508e
Impact CRLF injection leading to Request Smuggling.
Workaround If these specific conditions are met and you are unable to upgrade, then validate the user input to the version parameter to ensure it is a str.
Patch: https://github.com/aio-libs/aiohttp/pull/7835/files
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
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 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
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