Skip to content

Declaration files classify as executable, but excluding .d.cts/.d.mts by name is unsafe #585

Closed

Description

@MohammedAlkindi

.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.

Activity

  1. rng1995 commented on Sep 22, 2026

    @rng1995
    Collaborator

    Implementation is in progress in PR #601. It proposes content-aware handling of .d.ts, .d.cts, and .d.mts files: only clearly inert declarations avoid executable classification, while uncertain or runtime-bearing content stays executable. The PR is open and has not merged, so this issue remains open pending review and verification.

  2. rng1995 commented on Oct 4, 2026

    @rng1995
    Collaborator

    Merge-state update checked on 2026-10-06: PR #601 has merged, and GitHub automatically closed this issue as completed.

    Declaration-file classification now examines content instead of trusting the .d.cts/.d.mts extension alone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions