> This mobile app is a viewer/editor for Org Mode files. Users can open Org
Mode files accessible on local storage, through OS file provider APIs
(Dropbox-style file stores), or by providing an HTTP URL to a remote file.
It also accepts deep links like orgro.org/manual to open the manual.
It originally also accepted orgro.org/web?url=https://example.com to
facilitate opening remote Org Mode documents. However I did not ship this as
I was worried that it was the moral equivalent of an open proxy, and because
Org Mode documents can contain inline images that are loaded automatically
it can also trick users into divulging information like IP addresses
(imagine a user being tricked into opening an
orgro.org/web?url=https://evil-tracking-website.com link).
Are my concerns about the /web deep link feature founded, or is it a
reasonable feature to have? If it is potentially dangerous, is there a way
to implement the feature safely?
Security Analysis of Remote Deep Links:
Researching current remote file and image loading implementation to
evaluate security concerns.
✓ SearchText 'http|HttpClient|Dio|getUrl|fromUri' in lib/**/*.dart
→ Found 73 matches
✓ SearchText 'Image|NetworkImage|Image.network' in lib/**/*.dart
→ Found 100 matches (limited)
✓ SearchText 'orgro\.org/web|orgro\.org/manual' → Found 15 matches
✓ SearchText 'manual|web' in lib/**/*.dart → Found 92 matches
✓ ReadFile lib/src/routes/routes.dart
✓ SearchText 'RemoteImagePermissionsBanner' → Found 3 matches
✓ ReadFile lib/.../document/document.dart
→ Read lines 300-450 of 917 from lib/src/pages/document/document.dart
✓ SearchText 'bool get _askPermissionToLoadRemoteImages' → Found 1 match
✓ SearchText 'enum RemoteImagesPolicy' → Found 1 match
✓ ReadFile lib/src/navigation.dart
✓ ReadFile lib/src/pages/start/util.dart
✓ SearchText 'Open from URL' → No matches found
✓ SearchText 'menuItemOpenUrl' → Found 15 matches
✓ ReadFile lib/src/pages/start/start.dart
→ Read lines 60-110 of 398 from lib/src/pages/start/start.dart
✓ SearchText '_promptAndOpenUrl' → Found 4 matches
✓ ReadFile lib/src/pages/start/start.dart
→ Read lines 280-320 of 398 from lib/src/pages/start/start.dart
✦ Your concerns regarding the /web?url=... deep link feature are well-founded
and reflect a strong security-first mindset. Implementing this feature without
proper safeguards would indeed introduce several risks.
Analysis of the Risks
1. Privacy & IP Leakage (Pixel Tracking):
* The Leak: Even if you don't load images, the initial request to fetch
the Org document at the provided URL informs the remote server that a
user (at a specific IP) has opened the file.
* Automated Triggers: As you noted, Org Mode's support for inline images
([[https://example.com/image.png]]) makes this worse. An attacker could
craft a link like orgro.org/web?url=https://attacker.com/track.org
where track.org contains unique tracking pixels.
* Current State: Orgro already has a partial mitigation for this: the
RemoteImagePermissionsBanner (found in
lib/src/pages/document/document.dart) asks the user before loading
remote images. However, the initial .org file fetch is still a "ping."
2. App-Side SSRF (Server-Side Request Forgery):
* While not a traditional server-side vulnerability, this allows an
attacker to use a user's device as a "jumping-off" point.
* Internal Probing: An attacker could send a link like
orgro.org/web?url=http://192.168.1.1/admin. If the user is on their
home network, the Orgro app might reach internal services that the
attacker cannot access directly.
3. Open Redirect / Domain Reputation:
* Using orgro.org as a gateway to arbitrary content can be exploited to
bypass URL filters in other apps (e.g., a corporate firewall might
block malicious.com but allow orgro.org).
Is it a "Reasonable" Feature?
Yes, it is a very useful feature for sharing documents, but it requires
high-intent confirmation. The danger lies in the "one-click" nature of deep
links.
How to Implement it Safely
If you decide to re-enable this feature, I recommend the following "defense in
depth" strategy:
1. The Interstitial Confirmation (Mandatory)
Never open the remote file immediately. Instead, show a dialog or an
interstitial page that explains what is happening:
> "Open Remote Document?"
> "You followed a link to a remote document at:
https://example.com/important.org.
> Opening this will reveal your IP address to that server."
> [ Cancel ] [ Open Document ]
2. Strict Privacy Defaults for Web-Loaded Files
When a document is opened via a deep link, you should override the global
remote_images_policy and set it to deny for that session, regardless of the
user's default setting. This ensures that even if they agree to fetch the .org
file, they aren't automatically loading tracking pixels within it.
3. Distinct User-Agent
Use a custom User-Agent header (e.g., Orgro-Fetcher/1.0 (Mobile; DeepLink))
when fetching the remote file. This allows site owners to identify the traffic
and allows you to block malicious use-cases if they arise.
4. Restrict Protocols
Ensure the url parameter only accepts http or https. Do not allow file:// or
other schemes that might be used to exfiltrate local data.
Recommendation
The feature is worth having if you prioritize user consent. If you implement
an interstitial confirmation that clearly displays the target URL and its
implications, you effectively neutralize the "stealth" tracking and SSRF
concerns, as the user becomes an active participant in the security decision.
Orgro currently accepts https://orgro.org/manual as a "deep" link that opens the manual in the app. Initially I also implemented "web" deep links like https://orgro.org/web?url=https://example.com but removed this because of security concerns (2e45394).
I looked a bit into a way to do this feature safely: