HIGH zip slipcockroachdb

Zip Slip in Cockroachdb

How Zip Slip Manifests in CockroachDB

Zip Slip is a path traversal vulnerability where an attacker manipulates file archive entries (e.g., in a ZIP file) to write files to unintended locations outside the target directory. In CockroachDB, this risk surfaces primarily through two integrated features: the IMPORT command (for bulk data import) and the pg_catalog.pg_read_file() function (for reading server files).

Attack Pattern via IMPORT: When IMPORT processes a ZIP archive containing CSV or Avro data, it extracts files to a temporary directory on the server node. If the archive includes entries with paths like ../../../etc/passwd or absolute paths (e.g., /var/lib/cockroach/evil.sql), CockroachDB's extraction logic may follow these paths, overwriting critical configuration files or injecting SQL scripts. This is particularly dangerous in multi-tenant setups where a compromised tenant could escape their logical isolation.

Attack Pattern via pg_read_file(): While pg_read_file() is a read-only function, it often pairs with COPY ... FROM PROGRAM (where supported) or user-defined functions that write output. An attacker with SQL injection (e.g., via an API endpoint with BOLA/IDOR flaws) could execute: SELECT pg_read_file('../../../etc/passwd'); to read sensitive files, then use COPY ... TO PROGRAM or pg_write_file() (if enabled) to write extracted data to arbitrary locations. Even without write primitives, reading files like /etc/shadow or cockroach-data/security/keys/ exposes credentials.

CockroachDB-Specific Nuance: CockroachDB's IMPORT uses Go's archive/zip package under the hood. If the server's file extraction does not sanitize the Name field in zip.File structures (checking for .. or absolute paths), Zip Slip occurs. Additionally, CockroachDB's distributed nature means the vulnerable node processing the IMPORT might have different filesystem semantics (e.g., Windows vs. Linux), affecting path resolution.

CockroachDB-Specific Detection

Detecting Zip Slip in CockroachDB requires both static analysis of SQL/application code and dynamic testing of runtime endpoints. middleBrick's security scanner includes specific checks for this under its Input Validation and Data Exposure categories.

1. Scan for IMPORT Usage in API Endpoints: Identify any API routes that accept file uploads (e.g., POST /api/v1/import) and trigger a CockroachDB IMPORT command. Look for code that constructs the import query without validating the archive's internal file paths. Example vulnerable pattern in a Node.js/Express app:

app.post('/import', async (req, res) => {
  const zipBuffer = req.files.archive.data;
  // Store zip temporarily
  await fs.writeFile('/tmp/upload.zip', zipBuffer);
  // Directly pass user-controlled path to IMPORT
  const sql = `IMPORT INTO mytable CSV DATA ('file:///tmp/upload.zip')`;
  await db.exec(sql); // VULNERABLE if zip contains '../evil.csv'
});

2. Test for pg_read_file() Execution: Check if any API endpoint allows arbitrary SQL execution (e.g., GraphQL resolvers, search filters with SQL injection). middleBrick actively probes for this by attempting to read cockroach-data/security/security_settings.json (a known sensitive file in CockroachDB clusters) via payloads like: ' UNION SELECT pg_read_file(' cockroach-data/security/security_settings.json')--. Successful exfiltration indicates a path traversal + SQL injection chain.

3. Use middleBrick for Comprehensive Scanning: Submit your API endpoint URL to middleBrick. Its black-box scanner will:

  • Attempt to upload a crafted ZIP file with entries like ../../../../etc/passwd and monitor for file writes or error messages indicating path traversal.
  • Probe for pg_read_file() access via injection points, checking if sensitive CockroachDB file paths are readable.
  • Cross-reference findings with your OpenAPI spec to pinpoint which endpoints and parameters are vulnerable.

The scanner returns a risk score with per-category breakdowns; a finding in Input Validation with references to IMPORT or pg_read_file signals a Zip Slip risk.

CockroachDB-Specific Remediation

Remediation must occur at both the application layer (before data reaches CockroachDB) and, where possible, within CockroachDB's configuration.

1. Sanitize ZIP Entries in Application Code: Before passing any uploaded archive to IMPORT, extract and validate each file's path. Reject entries containing .., absolute paths, or symlinks. Example in Node.js using the yauzl library:

const yauzl = require('yauzl');
async function safeImport(zipBuffer) {
  return new Promise((resolve, reject) => {
    yauzl.fromBuffer(zipBuffer, { lazyEntries: true }, (err, zipfile) => {
      if (err) return reject(err);
      zipfile.readEntry();
      zipfile.on('entry', (entry) => {
        // Normalize and check for path traversal
        const normalized = path.normalize(entry.fileName);
        if (normalized.includes('..') || path.isAbsolute(normalized)) {
          return reject(new Error('Invalid zip entry: ' + entry.fileName));
        }
        zipfile.readEntry();
      });
      zipfile.on('end', async () => {
        // Proceed with IMPORT only if all entries are safe
        await db.exec(`IMPORT INTO mytable CSV DATA ('file:///tmp/upload.zip')`);
        resolve();
      });
    });
  });
}

2. Restrict pg_read_file() Access: CockroachDB inherits PostgreSQL's pg_read_server_files role. Revoke this role from all non-admin users and roles. In cockroach sql:

REVOKE pg_read_server_files FROM PUBLIC;
REVOKE pg_read_server_files FROM myapp_user;

Ensure your application's database user has minimal privileges—only CONNECT, SELECT on necessary tables, and IMPORT if absolutely required. Never use superuser or admin roles for application connections.

3. Use IMPORT with INTO Table Restrictions: When possible, import into a staging table first, then validate data before merging into production tables. This limits impact if a malicious file is imported.

4. File System Permissions: Run CockroachDB under a dedicated OS user with restrictive permissions. The cockroach-data directory should be writable only by this user, preventing overwritten files from being executed if an attacker plants a script.

5. Validate OpenAPI Specs: If your API uses an OpenAPI spec, mark file upload parameters with proper format: binary and document expected archive types. middleBrick's spec analyzer will flag endpoints that accept uploads but lack such constraints, helping you identify risky paths early in development.

Frequently Asked Questions

Can middleBrick detect Zip Slip vulnerabilities in my CockroachDB-backed API without credentials?
Yes. middleBrick performs unauthenticated black-box scanning. It will test your publicly accessible API endpoints by submitting crafted ZIP files and probing for path traversal via IMPORT or pg_read_file() execution through injection points. No database credentials are needed—only the API URL.
How do I integrate Zip Slip checks into my CI/CD pipeline for a CockroachDB service?
Use middleBrick's GitHub Action. Add it to your workflow to scan staging API endpoints on every pull request. Configure it to fail the build if the Input Validation score drops below a threshold (e.g., 'B') or if specific Zip Slip findings are detected. Example:
- name: Run middleBrick Scan
  uses: middlebrick/github-action@v1
  with:
    url: ${{ secrets.STAGING_API_URL }}
    fail_on_score_below: B
    fail_on_categories: Input Validation