Open Sim4n6 opened 7 months ago
Issue submitted after via email you requested that I do so.
I would also suggest enabling private vulnerability reporting : https://docs.github.com/en/code-security/security-advisories/working-with-repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository
Summary
Unicode characters used in a user-controlled filename may cause an application level DoS in infobyte/faraday when a report upload is performed to create data within the given workspace.
Details
I noticed that the user-controlled filename can reach a costly Unicode normalization operation.
The filename may carry a huge Unicode characters and may cause denial of service since the call to
secure_filename()
uses a costly Unicode compatibility normalization (underneath).This could get worse with Unicode characters like U+2100 (℀), or U+2105 (℅) which when Unicode compatibility normalized becomes three characters thus tripling the size of the filename.
The Vulnerable Flow Path
faraday/server/api/modules/upload_[reports.py](http://reports.py/)
faraday/server/api/modules/upload_[reports.py](http://reports.py/)
faraday/server/api/modules/upload_[reports.py](http://reports.py/)
faraday/server/api/modules/upload_[reports.py](http://reports.py/)
faraday/server/api/modules/upload_[reports.py](http://reports.py/)
Path with 5 steps
1. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L17C5-L17C12) 2. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L17C5-L17C12) 3. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L81C27-L81C34) 4. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L85C9-L85C20) 5. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L96C70-L96C90)Path with 5 steps
1. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L17C5-L17C12) 2. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L17C5-L17C12) 3. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L85C23-L85C30) 4. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L85C9-L85C20) 5. [faraday/server/api/modules/upload_[reports.py](http://reports.py/)](https://github.com/infobyte/faraday/blob/952e6d6af4aea2847cebad1573345f5b29fe3574/faraday/server/api/modules/upload_reports.py#L96C70-L96C90) # PoC As a proof of concept, I would use the following python script: ```python import requests import sys # Adjust the URL accordingly url = "https://valid_instance/" dangerous_size = 5_000_000 files = {"file": ("℁" * dangerous_size + ".bmp", open("titre.jpg", "rb"))} # Adjust the file path response = [requests.post](http://requests.post/)( url, files=files ) print(response.status_code, [response.elapsed.total](http://response.elapsed.total/)_seconds()) ``` This would cause the application to take an endless time to handle a single POST request. # Remediation - The fix could be as simple as limiting the incoming filename to 1000 characters as a maximum. This is similar to CVE-2023-46695 in Django codebase and https://hackerone.com/reports/2258758 # Impact - Server-side denial of service due to an attack similar to the "One Million Unicode". Regards, @sim4n6