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/passwdand 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?
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?
- 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