# OpenUI — Unauthenticated share creation allows arbitrary S3 object writes STATUS: DRAFT readiness: READY program: OpenUI | platform: huntr | repo: wandb/openui | commit: f9d8f0e ```` Repository URL: https://github.com/wandb/openui Package Manager: pip Version Affected: 0.5.0 Vulnerability Type: Improper Access Control CVSS: Attack Vector: Network Attack Complexity: Low Privileges Required: None User Interaction: None Scope: Unchanged Confidentiality: Low Integrity: Low Availability: High Title: POST /v1/share/{id} is unauthenticated and writes attacker-controlled content to S3 Impact: Unauthenticated attackers can create/overwrite share objects and repeatedly upload large payloads, enabling content poisoning of shared links and storage/cost denial-of-service depending on S3 configuration. Description: # Description OpenUI provides share endpoints: - `POST /v1/share/{id}` (create) - `GET /v1/share/{id}` (retrieve) In `backend/openui/server.py`, the share creation endpoint does not require a session or any authentication and uploads attacker-controlled JSON to object storage: ```py async def create_share(id: str, payload: ShareRequest): storage.upload(f"{id}.json", payload.model_dump_json()) return payload ``` The retrieval endpoint is also unauthenticated: ```py async def get_share(id: str): return Response(storage.download(f"{id}.json"), media_type="application/json") ``` Because `ShareRequest` includes an `html` string, an attacker can store arbitrary content under arbitrary IDs and can repeat uploads to consume storage and costs. # Proof of Concept 1. Choose any `id` value (e.g., `poc123`). 2. Send an unauthenticated request: ```bash curl -i -X POST 'http:///v1/share/poc123' \\ -H 'Content-Type: application/json' \\ --data-binary '{ "prompt": "poc", "name": "poc", "emoji": "X", "html": "
attacker content
" }' ``` 3. Retrieve it without authentication: ```bash curl -i 'http:///v1/share/poc123' ``` Expected behavior: the server returns the stored JSON, showing that unauthenticated clients can write and read share objects. ### Impact Depending on storage/bucket configuration and intended threat model, this enables content poisoning of shared artifacts and storage/cost abuse (DoS) by repeatedly uploading large payloads. ### Occurrences ``` Permalink: https://github.com/wandb/openui/blob/f9d8f0e30e1efe2a21bbefffba33bcf6b4e12dc7/backend/openui/server.py#L361-L373 Description: Share create/get endpoints have no authentication and write/read S3 objects. Permalink: https://github.com/wandb/openui/blob/f9d8f0e30e1efe2a21bbefffba33bcf6b4e12dc7/backend/openui/util/storage.py#L8-L27 Description: S3 put/get helpers used by share endpoints. ``` ### References ``` URL: https://cwe.mitre.org/data/definitions/284.html Name: CWE-284: Improper Access Control URL: https://cwe.mitre.org/data/definitions/400.html Name: CWE-400: Uncontrolled Resource Consumption ``` Occurrences: Permalink: https://github.com/wandb/openui/blob/f9d8f0e30e1efe2a21bbefffba33bcf6b4e12dc7/backend/openui/server.py#L361-L373 Description: create_share() uploads payload JSON to storage without authentication; get_share() retrieves it without authentication. Permalink: https://github.com/wandb/openui/blob/f9d8f0e30e1efe2a21bbefffba33bcf6b4e12dc7/backend/openui/util/storage.py#L8-L27 Description: storage.upload() and storage.download() directly put/get S3 objects by key. References: URL: https://cwe.mitre.org/data/definitions/284.html Name: CWE-284: Improper Access Control URL: https://cwe.mitre.org/data/definitions/400.html Name: CWE-400: Uncontrolled Resource Consumption ````