[Eclipse Theia] Arbitrary file read via file-download endpoints (no path containment)
<!-- Note that this issue is configured (see the quick actions at the bottom) to be created as confidential. Note that a vulnerability does not need to actually be resolved before it is reported and that these reports can be revised as needed (reopen the issue to request changes). If you do not know how to fill certain fields, mark that in the comment and we will help you. You can delete the comments (or not). --> <!-- Required. Specify the project's name (e.g., "Eclipse Dash") and Eclipse Foundation ID, e.g., "technology.dash". --> ## Basic information **Project name:** Eclipse Theia **Project id:** ecd.theia ## What are the affected versions? Confirmed on 1.72.3 and current `master` (1.73.0). Likely present in all prior releases that ship the same endpoints. ## Details of the issue - CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal) - CWE-36: Absolute Path Traversal - Impact: CWE-200 (Exposure of Sensitive Information) - Aggravating: CWE-306 (Missing Authentication for Critical Function); see paragraph about authentication, below The Theia backend exposes HTTP file-download endpoints that convert a client-supplied URI directly to a filesystem path and stream the file, without any restriction to the workspace (or any allow-listed root). A client can therefore read any file readable by the backend process, including files entirely outside the opened workspace (e.g. `/etc/hosts`, SSH keys, tokens, other users' files on a shared/hosted deployment). 1. Standalone `GET /file` endpoint: `packages/filesystem/src/node/download/file-download-endpoint.ts` (handler registered via `app.get('/file', ...)`): ``` const uri = url.parse(request.url).query; // client-controlled const fsPath = FileUri.fsPath(decodeURIComponent(uri)); response.sendFile(fsPath); // no containment check ``` 2. `/files/` single-file handler: `packages/filesystem/src/node/download/file-download-handler.ts` (`SingleFileDownloadHandler.handle`): ``` const uri = new URI(query.uri).toString(true); // client-controlled const filePath = FileUri.fsPath(uri); // fs.stat(filePath) + stream; directories are tar-archived // no check that filePath is inside a workspace/allowed root ``` Neither path is normalized against or confined to the workspace roots. In browser deployments, the connection token is enforced only on WebSocket upgrades. The corresponding Express middleware (`packages/core/src/node/hosting/browser-connection-token.ts`, `BrowserConnectionTokenBackendContribution.expressMiddleware`) does not reject tokenless HTTP requests; it only (re)issues the cookie and calls `next()`. Consequently, these HTTP endpoints are reachable without a valid token. (Electron uses a separate `ElectronSecurityToken`.) ## Steps to reproduce With the browser example (or any Theia-based app) running, in a terminal on your host system do: ``` $ curl 'http://<host>:3000/file?file%3A%2F%2F%2Fetc%2Fhosts' ``` This then returns the server's `/etc/hosts`, a file outside any workspace that any connected frontend has open. ## Do you know any mitigations of the issue? Excluding the `@theia/filesystem` package from the Theia-based application would not cause the affected service endpoint not to be present at run-time. <!-- Please, do not remove the line below. It will create a confidential issue that will be visible only to you and the members of this project. Confidential issues are used to keep security vulnerabilities private until they are sorted out. Eclipse Projects follow Responsible Disclosure best practices: the initial report is made privately, but with the full details being published once a patch has been made available (sometimes with a delay to allow more time for the patches to be installed). -->
issue

Copyright © Eclipse Foundation AISBL. All rights reserved.     Privacy Policy | Terms of Use | Copyright Agent