# How Modly's Extension Path Security Prevents Directory Traversal Attacks

> Discover how Modly's extension path security stops directory traversal attacks. Modly validates IDs and resolves paths within a root directory to keep your extension secure.

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: security
- Published: 2026-08-15

---

**Modly prevents directory traversal attacks by validating extension IDs against strict patterns and resolving all paths within a canonical root directory, ensuring resolved paths never escape the extension folder boundary.**

The Modly extension framework isolates third-party code in a dedicated directory tree, implementing a defense-in-depth strategy against filesystem escapes. According to the `lightningpixel/modly` source code, every filesystem operation involving extensions passes through a security layer that validates identifiers and canonicalizes paths before any disk access occurs. This approach blocks malicious inputs like `../../etc/passwd` at multiple validation stages.

## Three-Stage Path Validation Strategy

### Strict Extension-ID Validation with `assertSafeExtensionId`

The first line of defense resides in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts), where the `assertSafeExtensionId` function enforces five strict constraints on any extension identifier:

- **Non-empty and trimmed**: The ID must contain visible characters after whitespace removal (lines 10‑13).
- **No navigation tokens**: Rejects single `.` or double `..` directory references (lines 15‑17).
- **Relative-only**: Blocks absolute paths such as `/etc/passwd` (lines 19‑21).
- **No path separators**: Explicitly forbids forward slashes, backslashes, or other directory separators (lines 23‑25).
- **Pattern matching**: Validates against the regex `^[a-z0-9][a-z0-9._-]*$` to ensure alphanumeric-starting, shell-safe names (lines 27‑29).

By rejecting identifiers containing `../` sequences or absolute path markers at the entry point, Modly prevents attackers from injecting traversal payloads through the extension ID itself.

### Canonical Resolution Inside Root Boundaries

The `resolvePathWithinRoot` function handles the second validation stage, ensuring that even manipulated relative paths cannot escape the designated extension directory. Operating within [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts), this function accepts a trusted `rootDir` and an `unsafeLeaf` parameter, then performs the following verification:

After constructing an absolute candidate path, it calculates the relative path from the root to the candidate (line 37). The critical security gate at line 41 rejects any resolution that:

- Results in an empty relative string (indicating the leaf resolved directly to the root).
- Equals `..` or begins with `../` (indicating upward directory escape).
- Resolves to an absolute path after normalization.

If any condition triggers, the function throws an exception immediately, guaranteeing the final path remains within the extension directory tree.

### The Combined Safe-Resolution API

To ensure consistent application of both validation layers, Modly exposes `resolveExtensionPathWithinRoot` (lines 48‑50 in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts)). This high-level function composes `assertSafeExtensionId` and `resolvePathWithinRoot` into a single call, requiring all public filesystem operations to pass both security checks.

Internally, [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts) leverages this API during extension installation, staging, and backup operations, ensuring that every file access respects the sandbox boundaries regardless of the operation type.

## Practical Security Examples

The following TypeScript examples demonstrate how Modly's path security handles legitimate extensions versus traversal attempts:

```typescript
import { resolveExtensionPathWithinRoot } from './electron/main/extension-path-guard.ts';

// Safe resolution: Valid extension ID resolved within the root directory
const safePath = resolveExtensionPathWithinRoot(
  '/usr/local/modly/extensions',
  'my_cool.extension-1'
);
// Returns: '/usr/local/modly/extensions/my_cool.extension-1'

```

Attempting to traverse upward using directory navigation in the extension ID triggers an immediate validation error:

```typescript
// Blocked at assertSafeExtensionId (lines 15-17, 23-25)
try {
  resolveExtensionPathWithinRoot(
    '/usr/local/modly/extensions',
    '../outside'
  );
} catch (e) {
  console.error(e.message); // Throws: Invalid extension ID
}

```

Even when bypassing the ID validation (internals only), the path resolution layer catches escapes:

```typescript
import { resolvePathWithinRoot } from './electron/main/extension-path-guard.ts';

// Blocked at line 41 during relative path calculation
try {
  resolvePathWithinRoot(
    '/usr/local/modly/extensions',
    '../../etc/passwd'
  );
} catch (e) {
  console.error(e.message); // Throws: Path escapes root directory
}

```

## Summary

- **Multi-layer validation**: Modly combines strict ID pattern matching (`assertSafeExtensionId`) with canonical path resolution (`resolvePathWithinRoot`) to create a defense-in-depth architecture.
- **Root confinement**: The resolution logic explicitly checks for `..` prefixes and absolute paths after normalization, ensuring all operations remain within [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts) defined boundaries.
- **Consistent API enforcement**: The `resolveExtensionPathWithinRoot` function ensures that installation utilities in [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts) and other callers cannot accidentally skip security checks.
- **Comprehensive test coverage**: Unit tests in [`electron/main/extension-path-guard.test.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.test.ts) verify that various traversal patterns are rejected before filesystem access occurs.

## Frequently Asked Questions

### What specific patterns does Modly block in extension identifiers?

Modly rejects any extension ID that is empty, equals `.` or `..`, contains path separators, starts with an absolute path marker, or fails to match the regex `^[a-z0-9][a-z0-9._-]*$`. These constraints prevent attackers from embedding `../` sequences or absolute paths directly into the identifier string before it reaches the filesystem layer.

### How does Modly prevent path traversal if an attacker bypasses the ID validation?

Even if an attacker somehow supplies a malicious relative path like `../../etc/passwd` to the internal `resolvePathWithinRoot` function, the code calculates the relative path from the trusted root and rejects any result that equals `..`, begins with `../`, or resolves to an absolute path (line 41 in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts)). This ensures the final resolved path never escapes the extension directory.

### Which Modly components rely on these path security functions?

The [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts) module uses these guards during extension installation, staging, and backup operations. Additionally, [`electron/main/extension-path-guard.test.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.test.ts) contains the unit test suite that continuously validates the security boundaries against traversal attempts.

### Can absolute paths ever be resolved by Modly's extension system?

No. The `assertSafeExtensionId` function explicitly blocks absolute paths at lines 19‑21, and `resolvePathWithinRoot` throws an exception if normalization results in an absolute path outside the root. Combined, these checks ensure that only relative, validated paths within the extension directory tree are accessible.