Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,12 @@ dxt unsign my-extension.dxt
For signing extensions, you need:

1. **Certificate**: X.509 certificate in PEM format

- Should have Code Signing extended key usage
- Can be self-signed (for development) or CA-issued (for production)

2. **Private Key**: Corresponding private key in PEM format

- Must match the certificate's public key

3. **Intermediate Certificates** (optional): For CA-issued certificates
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,14 @@ The `server` object defines how to run the MCP server:
### Server Types

1. **Python**: `server.type = "python"`

- Requires `entry_point` to Python file
- All dependencies must be bundled in the DXT
- Can use `server/lib` for packages or `server/venv` for full virtual environment
- Python runtime version specified in `compatibility.runtimes.python`

2. **Node.js**: `server.type = "node"`

- Requires `entry_point` to JavaScript file
- All dependencies must be bundled in `node_modules`
- Node.js runtime version specified in `compatibility.runtimes.node`
Expand Down
13 changes: 12 additions & 1 deletion src/cli/unpack.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unzipSync } from "fflate";
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`

Check warning on line 2 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Replace `·chmodSync,·existsSync,·mkdirSync,·readFileSync,·writeFileSync·` with `⏎··chmodSync,⏎··existsSync,⏎··mkdirSync,⏎··readFileSync,⏎··writeFileSync,⏎`
import { join, resolve } from "path";
import { join, resolve, sep } from "path";

import { extractSignatureBlock } from "../node/sign.js";
import { getLogger } from "../shared/log.js";
Expand Down Expand Up @@ -41,7 +41,7 @@
if (isUnix) {
// Parse ZIP central directory to extract file attributes
const zipBuffer = originalContent;

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Delete `······`

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Delete `······`

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Delete `······`

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Delete `······`

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Delete `······`

Check warning on line 44 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Delete `······`
// Find end of central directory record
let eocdOffset = -1;
for (let i = zipBuffer.length - 22; i >= 0; i--) {
Expand All @@ -54,21 +54,21 @@
if (eocdOffset !== -1) {
const centralDirOffset = zipBuffer.readUInt32LE(eocdOffset + 16);
const centralDirEntries = zipBuffer.readUInt16LE(eocdOffset + 8);

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Delete `········`

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Delete `········`

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Delete `········`

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Delete `········`

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Delete `········`

Check warning on line 57 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Delete `········`
let offset = centralDirOffset;

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Delete `········`

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Delete `········`

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Delete `········`

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Delete `········`

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Delete `········`

Check warning on line 59 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Delete `········`
for (let i = 0; i < centralDirEntries; i++) {
if (zipBuffer.readUInt32LE(offset) === 0x02014b50) {
const externalAttrs = zipBuffer.readUInt32LE(offset + 38);
const filenameLength = zipBuffer.readUInt16LE(offset + 28);
const filename = zipBuffer.toString('utf8', offset + 46, offset + 46 + filenameLength);

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 64 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Replace `'utf8',·offset·+·46,·offset·+·46·+·filenameLength);` with `⏎··············"utf8",⏎··············offset·+·46,⏎··············offset·+·46·+·filenameLength,`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Insert `);⏎`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Insert `);⏎`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Insert `);⏎`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Insert `);⏎`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Insert `);⏎`

Check warning on line 65 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Insert `);⏎`
// Extract Unix permissions from external attributes (upper 16 bits)
const mode = (externalAttrs >> 16) & 0o777;
if (mode > 0) {
fileAttributes.set(filename, mode);
}

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, macos-latest)

Delete `············`

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, ubuntu-latest)

Delete `············`

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, ubuntu-latest)

Delete `············`

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, macos-latest)

Delete `············`

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (20.19.x, windows-latest)

Delete `············`

Check warning on line 71 in src/cli/unpack.ts

View workflow job for this annotation

GitHub Actions / Test (22.17.x, windows-latest)

Delete `············`
const extraFieldLength = zipBuffer.readUInt16LE(offset + 30);
const commentLength = zipBuffer.readUInt16LE(offset + 32);
offset += 46 + filenameLength + extraFieldLength + commentLength;
Expand All @@ -85,6 +85,17 @@
if (Object.prototype.hasOwnProperty.call(decompressed, relativePath)) {
const data = decompressed[relativePath];
const fullPath = join(finalOutputDir, relativePath);

// Prevent zip slip attacks by validating the resolved path
const normalizedPath = resolve(fullPath);
const normalizedOutputDir = resolve(finalOutputDir);
if (
!normalizedPath.startsWith(normalizedOutputDir + sep) &&
normalizedPath !== normalizedOutputDir
) {
throw new Error(`Path traversal attempt detected: ${relativePath}`);
}

const dir = join(fullPath, "..");
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
Expand Down
Loading