Skip to content

[LOW] Markdown links from untrusted peer messages can launch tel: and unverified custom (whitenoise://) schemes — dialer-prefill phishing / cross-app deep-link #189

@erskingardner

Description

@erskingardner

Severity: LOW

Summary

The markdown link allowlist used to render untrusted peer message bodies includes tel: and the custom whitenoise:// / whitenoise-staging:// schemes. Tapping such a link fires ACTION_VIEW with attacker-controlled content from a chat message.

Evidence

app/src/main/java/dev/ipf/darkmatter/ui/MarkdownRenderer.kt

private val openableMarkdownLinkSchemes = setOf("http", "https", "mailto", "tel", "whitenoise", "whitenoise-staging")

The link scheme gate is otherwise well-hardened (it correctly rejects javascript:, data:, file:, intent:, etc., normalizes whitespace/case, and re-validates at launch time). The remaining concern is the two entries above:

  • tel: — a peer can send [Call support](tel:+1900...) or label a link deceptively ([+1 555-0000](tel:+1 900-...)). Tapping opens the dialer pre-filled with the attacker's number. (It is ACTION_VIEW, not ACTION_CALL, and the app holds no CALL_PHONE permission, so a manual dial press is still required — hence LOW — but the mislabeled-destination is a classic phishing primitive.)
  • whitenoise:// / whitenoise-staging:// — custom schemes are not domain-verified (unlike https App Links), so any installed app can register them. A peer-crafted link can drive the user into an arbitrary (possibly hostile) handler with an attacker-controlled path.

Impact

Social-engineering from chat content: dialer-prefill phishing via tel:, and cross-app deep-linking into an unverified handler via the custom schemes.

Suggested fix

  • Reconsider whether tel: belongs in chat-message links; if kept, render the resolved phone number as the visible affordance rather than trusting the link label.
  • If the whitenoise schemes target a specific sibling app, set the target package on the Intent (or validate the URI structure) instead of allowlisting the bare scheme for any handler. Confirm cross-app deep-linking from untrusted content is intended.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions