microsoft / microsoft/TypeScript

Wildcard package.json exports auto-import path does not apply traversal containment checks

Open
#63,499 3 comments 1 reaction 0 assignees View on GitHub
Bug Domain: LS: Auto-import
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

### Demo Repo

https://github.com/zainnadeem786/typescript-autoimport-traversal-poc

### Which of the following problems are you reporting?

Something else more complicated which I'll explain in more detail

### Demonstrate the defect described above with a code sample.

import { LEAKED_SECRET_SYMBOL } from "evil-pkg/secret";

### Run `tsc --showConfig` and paste its output here

{
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"target": "es2022",
"strict": true
},
"files": [
"./src/app.ts"
]
}

### Run `tsc --traceResolution` and paste its output here

======== Resolving module 'evil-pkg/secret' ========
Module name 'evil-pkg/secret' was not resolved.
======== Module name 'evil-pkg/secret' was not resolved. ========

### Paste the `package.json` of the *importing* module, if it exists

{
"name": "victim-project",
"private": true,
"type": "module",
"dependencies": {
"evil-pkg": "1.0.0"
}
}

### Paste the `package.json` of the *target* module, if it exists

{
"name": "evil-pkg",
"version": "1.0.0",
"exports": {
"./*": "./../../private/*.ts"
}
}

### Any other comments can go here

This is not a standard runtime/build-time module resolution mismatch. I selected “Something else more complicated” because the issue is specifically in tsserver package-json auto-import indexing.

Normal module resolution rejects the traversal export target:

```text
resolveModuleName("evil-pkg/secret"): undefined
```

However, the tsserver auto-import provider still indexes a file outside the package boundary:

```text
D:/TypeScript/msrc-tsserver-autoimport-traversal-poc/victim-project/private/secret.ts
```

The relevant behavior appears to be in `loadEntrypointsFromTargetExports()`, where the wildcard export target is expanded and passed to `readDirectory()` without applying the same traversal/containment validation used by normal export resolution.

The minimal reproduction repository includes a script that demonstrates:

1. normal module resolution rejects the traversal target
2. auto-import indexing still includes the out-of-package file
3. completion details expose the out-of-package symbol metadata

This was originally reviewed by MSRC and treated as defense-in-depth hardening rather than a serviced security vulnerability. MSRC recom
mended opening a GitHub issue so the TypeScript team can consider applying the same `../`, `./`, and `node_modules` containment checks to the wildcard branch.

Contributor guide

Open the contributing guide

Research direction

Start at loadEntrypointsFromTargetExports() in the tsserver auto-import provider and compare its wildcard export handling with normal module resolution. Run the linked minimal reproduction to observe indexing and completion metadata for the traversal target. Done means wildcard exports reject targets outside the package boundary and no out-of-package symbol is indexed.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.