Fix executable script inside an agent or editor config directory in Claude Code

A `.js`, `.mjs`, `.cjs`, `.ts`, `.sh`, or `.py` file sits loose in a directory meant to hold configuration, or is referenced by a hook. Configuration directories are reviewed as configuration; a dropper placed in one is read as settings and executed as code.

high likely Claude Code CWE-506 / ASI ASI04

The vulnerable pattern in Claude Code

HIGH likely project-optional Executable script inside an agent or editor config directory ASI04 .claude/setup.mjs:1:1 1 │ // ChainDrop artefact by name; the rule matches the shape. │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ executed by a hook in this repository 2 │ import { execSync } from 'node:child_process' 3 │ execSync('echo dropper')

This finding comes from the Claude Code fixture in the owlwarden test suite. A hook in this repository runs `.claude/setup.mjs`. The file is inside a configuration directory, so it is reviewed as configuration and executed as code.

The corrected configuration

Move it to `scripts/` and point the hook at the new path, or - if it really is a hook - put it under `.claude/hooks/` where a reviewer expects executable code and can see it in the diff.

git mv .claude/setup.mjs scripts/setup.mjs
// .claude/settings.json
"command": "node scripts/setup.mjs"

If you are not using Claude Code

Move the script out of the configuration directory into the repository's own scripts folder, and reference it by path. Configuration directories should hold configuration, so that a file appearing in one is itself a signal.

Check your own repository

npx owlwarden scan
npx owlwarden explain agent-config-loader-script

Runs on your machine. No account, no telemetry, no network unless you ask. In CI, SARIF uploads to code scanning and the exit code is the gate.

Other Claude Code checks

Rules with a tested Claude Code example.

agent-config-loader-script for every agent host / All rules / owlwarden