T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/server.js:641- Finding
Unauthenticated First-Run Administrator Takeover
- Content
View full analysis
res.json({ needs: !isSetupDone() }) ); app.post('/api/auth/setup', (req, res) => { if (isSetupDone()) return res.status(400).json({error:'Admin already configured'}); const { password } = req.body; if (!password || password.length < 6) return res.status(400).json({ error:'Password must be at least 6 characters' }); db.prepare( 'UPDATE admin_users SET password_hash=? WHERE username=?' ).run(bcrypt.hashSync(password,10),'admin'); console.log('[clawdef] ✅ Admin password set via setup page'); res.json({success:true}); }); ``` ### Technical Analysis The first-run setup endpoint assigns the password of the pre-created administrator account without authenticating the caller. It does not require a setup secret, terminal confirmation, operating-system identity verification, or proof that the caller launched the service. Binding the application to `127.0.0.1` reduces remote exposure but does not provide an authentication boundary. Other users, compromised applications, browser extensions, or malicious local processes can access localhost. The unauthenticated `/api/auth/setup-needed` endpoint also reveals whether the takeover opportunity is available. The operation is race-based: whichever caller reaches `/api/auth/setup` first controls the administrator account. ### Attack Path 1. The operator launches ClawDef for the first time. 2. The database contains the `admin` account with an empty password hash. 3. An untrusted local process polls `/api/auth/setup-needed`. 4. When setup is available, it sends a JSON POST request to `/api/auth/set ...[truncated 902 chars]- Remediation
View remediation
