You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
app.post('/opencode-install-version',async(c)=>{constoldVersion=opencodeServerManager.getVersion()logger.info(`Current OpenCode version: ${oldVersion}`)try{constbody=awaitc.req.json()const{ version }=z.object({version: z.string().min(1)}).parse(body)logger.info(`Installing OpenCode version: ${version}`)constversionArg=version.startsWith('v') ? version : `v${version}`constinstallMethod=getOpenCodeInstallMethod()logger.info(`Running opencode upgrade ${versionArg} --method ${installMethod} with 90s timeout...`)const{output: upgradeOutput, timedOut }=execWithTimeout(`opencode upgrade ${versionArg} --method ${installMethod} 2>&1`,90000)[...]
The /opencode-install-version endpoint in backend/src/routes/settings.ts accepts a version parameter from user JSON input and used in the function execWithTimeout (which uses execSync).
However:
the validation for version is insufficient:
it only verifies that the string is not empty
it does not verify that the string is a valid version (MAJOR.MINOR.PATCH)
execSync is vulnerable to command injection when concatenating unsafe inputs like version.
Proof of Concept
Warning
The attacker needs to be authenticated in order to exploit.
Setup
git clone https://github.com/chriswritescode-dev/opencode-manager.git
cd opencode-manager/
cp .env.example .env
sed -i -e "s/# AUTH_SECRET=your-secure-random-secret-here/AUTH_SECRET=your-secure-random-secret-here/g" .env
sed -i -e "s/# ADMIN_EMAIL=admin@example.com/ADMIN_EMAIL=admin@example.com/g" .env
sed -i -e "s/# ADMIN_PASSWORD=your-secure-password/ADMIN_PASSWORD=your-secure-password/g" .env
docker compose up
opencode-manager already allows remote code execution through OpenCode. Since the exploitation of this vulnerability requires to be authenticated, the final impact is considered as LOW even if the impact of the vulnerability by itself is considered high.
This vulnerability by itself does not impact the security of opencode-manager. However, it has been observed that this type of vulnerability is often chained with other vulnerabilities, which can lead to a real security risk, as in a similar package: Unauthenticated RCE via WebSocket shell injection in siteboon/claudecodeui.
The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
Learn more on MITRE.
Fix commit
4752487
Analysis
Affected Component:
backend/src/routes/settings.ts:L637The
/opencode-install-versionendpoint inbackend/src/routes/settings.tsaccepts aversionparameter from user JSON input and used in the functionexecWithTimeout(which usesexecSync).However:
versionis insufficient:MAJOR.MINOR.PATCH)execSyncis vulnerable to command injection when concatenating unsafe inputs likeversion.Proof of Concept
Warning
The attacker needs to be authenticated in order to exploit.
Setup
Exploitation
Change the cookie accordingly.
Result
Impact
opencode-manager already allows remote code execution through OpenCode. Since the exploitation of this vulnerability requires to be authenticated, the final impact is considered as LOW even if the impact of the vulnerability by itself is considered high.
This vulnerability by itself does not impact the security of opencode-manager. However, it has been observed that this type of vulnerability is often chained with other vulnerabilities, which can lead to a real security risk, as in a similar package: Unauthenticated RCE via WebSocket shell injection in siteboon/claudecodeui.
Remediation
execFileSync:version: