T09 · Insecure Skill Coding Practices
- Location
run.js:153- Finding
OAuth Login CSRF Due to Fixed and Unvalidated State Parameter
- Content
View full analysis
{ const app = express(); const server = app.listen(3001); app.get('/callback', async (req, res) => { try { const code = req.query.code; const realmId = req.query.realmId; ``` ### Technical Analysis OAuth 2.0 authorization-code flows require a cryptographically unpredictable, session-bound `state` value. The application must compare the state returned to the callback with the value generated for the active authorization request. This implementation always sends the fixed value `randomstate`. More importantly, the callback does not read or validate `req.query.state` at all. It accepts any authorization code and realm ID delivered to the local callback endpoint. Consequently, the callback is not bound to the authentication operation initiated by the victim. An attacker who can cause the victim's browser or another locally accessible process to request the callback may inject an authorization response associated with a different QuickBooks account or company. The implementation also fails to validate that `code` and `realmId` are present and correctly formed before exchanging and persisting them. ### Attack Path 1. The attacker learns the application's OAuth client ID and redirect URI. 2. The attacker initiates an Intuit OAuth authorization flow and authorizes access to an attacker-controlled QuickBooks company. 3. The attacker obtains an authorization response intended for `http://localhost:3001/callback`. 4. While the victim's Skill callback server is listening, the ...[truncated 1277 chars]- Remediation
View remediation
