T09 · Insecure Skill Coding Practices
Warning
- Location
- ultrawork-handler.ts:44
- Finding
- Concurrency Safety Checks Are Bypassed During Automatic Parallel Execution<![CDATA[ ## Vulnerability Details **File Location**: `ultrawork-handler.ts:44-72, 95-98, 121-169`; related unused safeguards in `src/concurrency.ts:20-78, 121-145` **Vulnerability Type**: Unsafe parallel execution of dependent or conflicting tasks **Risk Level**: Medium ### Vulnerable Code The automatic classifier treats refactoring and bug-fixing requests as candidates for parallel execution: ```typescript export function shouldAutoParallelize(task: string): boolean { const keywords = ['ulw', 'ultrawork', 'parallel']; const hasKeyword = keywords.some(k => task.toLowerCase().includes(k)); // Also detect by complexity const complexPatterns = [ /criar\s+(um?\s+)?(novo|nova)/i, /implementar/i, /construir/i, /refatorar/i, /reescrever/i, /migrar/i, /criar\s+.*api/i, /criar\s+.*cli/i, /criar\s+.*projeto/i, /criar\s+.*app/i, /build\s+/i, /corrigir\s+o?\s*bug/i, /fix\s+(the\s+)?bug/i, /consertar/i, ]; const isComplex = complexPatterns.some(p => p.test(task.toLowerCase())); return hasKeyword || isComplex; } ``` The preparation path proceeds directly to planning without invoking the concurrency safeguards implemented in `src/concurrency.ts`: ```typescript // Detectar se tem prefixo ulw para limpar const cleanedTask = task.replace(/^(ulw|ultrawork)\s*/i, '').trim(); // Execute o planner const plan = planSimpleTask(cleanedTask); ``` The planner then returns logically dependent bug-fixing tasks as a single collection intended for `parallel_spawn`: ```typescript if (lower.includes('fix') || lower.includes('bug')) { return { mainTask: task, chunks: [ { label: 'debug', task: `Find and understand bug: ${task}. Find root cause.`, persona: 'oracle' }, { label: 'fix', task: `Fix bug: ${task}.`, persona: 'hephaestus' }, { label: 'verify', task: `Verify fix: ${task}.`, persona: 'explore' }, ], }; } ``` Refactoring tasks are handled similarly: ```typescript if ...[truncated 3123 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce concurrency analysis in the active execution path** - Import and invoke `analyzeTask()` or `checkConcurrencySafety()` inside `prepareParallelExecution()`. - Do not return a parallel-executable batch unless the result explicitly recommends `parallel`. 2. **Default conflicting operations to sequential execution** - Treat bug fixes, refactors, migrations, same-file edits, and shared configuration changes as sequential unless independence has been established. - Return `shouldExecute: false` or an explicit sequential strategy for uncertain cases. 3. **Model task dependencies** - Populate the existing `dependsOn` field for task chunks. - For example, make `fix` depend on `debug`, and make `verify` depend on `fix`. - Execute chunks in topological stages, parallelizing only independent chunks within the same stage. 4. **Separate read-only and modifying tasks** - Permit parallel execution for independent read-only analysis. - Ensure that tasks with `write`, `edit`, package installation, build generation, or other mutating capabilities do not concurrently target shared resources. 5. **Require explicit conflict information** - Resolve each chunk to its anticipated files or directories before execution. - Reject or serialize chunks with overlapping write sets. 6. **Add regression tests** - Verify that `fix bug`, `refactor`, same-file edits, and shared-module changes never produce an unrestricted parallel write batch. - Verify that explicitly independent, disjoint-file tasks remain eligible for parallel execution. - Test that dependency ordering is enforced before verification begins. 7. **Align documentation and implementation** - Ensure the active handler follows the sequential behavior promised by `SKILL.md`. - Document whether `shouldExecute` means parallel execution specifically or any orchestrated execution. ]]>
