The vulnerability is a stored Cross-Site Scripting (XSS) issue in Phraseanet 4.0.3, identified as CVE-2018-25157. The root cause is the application's failure to properly sanitize user-controlled input, specifically filenames, before storing and displaying them. An authenticated attacker could upload a file with a specially crafted name containing malicious JavaScript code. When this file, or its metadata (like the title), is viewed by other users, the embedded script executes in their browser, potentially leading to session hijacking, data theft, or other malicious actions.
My analysis of the patches between the vulnerable version (4.0.3) and the fixed version (4.0.7) reveals several key changes that address this vulnerability:
-
Input Sanitization: The most direct fix is in lib/Alchemy/Phrasea/Filesystem/LazaretPathBooker.php, where the bookFile function is modified to strip non-alphanumeric characters from filenames using preg_replace. This prevents malicious characters from being saved in the first place.
-
Output Escaping: Multiple files were patched to apply output escaping. For example, in lib/classes/record/adapter.php, the getTitle function now uses htmlspecialchars to escape the record title before it's displayed. Similarly, in Twig templates like templates/web/prod/results/record.html.twig, the |e filter (which is Twig's auto-escaping mechanism) is added to variables that display record titles and other user-provided data.
-
Client-Side Encoding: In templates/web/prod/upload/upload.html.twig, the filename is now encoded using encodeURI on the client-side before being sent to the server. This adds another layer of protection.
By identifying these changes, I have pinpointed the functions that were directly involved in the vulnerability. These functions would appear in a runtime profile when the vulnerability is triggered, as they are responsible for processing the malicious input and rendering it in the application.