Declaration files classify as executable, but excluding .d.cts/.d.mts by name is unsafe
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 17.9k
- Forks
- 1.5k
- Avg merge
- 5d 10h
- Merged PRs (30d)
- 66
Description
.cts, .mts and .ts joined _EXECUTABLE_SUFFIXES in #548, so Path.suffix now classifies TypeScript declaration files as executable content. A skill whose only payload is types.d.cts scans as Executable=Yes.
The obvious fix is to exclude .d.cts/.d.mts by filename. I implemented exactly that in #480, measured it, and withdrew it as unsafe.
Node executes these files. On v24.18.0 node evil.d.cts runs, and node t.d.ts runs under type stripping. The .d. infix is a TypeScript convention, not a loader rule. So with a name-based exclusion, evil.d.cts containing execSync(...), no shebang and no exec bit, flips from flagged to unflagged. Renaming payload.cts to payload.d.cts would evade the scan.
That matters most at build_context.py:715 and :1319, which call is_executable_content(path, b"") with no mode. Suffix is the only live signal there, so neither the shebang nor the exec-bit arm can compensate.
Filing rather than patching, because the false positive is real but the cheap fix trades it for a false negative. Separating a declaration file from a runtime module needs content inspection, not the filename.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at build_context.py:715 and :1319, then trace is_executable_content(path, b"") to understand how suffix, shebang, and executable-bit signals are combined. Define a content-based way to distinguish declaration files from runtime modules without relying on the filename, while ensuring executable code in names such as evil.d.cts remains flagged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100