GHSA-7M8F-HGJQ-8GC9

Vulnerability from github – Published: 2026-05-22 17:27 – Updated: 2026-05-22 17:27
VLAI
Summary
aiosend: Deserialization of request body before signature verification (Pre-auth DoS) in webhook handler
Details

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.pyWebhookHandler.feed_update()
  • aiosend/types/base.pyCryptoPayObject (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.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "aiosend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.0.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-22T17:27:56Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "# Vulnerability Description\n\nIn `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 \u2014 the server will parse it, spend CPU and memory, and only then reject it.\n\n## Vulnerable Code\n\n```python\n# aiosend/webhook/base.py \u2014 feed_update()\nupdate = Update.model_validate(body, context={\"client\": self})  #  parsing \u2014 always\nif not self._check_signature(body, headers):                    #  auth \u2014 too late\n    return False\n```\n\nAdditional aggravating factor: `CryptoPayObject` is declared with `ConfigDict(extra=\"allow\")` \u2014 all arbitrary fields from the body are stored in memory without any limits.\n\n## Minimal PoC\n\nRequests with deliberately invalid signatures (zero credentials):\n\n| extra_fields | body_size | parse_time | status |\n|---|---|---|---|\n| 0 | 336 B | 26 \u00b5s | **403 REJECTED** |\n| 1,000 | 82 KB | 257 \u00b5s | **403 REJECTED** |\n| 5,000 | 410 KB | 1,183 \u00b5s | **403 REJECTED** |\n| 10,000 | 820 KB | 2,552 \u00b5s | **403 REJECTED** |\n| 10,000 (\u00d7512B) | 5.3 MB | 7,490 \u00b5s | **403 REJECTED** |\n\nAll requests were rejected \u2014 but the server already performed parsing for each one. 10 parallel threads with 5 MB bodies = \u003e75 ms of CPU spent on requests that will never be authorized.\n\n## Affected Components\n\n- `aiosend/webhook/base.py` \u2014 `WebhookHandler.feed_update()`\n- `aiosend/types/base.py` \u2014 `CryptoPayObject` (`extra=\"allow\"`)\n- All adapters: `AiohttpManager`, `FastAPIManager`, `FlaskManager`\n\n## Exploitation Conditions\n\n- **Attacker**: anyone with network access to the webhook endpoint\n- **Authentication**: not required\n- **Body size limit**: absent at the library level (Flask and FastAPI have no default limit)\n\n---\nThe advisory was translated using Copilot.",
  "id": "GHSA-7m8f-hgjq-8gc9",
  "modified": "2026-05-22T17:27:56Z",
  "published": "2026-05-22T17:27:56Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/vovchic17/aiosend/security/advisories/GHSA-7m8f-hgjq-8gc9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/vovchic17/aiosend"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "aiosend: Deserialization of request body before signature verification (Pre-auth DoS) in webhook handler"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…