
Angular Expression Injection Leading to XSS Without HTML
- Product: GitBlit (gitblit-org/gitblit)
- Affected Versions: All versions ≤ 1.10.0 (latest release)
- Patched Versions: N/A
- Severity: High - CVSS 8.7
- CVSS Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N
- Weakness: CWE-1336 (Improper Neutralization of Special Elements in Template Engine)
- Disclosed: 27 November, 2025, 90 day disclosure window elapsed without vendor response
Executive Summary
A critical Client-Side Template Injection (CSTI) vulnerability exists in all released versions of GitBlit, a widely deployed open-source Java Git server. The vulnerability arises from AngularJS being scoped to the entire web application while user-controlled input is reflected into the page without sanitization. An attacker can inject arbitrary AngularJS expressions via a crafted URL parameter, achieving JavaScript execution in the context of the victim's browser without requiring any HTML injection.
This vulnerability was discovered during a routine penetration test conducted by Hadrian Security. All versions through the latest release (1.10.0) are confirmed affected. The vendor has been unresponsive across all disclosure channels since 27 November 2025. Full technical details are being released following the lapse of the standard 90-day coordinated disclosure window.
Impact: Successful exploitation allows an attacker to perform any action the victim user can perform, read sensitive repository data, exfiltrate credentials, and conduct persistent attacks against other authenticated users ,all without any HTML injection.
Background: What Is GitBlit?
GitBlit is a lightweight, self-hosted Git server written in Java. It provides repository hosting, a web UI, LDAP integration, and user/role management. The application uses an embedded Jetty server and is commonly deployed on port 8080. It is a popular choice for enterprises, legacy internal infrastructure, and development environments seeking a simpler alternative to GitLab or GitHub Enterprise.
As of disclosure, GitBlit has over 2,300 stars on GitHub. Internet-wide scanning data (Shodan) reveals thousands of publicly accessible instances across multiple versions, the majority of which are unpatched and exposed to the internet.
Technical Analysis
Vulnerability Root Cause
The vulnerability stems from two compounding conditions:
- AngularJS is initialized with scope bound to the entire application document rather than a contained component.
- User-controlled input from HTTP query parameters is reflected directly into the rendered page without sanitization or encoding.
The relevant Java code path in GitBlit's Wicket-based web framework iterates over URL query parameters and attempts to match them to existing page components:
if (pageParameters != null) {
for (String key : pageParameters.keySet()) {
Component c = get(key);
if (c != null) {
// this form has a field id which matches the
// parameter key, so the value is reflected into the component
When a query parameter key matches a component ID, the parameter value is reflected into the rendered HTML. Because AngularJS processes template expressions across the entire document scope, any AngularJS expression syntax in the reflected value is evaluated by the framework prior to output.
Why Standard XSS Defenses Fail
Traditional XSS mitigations operate at the HTML layer, escaping angle brackets, quotes, and script tags. CSTI operates at a layer above this. The injection occurs within AngularJS template expression delimiters ({{ }}) which the framework evaluates as JavaScript before the page is fully rendered. An application can be fully protected against HTML injection and still be vulnerable to CSTI if user input is reflected into an AngularJS-scoped document.
This is the core insight described by Gareth Heyes in the PortSwigger research on XSS without HTML, the AngularJS template engine itself becomes the execution surface.
Proof of Concept
The vulnerability is trivially reproducible against any publicly accessible GitBlit instance. No authentication is required.
Reproduction Steps
- Identify a target running GitBlit (any version ≤ 1.10.0).
- Navigate to the following URL, substituting the target hostname:
http://[TARGET HOST]/?a=%7B%7Bconstructor.constructor(%27alert(1)%27)()%7D%7D
- Observe JavaScript execution via the alert dialogue.
URL-decoded, the injected value is:
{{constructor.constructor('alert(1)')()}}
The expression accesses the Function constructor through the Angular scope's prototype chain and invokes it to execute arbitrary JavaScript. This technique bypasses Angular sandbox implementations where they exist and is effective across AngularJS versions that scope the entire document.
Impact Assessment
Successful exploitation of this vulnerability against an authenticated user allows an attacker to:
- Perform any action within the application that the victim user is authorized to perform, including repository access, cloning, pushing, and administrative actions if the victim holds elevated privileges.
- Exfiltrate any data visible to the victim, including source code, credentials stored in repositories, CI/CD configurations, and private repository content.
- Modify repository content, settings, or user data accessible to the victim's session.
- Launch attacks against other authenticated users that appear to originate from the victim, facilitating horizontal privilege escalation and persistent access.
- Steal session tokens or inject persistent malicious scripts if the application stores any state in accessible storage.
Because GitBlit is frequently deployed on internal infrastructure with elevated trust assumptions, often containing proprietary source code, infrastructure configurations, and sensitive credentials committed to repositories, the practical impact of exploitation in enterprise environments is severe.
Coordinated Disclosure Timeline
The vendor did not respond to any contact attempts across GitHub Security Advisories, email, or social media over the full 90-day disclosure window. The project appears to be unmaintained. No patch is available.
- 27 Nov 2025 (12:45): Vulnerability discovered during an authorized penetration test.
- 27 Nov 2025 (15:54): GitHub Security Advisory (GHSA-rg9h-f6mh-j6wp) opened and the vendor was notified.
- 01 Dec 2025 (12:18): Follow-up email sent to the vendor's security address including a full Proof of Concept (PoC).
- 08 Dec 2025: Dutch Institute of Vulnerability Disclosure (DIVD) notified.
- 14 Dec 2025 (18:18): Attempted to contact maintainer James Moger via Twitter/X.
- 18 Dec 2025: GHSA thread bumped; no response received.
- 21 Dec 2025 (12:27): Attempted to contact maintainer flaix via Twitter/X.
- 27 Dec 2025 (15:02): Second follow-up email sent and GHSA thread bumped again.
- 25 Feb 2026 (13:09): The 90-day disclosure window elapsed. CVE ID requested from MITRE and public disclosure initiated.
Mitigation Guidance
As no patch is available from the vendor, organizations running GitBlit should consider the following mitigations:
Immediate Actions
- Restrict public access to GitBlit instances ,place them behind a VPN or network access control if they are currently internet-exposed.
- Disable anonymous access if enabled. Reducing the user population limits the phishing surface for CSTI-based attacks.
- Implement a Web Application Firewall (WAF) rule to block requests containing AngularJS template expression syntax ({{ }}) in query parameters as a defense-in-depth measure.
Longer-Term Recommendations
- Evaluate migration to an actively maintained Git hosting platform (Gitea, Forgejo, GitLab CE) given that GitBlit appears unmaintained and carries an unpatched critical vulnerability.
- Audit commit history and repository access logs for any indication of unauthorized access, particularly if the instance was publicly accessible.
- Rotate any credentials, tokens, or secrets stored in repositories hosted on affected instances as a precautionary measure.







