Vulnerability Description
In aiosend/webhook/base.py, the WebhookHandler.feed_update() method performs full deserialization of the incoming JSON via Pydantic before verifying the HMAC signature. Anyone can send a request with an arbitrary body — the server will parse it, spend CPU and memory, and only then reject it.
Vulnerable Code
# aiosend/webhook/base.py — feed_update()
update = Update.model_validate(body, context={"client": self}) # parsing — always
if not self._check_signature(body, headers): # auth — too late
return False
Additional aggravating factor: CryptoPayObject is declared with ConfigDict(extra="allow") — all arbitrary fields from the body are stored in memory without any limits.
Minimal PoC
Requests with deliberately invalid signatures (zero credentials):
| extra_fields |
body_size |
parse_time |
status |
| 0 |
336 B |
26 µs |
403 REJECTED |
| 1,000 |
82 KB |
257 µs |
403 REJECTED |
| 5,000 |
410 KB |
1,183 µs |
403 REJECTED |
| 10,000 |
820 KB |
2,552 µs |
403 REJECTED |
| 10,000 (×512B) |
5.3 MB |
7,490 µs |
403 REJECTED |
All requests were rejected — but the server already performed parsing for each one. 10 parallel threads with 5 MB bodies = >75 ms of CPU spent on requests that will never be authorized.
Affected Components
aiosend/webhook/base.py — WebhookHandler.feed_update()
aiosend/types/base.py — CryptoPayObject (extra="allow")
- All adapters:
AiohttpManager, FastAPIManager, FlaskManager
Exploitation Conditions
- Attacker: anyone with network access to the webhook endpoint
- Authentication: not required
- Body size limit: absent at the library level (Flask and FastAPI have no default limit)
The advisory was translated using Copilot.
References
Vulnerability Description
In
aiosend/webhook/base.py, theWebhookHandler.feed_update()method performs full deserialization of the incoming JSON via Pydantic before verifying the HMAC signature. Anyone can send a request with an arbitrary body — the server will parse it, spend CPU and memory, and only then reject it.Vulnerable Code
Additional aggravating factor:
CryptoPayObjectis declared withConfigDict(extra="allow")— all arbitrary fields from the body are stored in memory without any limits.Minimal PoC
Requests with deliberately invalid signatures (zero credentials):
All requests were rejected — but the server already performed parsing for each one. 10 parallel threads with 5 MB bodies = >75 ms of CPU spent on requests that will never be authorized.
Affected Components
aiosend/webhook/base.py—WebhookHandler.feed_update()aiosend/types/base.py—CryptoPayObject(extra="allow")AiohttpManager,FastAPIManager,FlaskManagerExploitation Conditions
The advisory was translated using Copilot.
References