T09 · Insecure Skill Coding Practices
- Location
SKILL.md:145- Finding
Missing Ownership and State Checks Permit Unauthorized Job-State Modification
- Content
View full analysis
= max_attempts THEN 'failed' ELSE 'pending' END, last_error = $2, worker_id = NULL, claimed_at = NULL WHERE id = $1`, jobID, errMsg, ) return err } ``` ### Technical Analysis The `Complete` and `Fail` methods authorize state changes solely by the supplied job UUID. Their SQL statements do not verify that: - The job is owned by the calling worker, such as through `worker_id = q.workerID`. - The job is currently in an eligible state, such as `claimed` or `running`. - Exactly one authorized row was modified. Consequently, any worker or application component with access to these methods and knowledge of another job's UUID can change that job's status. The `Complete` method can mark an unprocessed or differently owned job as completed, while the `Fail` method can force a retry or terminal failure, inject misleading error information, and clear the legitimate worker assignment. The use of UUIDs does not constitute an authorization boundary. Job identifiers may be exposed through logs, application responses, monitoring systems, or database queries available to other workers. ### Attack Path 1. An attacker compromises a worker, gains access to an application component using the queue, or otherwise o ...[truncated 1417 chars]- Remediation
View remediation
= max_attempts THEN 'failed' ELSE 'pending' END, last_error = $3, worker_id = NULL, claimed_at = NULL WHERE id = $1 AND worker_id = $2 AND status IN ('claimed', 'running'); ``` Pass `q.workerID` as the worker parameter and verify `RowsAffected()`. Treat zero modified rows as an ownership conflict, invalid state transition, missing job, or stale claim rather than reporting success. Additional hardening measures include: 1. Centralize state transitions in stored procedures or repository methods that consistently enforce ownership and lifecycle invariants. 2. Define and enforce an explicit state-transition model, preventing transitions such as `pending` directly to `completed`. 3. Use least-privilege database roles so workers cannot issue unrestricted updates against the `jobs` table. 4. Consider a per-claim random lease token in addition to `worker_id`, and require that token for completion or failure updates. 5. Record transition audit events containing the job ID, previous state, new state, worker identity, and timestamp. 6. Add concurrency tests proving that one worker cannot complete or fail a job claimed by another worker. ]]>
