Skip to content

Unrestricted File Upload Leading to Cross-Account XSS and Session Hijack in Monica CRM #7959

Description

@bshakeel86

⚠️ This issue respects the following points: ⚠️

  • This is a bug, not a question or a configuration/webserver/proxy issue.
  • This issue is not already reported on Github (I've searched it).
  • I agree to follow Monica's Code of Conduct.

Bug description

Monica CRM (v4.1.2, latest stable release) contains an unrestricted file upload vulnerability in the document upload endpoint ( POST /api/documents ). The application accepts files of any MIME type and extension with no validation, stores them in a publicly accessible directory served by Apache without authentication, and serves uploaded HTML files with Content-Type: text/html — causing browsers to execute embedded JavaScript in Monica's origin. An attacker with any valid Monica account (no admin rights required) can upload a malicious HTML file disguised as a business document, send the public URL to a logged-in victim, and silently exfiltrate all CRM contact data plus session tokens — enabling full account takeover. Introduced in PR #1912 and present in every release from v2.10.0 through v4.1.2.

Steps to reproduce

Two Monica accounts required — attacker ( user@test.local , any
privilege level) and victim ( admin@test.local , logged in with active
session).

  1. Create malicious payload file — Create Q1-2025-Report.html
    containing a JavaScript fetch to /api/contacts with
    credentials:'include' . The file is disguised as a quarterly
    business report.

  2. Attacker uploads the file — Log in as attacker and upload Q1-
    2025-Report.html via POST /api/documents . Monica returns HTTP
    201 with "mime_type": "text/html" — no validation error.

  3. Confirm unauthenticated access — Access the public URL
    /storage/documents/.html without any cookies. Returns
    HTTP 200 with Content-Type: text/html .

  4. Attacker sends link to victim — URL is on Monica's own trusted
    domain. Framed as: "Hey, check this Q1 2025 business report."

  5. Victim clicks the link — XSS fires — JavaScript executes in
    Monica's origin. Victim's session cookie is auto-sent with the fetch
    call. All CRM contacts and XSRF-TOKEN are returned and
    displayed.

Impact:

An attacker with any Monica account can silently steal all CRM contact
records, session tokens, and private notes from any logged-in user who
clicks a link. The captured XSRF-TOKEN and session cookies grant
persistent API access to the victim's entire account without knowing their
password. The attack requires one click, leaves no trace for the victim,
and the malicious URL is hosted on Monica's own trusted domain —
making it indistinguishable from a legitimate link. All personal relationship
data stored in Monica (contact names, phone numbers, addresses, notes,
journal entries) is at risk of exfiltration and the victim's account is fully
compromised.

Expected behavior

Recommended Remediation:
1 — Whitelist safe file types in
app/Services/Contact/Document/UploadDocument.php :
$request->validate([
'document' => ['required', 'file', 'mimes:pdf,doc,docx,jpg,jpeg,p
]);
2 — Require authentication to access uploaded files — serve files
through an authenticated controller route rather than directly from the
public filesystem.
3 — Force download for all uploaded files — set Content
Disposition: attachment and X-Content-Type-Options: nosniff
headers on the /storage/documents/ path to prevent browsers from
executing uploaded content.

Environment

app.monicahq.com (monica v4)

Version of Monica

4.1.2

Installation method

None

Web server

None

Database engine version

None

Additional info

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions