HIGH symlink attackfeathersjscockroachdb

Symlink Attack in Feathersjs with Cockroachdb

Symlink Attack in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

A symlink attack in a Feathersjs service backed by Cockroachdb can occur when user-supplied file paths or URLs are used to interact with the filesystem without canonicalization or strict validation. Feathersjs services often handle file uploads, references, or dynamic route parameters that may be stored or processed by backend logic. If these values are used to construct filesystem paths (for example, to read uploaded files, logs, or assets) and are passed directly to utilities like fs.readFile or fs.stat, an attacker may provide a path containing a symbolic link (e.g., ../../../etc/passwd) that traverses outside the intended directory. Cockroachdb, being a distributed SQL database, typically stores file metadata, paths, or references as strings; it does not enforce filesystem semantics. Therefore, if a Feathersjs service stores user-controlled path-like data in Cockroachdb and later uses it to resolve files on disk, the service becomes vulnerable to path traversal and symlink-based attacks. An attacker might first upload a file via a seemingly benign endpoint (e.g., a profile picture upload), coaxing the service to store a reference to a path under attacker control. Later, a crafted request to a different Feathersjs endpoint that reads from that stored path can cause the service to follow a malicious symlink, revealing sensitive files or enabling unauthorized data access. Because Feathersjs is framework-agnostic about storage, developers may assume database-stored paths are safe, but without server-side validation and canonicalization, the combination of Feathersjs dynamic services and Cockroachdb-stored references creates an exploitable chain. The database faithfully returns the path string, and the server-side filesystem operations act on it, enabling unintended file access. This risk is especially relevant when services use relative paths or concatenate user input with base directories. The attack surface is not in Cockroachdb itself but in how Feathersjs resolves paths before issuing filesystem calls, where missing checks allow directory traversal and symlink following. Attack patterns such as Path Traversal map directly to this scenario, and related findings may be surfaced by scanners aligned with the OWASP API Top 10.

Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on ensuring that any path derived from user input is canonicalized, scoped to an allowed directory, and never directly stored or used as a filesystem target based solely on database content. In Feathersjs, implement path validation in service hooks before any filesystem operation. Use Node.js built-in path utilities to resolve and verify locations. For example, when handling file references stored in Cockroachdb, resolve the intended base directory and ensure the final path remains within it.

const path = require('path');
const fs = require('fs').promises;

function safeFilePath(userSuppliedPath) {
  const base = path.resolve('/srv/app/uploads');
  const target = path.resolve(base, userSuppliedPath);
  if (!target.startsWith(base + path.sep) && target !== base) {
    throw new Error('Invalid path: traversal attempt');
  }
  return target;
}

// Feathersjs before hook example
app.service('documents').hooks({
  before: {
    async get(context) {
      const { id } = context.params.query;
      // Assume Cockroachdb stores a relative path in 'filePath'
      const row = await context.app.get('dbClient').query('SELECT filePath FROM documents WHERE id = $1', [id]);
      if (!row.rowCount) throw new Error('Not found');
      const fullPath = safeFilePath(row.rows[0].filepath);
      const content = await fs.readFile(fullPath, 'utf-8');
      context.result = { content };
      return context;
    }
  }
});

When storing paths in Cockroachdb, prefer storing a stable identifier or a normalized relative path that is resolved only against a strict base directory at read time. Avoid storing absolute paths or allowing user input to dictate directory components. If your Feathersjs service must accept file uploads, generate server-side filenames and store only the generated name in Cockroachdb, never the user-provided filename directly.

Additionally, apply the principle of least privilege to the process running Feathersjs filesystem operations. Even if a symlink exists outside the allowed directory, filesystem permissions should prevent read access to sensitive files. Combine runtime path validation with OS-level controls. For services that also expose download endpoints, ensure that Content-Disposition headers are set appropriately and that filenames are sanitized to prevent header injection.

Frequently Asked Questions

Can storing paths in Cockroachdb alone cause a symlink attack?
No. Storing paths in Cockroachdb is safe as long as the Feathersjs service does not blindly use those paths in filesystem operations without validation and canonicalization. The vulnerability arises when user-influenced path strings are resolved against the filesystem.
Does middleBrick detect symlink-related misconfigurations in Feathersjs services?
middleBrick scans unauthenticated attack surfaces and can identify findings related to authentication, authorization, input validation, and security configurations that may expose symlink risks. Findings include severity and remediation guidance mapped to frameworks such as OWASP API Top 10.