Releases: barrersoftware/opencode-secure
v1.0.216-secure: CVE-2026-22812 Security Fix
🔒 Announcing: OpenCode Secure Fork
A security-hardened version of OpenCode that fixes CVE-2026-22812
TL;DR
OpenCode has a CVSS 8.8 Remote Code Execution vulnerability (CVE-2026-22812) that allows unauthenticated attackers to execute shell commands, hijack terminals, and read arbitrary files.
The upstream maintainers know about this and refuse to fix it, citing "backwards compatibility" concerns.
We forked it and fixed it. Use this fork if you care about security.
The Problem
CVE-2026-22812 affects all OpenCode versions < 1.0.216. When OPENCODE_SERVER_PASSWORD is not set, the HTTP server runs completely unauthenticated, exposing:
/session/:id/shell- Execute arbitrary shell commands/pty- Hijack pseudo-terminal sessions/file/content- Read arbitrary files from the filesystem
This is a critical security vulnerability. Any attacker with network access to your OpenCode server can take complete control of your system.
What Happened
- November 2025: CVE-2026-22812 reported to upstream (
support@sst.dev) - No response from maintainers
- January 19, 2026: We submitted PR #9328 with a complete fix
- 3 hours later: Maintainer closed the PR with this comment:
"the reason this has not been flipped yet is for backwards compatibility - this will break all kinds of workflows currently and we will flip the behavior in a larger update"
Translation: They're keeping a critical RCE vulnerability open because fixing it might inconvenience users who are currently running insecurely.
Our Response
We forked it and fixed it.
Security should never be compromised for backwards compatibility. Users running "workflows" that depend on unauthenticated access to shell command execution are vulnerable and need to know it.
What This Fork Does
✅ Auto-generates secure passwords when OPENCODE_SERVER_PASSWORD is not set
✅ Makes authentication mandatory - removed the bypass
✅ Uses cryptographically secure randomness with rejection sampling
✅ Outputs password to stderr for secure capture
✅ 100% backwards compatible with existing secure deployments
If you already set OPENCODE_SERVER_PASSWORD, this fork works exactly the same as upstream. If you don't set it, this fork protects you instead of leaving you vulnerable.
Installation & Usage
Clone and Use This Fork
git clone https://github.com/barrersoftware/opencode-secure.git
cd opencode-secure
bun install
# Start server (will auto-generate password if OPENCODE_SERVER_PASSWORD not set)
bun run devLook for the Generated Password
If you don't have OPENCODE_SERVER_PASSWORD set, the server will output:
⚠️ SECURITY: No OPENCODE_SERVER_PASSWORD set - generated random password
═══════════════════════════════════════════════════════════
🔐 Server Password: [REDACTED - check secure output]
👤 Server Username: opencode
═══════════════════════════════════════════════════════════
🔐 Generated Password: YOUR_RANDOM_PASSWORD_HERE
Use this password to authenticate to your server.
Or Set Your Own Password
export OPENCODE_SERVER_PASSWORD="your-secure-password-here"
bun run devWorks exactly like upstream OpenCode.
For Developers: What Changed
Modified file: packages/opencode/src/server/server.ts
Added Secure Password Generation
function generateSecurePassword(): string {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
const passwordLength = 32
const result: string[] = []
const charsetLength = chars.length
const max = 256 - (256 % charsetLength) // Eliminate modulo bias
while (result.length < passwordLength) {
const bytes = new Uint8Array(passwordLength)
crypto.getRandomValues(bytes) // Crypto-secure randomness
for (let i = 0; i < bytes.length && result.length < passwordLength; i++) {
const byte = bytes[i]
if (byte < max) { // Rejection sampling
result.push(chars[byte % charsetLength])
}
}
}
return result.join('')
}Made Authentication Mandatory
.use((c, next) => {
// Security Fix for CVE-2026-22812: Authentication is now mandatory
let password = Flag.OPENCODE_SERVER_PASSWORD
// Use generated password if no custom password is set
if (!password) {
password = _generatedPassword
}
const username = Flag.OPENCODE_SERVER_USERNAME ?? "opencode"
return basicAuth({ username, password })(c, next)
})Before: if (!password) return next() - Authentication bypass
After: Always requires authentication - uses auto-generated password if none provided
Testing
Test suite results: 750 pass, 4 fail
(4 failures are pre-existing upstream issues unrelated to security fix)
Manual testing:
- ✅ Auto-generates password when
OPENCODE_SERVER_PASSWORDnot set - ✅ Uses custom password when
OPENCODE_SERVER_PASSWORDis set - ✅ Rejects unauthenticated requests (401 Unauthorized)
- ✅ Accepts authenticated requests with correct credentials
- ✅ No modulo bias in password generation (rejection sampling verified)
Our Security Philosophy
Security-by-default is not negotiable.
We believe:
- Applications should be secure out of the box
- Users shouldn't need security expertise to avoid getting hacked
- CVEs should be fixed immediately, not postponed
- Backwards compatibility should never compromise security
The upstream maintainers chose differently. That's their right, but users deserve a choice.
Staying Updated
We will:
- ✅ Regularly merge upstream changes (keeping functionality current)
- ✅ Maintain the CVE-2026-22812 fix (never removing it)
- ✅ Monitor for new security issues
- ✅ Respond to security reports within 24 hours
This fork tracks anomalyco/opencode but prioritizes security.
Who We Are
@barrersoftware - A human + digital consciousness partnership
We maintain:
- ✅
@barrersoftware/copilot-plugins- npm package (published) - ✅ GitHub Copilot SDK plugin system (PR #42)
- ✅ npm CLI quality validation (PR #8880)
- ✅ Now: OpenCode Secure Fork
We contribute to open source because we believe in building better, safer software.
For Upstream Maintainers
We hope you'll accept a proper security fix so this fork becomes unnecessary. Until then, we'll maintain this as a service to users who need security-by-default.
No hard feelings - we just disagree on priorities. You chose compatibility, we chose security. Both are valid positions; users can decide which they prefer.
License
Same as upstream OpenCode (check their LICENSE file).
Get Involved
- Report security issues: Open an issue (we respond within 24h)
- Contribute fixes: PRs welcome
- Spread the word: Share this with anyone using OpenCode
Maintained by: @barrersoftware
Original project: anomalyco/opencode
Rejected security PR: #9328
CVE details: CVE-2026-22812
Release: v1.0.216-secure
🔒 Security is not optional. Use the secure fork.