Stored Cross-site Scripting in Pentestify user account deletion via unescaped username
Description
Improper Neutralization of Input During Web Page Generation (Cross-site Scripting) (CWE-79), stored, in the frontend user management component (js/app.js) and in the CreateUserRequest input schema (backend/schemas.py), exposed at POST /api/users and rendered on the Account page, in Pentestify 1.1.0, which allows an authenticated user to execute arbitrary JavaScript in the browser of another authenticated user via a crafted username, because the username field was declared as str with no validator and no allowlist, was persisted verbatim, and was interpolated by the frontend inside a JavaScript string literal in the account deletion button's onclick attribute (js/app.js:1923), where the sanitization applied was ineffective: escapeHTML() converts the single quote to ' and the subsequent replace, intended to escape literal quotes, then finds none, so the HTML parser decodes the entity back to ' before the JavaScript engine parses the handler, closing the string literal and injecting executable code, unlike line 1918 of that same view, which renders the same value through escapeHTML() in a text context and is not exploitable. This results in arbitrary JavaScript execution in the application origin, in the browser of the user who clicks the deletion button for the crafted account. The proof of concept demonstrates execution of the injected code: it does not demonstrate session access or data exfiltration.
Vulnerability type (CWE)
CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Affected versions
Pentestify before 1.1.1 (fixed in 1.1.1 by commit 714e05e, dated 2026-06-25). The sink was introduced along with user management in commit 2a1551b (2026-06-20), at version 1.0.0, and was present in versions 1.0.0 and 1.1.0. Neither of those versions carries a git tag: v1.1.1 is the earliest tag in the repository and already contains the fix, so no tagged release shipped in a vulnerable state. Versions are read from the APP_VERSION constant in js/app.js. Default status: unaffected.
Score (CVSS 4.0)
Medium (5.1)
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N
Solution
Upgrade to version 1.1.1 or higher.
Patch
Commit 714e05e
Credits
- Marcos García (s3ntinl) - finder
- Xoán M. Otero Jorge - analyst
- Darío Rivas Quero - analyst
- Secur0 CNA - coordinator
- Mario Álvarez Fernández - remediation developer Discovery source: External Official record: CVE-2026-19716