Can you do a security audit on this vscode extension?
do a security audit on this vscode extension
I've now reviewed the entire codebase. Here is my comprehensive security audit:
#🔒 Security Audit: copy VS Code Extension (v1.1.1)
##Overview
This is a relatively simple VS Code extension that copies file paths, names, and references to the clipboard, with optional integration with GitLens and GitHub Pull Request extensions. The attack surface is small due to its limited scope.
##✅ Positive Findings (Things Done Right)
-
No runtime dependencies — Only
devDependenciesexist inpackage.json. The extension ships with zero third-party runtime dependencies, which massively reduces supply-chain risk. -
No network access — The extension makes no HTTP requests, opens no sockets, and does not communicate with any external servers.
-
No filesystem writes — The extension only reads file metadata (paths, names, line numbers) from the VS Code API. It never reads file contents or writes to disk.
-
No user input processing (mostly) — Data written to the clipboard comes from trusted VS Code APIs (
editor.document.fileName,workspace.asRelativePath,editor.selection.active.line), not from user-controlled free-text input. -
Strict TypeScript —
tsconfig.jsonhas"strict": true, which helps catch type-safety bugs at compile time. -
Proper disposal — Extension disposables are correctly pushed to
context.subscriptions, preventing memory leaks. -
Extension detection before delegation — In
src/utils.ts, the code checksextension?.isActivebefore exposing GitLens/GitHub options, preventing attempts to invoke commands on extensions that aren't installed.
##⚠️ Low-Severity Findings
###1. Arbitrary Command Execution via QuickPick — src/quickPick.ts:43-46
const execute = (selected: QuickPickOption) => {
if (selected.description) {
env.clipboard.writeText(selected.description)
} else if (selected.command) {
commands.executeCommand(selected.command)
}
}
Risk: The execute function calls commands.executeCommand(selected.command) where selected.command comes from the QuickPickOption items. Currently, these commands are hardcoded in src/constants.ts (e.g., gitlens.copyShaToClipboard, issue.copyGithubPermalink), so this is safe. However, the type system (QuickPickOption has command?: string) allows any string as a command. If future code changes dynamically populate commands from untrusted input, this could become a command injection vector.
Severity: Low (currently safe; defensive concern for future maintenance).
Recommendation: Consider restricting the command field to a union of known-safe command identifiers rather than string.
###2. Double Execution in onDidChangeValue — src/quickPick.ts:59-69
const onDidChangeValue = (qp: QuickPick<QuickPickOption>) => {
clearTimeout(timeout)
const index = parseInt(qp.value, 10)
const quickPickOptions = qp.items
if (quickPickOptions[index]) {
timeout = setTimeout(() => {
execute(quickPickOptions[index]) // First execution (after 500ms)
showSuccess()
qp.hide()
}, 500)
execute(quickPickOptions[index]) // Second execution (immediate)
}
}
Risk: This is a logic bug, not strictly a security issue. When a user types a numeric index, execute() is called twice — once immediately and once after a 500ms timeout. This means:
- A clipboard write happens twice (harmless but wasteful).
- A delegated command (GitLens/GitHub) gets executed twice, which could trigger unintended side effects depending on the command.
Severity: Low (logic bug with minor side-effect potential).
Recommendation: Remove the immediate execute() call on line 68, keeping only the debounced timeout.
###3. Unbounded parseInt Index Access — src/quickPick.ts:61
const index = parseInt(qp.value, 10)
Risk: parseInt on arbitrary text can return NaN, negative numbers, or very large numbers. While quickPickOptions[index] will simply be undefined for out-of-bounds indices (making this safe in practice), there's no validation that index is a non-negative integer within the expected range. parseInt("1e2", 10) returns 1, so there's no real exploit here, but it's a code quality concern.
Severity: Very Low.
Recommendation: Add explicit bounds checking: if (index >= 0 && index < quickPickOptions.length).
###4. absolutePathWithLine Leaks URI Scheme — src/utils.ts:11
const absolutePathWithLine = `${editor.document.uri.toString()}#${currentLine}`
Risk: editor.document.uri.toString() returns the full URI including the scheme (e.g., file:///home/user/project/foo.ts#42 or vscode-remote://...). This may unintentionally expose:
- The full local filesystem path structure.
- Remote connection details (SSH hostname, container name) for remote development users.
This is clipboard data, so it's only exposed if the user pastes it somewhere, but it could inadvertently leak sensitive environment info.
Severity: Low (by-design behavior for a "copy path" extension, but worth noting).
Recommendation: Document this behavior. Consider using editor.document.uri.fsPath instead for consistency with absolutePath on line 5, or add a note to users that this may contain remote connection details.
###5. No .vscodeignore for node_modules
The .vscodeignore file does not explicitly exclude node_modules/:
.vscode/**
.vscode-test/**
src/**
...
Risk: While vsce (the VS Code packaging tool) excludes node_modules by default when there are no production dependencies, explicitly listing it is a best practice to prevent accidental inclusion of dev dependencies in the published .vsix, which could increase attack surface.
Severity: Very Low.
Recommendation: Add node_modules/** to .vscodeignore.
##📦 Supply Chain Assessment
| Category | Status |
|---|---|
| Runtime dependencies | ✅ None |
| Dev dependencies | ⚠️ Pinned with ^ ranges (minor/patch float) |
| Lock file | ✅ Present (package-lock.json, lockfileVersion 3) |
@aashutoshrathi/word-wrap | ⚠️ Transitively included — this is a fork of the original word-wrap package created after CVE-2023-26115. The version 1.2.6 is safe. |
| Source maps in production | ⚠️ tsconfig.json has "sourceMap": true — source maps are shipped but excluded via .vscodeignore (**/*.map) ✅ |
Since there are zero runtime dependencies, supply chain risk is effectively negligible. All dependencies are dev-only (TypeScript, ESLint, test runners).
##🔑 Permissions Assessment
The extension requests no special permissions in its package.json:
- No
extensionDependencies - No
extensionPack - No custom URI handlers
- No webview panels
- No terminal access
- No task providers
- No authentication providers
activationEvents: []— activates only on command invocation ✅
##🏁 Summary
| Area | Rating |
|---|---|
| Overall Risk | 🟢 Low |
| Supply Chain | 🟢 Minimal (no runtime deps) |
| Code Injection | 🟢 None found |
| Data Exfiltration | 🟢 None (no network access) |
| Privilege Escalation | 🟢 None (no elevated permissions) |
| Information Disclosure | 🟡 Minor (URI scheme in absolutePathWithLine) |
| Logic Bugs | 🟡 Minor (double execution in onDidChangeValue) |
This extension has a very small, well-contained attack surface. The most actionable finding is the double execution bug in onDidChangeValue, which should be fixed to avoid calling delegated commands (GitLens, GitHub) twice. The rest are defensive coding recommendations for long-term maintainability.
can i install? is my question :)
Yes, install it. It's clean.
- Zero runtime dependencies
- No network access
- No filesystem writes
- No special permissions
- Only reads path metadata from VS Code's own APIs and copies it to your clipboard
The findings in the audit are nitpicks — nothing that puts you at risk. Go for it. 🟢
END OF POST