Every CVE Search/ Get API key

CVE-2026-45395

Open WebUI: Missing `workspace.tools` Authorization Check on Tool Update Endpoint Allows Privilege Escalation to Code Execution

7.2 HighFix available

Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.5, the tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary. This vulnerability is fixed in 0.9.5.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
High
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.44%Up 0.4 points since May 16, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.2

Open WebUI: Missing `workspace.tools` Authorization Check on Tool Update Endpoint Allows Privilege Escalation to Code Execution

Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.5, the tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary. This vulnerability is fixed in 0.9.5.

Record
CVE-2026-45395
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269, CWE-862
Updated
2026-11-02
EUVDEUVD-2026-30627 7.2

Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.5, the tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary. This vulnerability is fixed in 0.9.5.

Record
EUVD-2026-30627
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-p4fx-23fq-jfg6 7.2

Open WebUI: Missing `workspace.tools` Authorization Check on Tool Update Endpoint Allows Privilege Escalation to Code Execution

Summary

The tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary.

Open WebUI's security policy correctly states that workspace.tools is the trust boundary for code execution: "Granting a user the ability to create Tools is equivalent to giving them shell access to the server." This vulnerability breaks that boundary. A write access grant on a single tool is sufficient to bypass workspace.tools entirely.

This is not a report about exec() being unsandboxed (that is acknowledged as intended behavior). This is a report about a missing authorization check that allows an untrusted user to reach the exec() sink that should be gated behind workspace.tools.

Root Cause

The create and update endpoints for tools have asymmetric authorization checks. The create endpoint enforces the workspace.tools permission; the update endpoint does not.

Create endpoint, enforces workspace.tools

File: backend/open_webui/routers/tools.py, lines 326-345

@router.post('/create', response_model=Optional[ToolResponse])
async def create_new_tools(
    request: Request,
    form_data: ToolForm,
    user=Depends(get_verified_user),
    db: AsyncSession = Depends(get_async_session),
):
    if user.role != 'admin' and not (
        await has_permission(
            user.id, 'workspace.tools',                    # ← CHECKED
            request.app.state.config.USER_PERMISSIONS, db=db
        )
        or await has_permission(
            user.id, 'workspace.tools_import',             # ← CHECKED
            request.app.state.config.USER_PERMISSIONS, db=db
        )
    ):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=ERROR_MESSAGES.UNAUTHORIZED,
        )
    # ... proceeds to exec(content, ...) at line 367

Update endpoint does NOT enforce workspace.tools

File: backend/open_webui/routers/tools.py, lines 451-485

@router.post('/id/{id}/update', response_model=Optional[ToolModel])
async def update_tools_by_id(
    request: Request,
    id: str,
    form_data: ToolForm,
    user=Depends(get_verified_user),
    db: AsyncSession = Depends(get_async_session),
):
    tools = await Tools.get_tool_by_id(id, db=db)
    # ...

    if (
        tools.user_id != user.id
        and not await AccessGrants.has_access(
            user_id=user.id,
            resource_type='tool',
            resource_id=tools.id,
            permission='write',                            # ← only checks write grant
            db=db,
        )
        and user.role != 'admin'
    ):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=ERROR_MESSAGES.UNAUTHORIZED,
        )
    # NOTE: No has_permission(user.id, 'workspace.tools', ...) check

    # ... proceeds to exec(content, ...) at line 485
    tool_module, frontmatter = await load_tool_module_by_id(id, content=form_data.content)

The write access grant is a collaboration primitive used across the application (knowledge bases, prompts, models, tools) for content editing. On every other resource type, a write grant allows editing metadata and content. On tools specifically, because the update endpoint triggers exec(), a write grant silently escalates to code execution but only because the workspace.tools check is missing. If the check were present (as it is on create), the write grant would not confer execution privilege.

Prerequisites

  1. Attacker (Bob): A regular user account with no workspace.tools permission. workspace.tools…
Record
GHSA-p4fx-23fq-jfg6
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269, CWE-862
Updated
2026-11-02
NVD 7.2

Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.5, the tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary. This vulnerability is fixed in 0.9.5.

Record
CVE-2026-45395
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269, CWE-862
Updated
2026-11-02
OSV 7.2

Open WebUI: Missing `workspace.tools` Authorization Check on Tool Update Endpoint Allows Privilege Escalation to Code Execution

Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.5, the tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary. This vulnerability is fixed in 0.9.5.

Record
CVE-2026-45395
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269, CWE-862
Updated
2026-11-02
OSVGHSA-p4fx-23fq-jfg6 7.2

Open WebUI: Missing `workspace.tools` Authorization Check on Tool Update Endpoint Allows Privilege Escalation to Code Execution

Summary

The tool update endpoint (POST /api/v1/tools/id/{id}/update) is missing the workspace.tools permission check that is present on the tool create endpoint. This allows a user who has been explicitly denied tool management capabilities ( and who the administrator considers untrusted for code execution ) to replace a tool's server-side Python content and trigger execution, bypassing the intended workspace.tools security boundary.

Open WebUI's security policy correctly states that workspace.tools is the trust boundary for code execution: "Granting a user the ability to create Tools is equivalent to giving them shell access to the server." This vulnerability breaks that boundary. A write access grant on a single tool is sufficient to bypass workspace.tools entirely.

This is not a report about exec() being unsandboxed (that is acknowledged as intended behavior). This is a report about a missing authorization check that allows an untrusted user to reach the exec() sink that should be gated behind workspace.tools.

Root Cause

The create and update endpoints for tools have asymmetric authorization checks. The create endpoint enforces the workspace.tools permission; the update endpoint does not.

Create endpoint, enforces workspace.tools

File: backend/open_webui/routers/tools.py, lines 326-345

@router.post('/create', response_model=Optional[ToolResponse])
async def create_new_tools(
    request: Request,
    form_data: ToolForm,
    user=Depends(get_verified_user),
    db: AsyncSession = Depends(get_async_session),
):
    if user.role != 'admin' and not (
        await has_permission(
            user.id, 'workspace.tools',                    # ← CHECKED
            request.app.state.config.USER_PERMISSIONS, db=db
        )
        or await has_permission(
            user.id, 'workspace.tools_import',             # ← CHECKED
            request.app.state.config.USER_PERMISSIONS, db=db
        )
    ):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=ERROR_MESSAGES.UNAUTHORIZED,
        )
    # ... proceeds to exec(content, ...) at line 367

Update endpoint does NOT enforce workspace.tools

File: backend/open_webui/routers/tools.py, lines 451-485

@router.post('/id/{id}/update', response_model=Optional[ToolModel])
async def update_tools_by_id(
    request: Request,
    id: str,
    form_data: ToolForm,
    user=Depends(get_verified_user),
    db: AsyncSession = Depends(get_async_session),
):
    tools = await Tools.get_tool_by_id(id, db=db)
    # ...

    if (
        tools.user_id != user.id
        and not await AccessGrants.has_access(
            user_id=user.id,
            resource_type='tool',
            resource_id=tools.id,
            permission='write',                            # ← only checks write grant
            db=db,
        )
        and user.role != 'admin'
    ):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=ERROR_MESSAGES.UNAUTHORIZED,
        )
    # NOTE: No has_permission(user.id, 'workspace.tools', ...) check

    # ... proceeds to exec(content, ...) at line 485
    tool_module, frontmatter = await load_tool_module_by_id(id, content=form_data.content)

The write access grant is a collaboration primitive used across the application (knowledge bases, prompts, models, tools) for content editing. On every other resource type, a write grant allows editing metadata and content. On tools specifically, because the update endpoint triggers exec(), a write grant silently escalates to code execution but only because the workspace.tools check is missing. If the check were present (as it is on create), the write grant would not confer execution privilege.

Prerequisites

  1. Attacker (Bob): A regular user account with no workspace.tools permission. workspace.tools…
Record
GHSA-p4fx-23fq-jfg6
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-269, CWE-862
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
open-webui
npm
before 0.9.5
0.9.5

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-45395 is a high vulnerability (CVSS 7.2) in Openwebui Open Webui, published May 14, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.44%, the 38th percentile. Fixed in open-webui 0.9.5.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open