Open theGEBIRGE opened 2 months ago
Hey Frederic, Thanks for the detailed writeup!
I understand that allowing javascript and a wildcard access scope opens up a lot of surface area, But I think users, even in the case of malicious scripts, should be safe.
The reason I believe this is because I have the HttpAllowlistScope set here https://github.com/btpf/Alexandria/blob/main/src-tauri/tauri.conf.json#L28
https://tauri.app/v1/api/config/#httpallowlistconfig
So even if a malicious script reads a file off the FS, if working as intended, data could not send it out anywhere.
If I'm mistaken, or there are other security implications, please let me know so I can explore solutions.
Thanks
Hey, you're welcome!
That's a plausible assumption. After reading you're comment, I thought that maybe testing on localhost enabled me to make the HTTP request. Sadly, that's not what I'm observing.
After changing the script to make a request to webhook.site/...., it's still coming through.
I've looked into it a bit more. At first I thought Tauri would intercept every HTTP call, but after reading this, this and this I'm pretty sure that HttpAllowListConfig
is only respected by their own HTTP client.
The last link is for the beta of Tauri 2.0, but the design is probably the same. It says:
The current fetch method is an API to Rust backend. It tries to be as close and compliant to the fetch Web API as possible.
To me this sounds like I can use the Browser/WebView built-in fetch()
without having to worry about those restrictions?
I thought that maybe testing on localhost enabled me to make the HTTP request
I thought the same thing.
This webhook.site also looks great btw, I was looking for something like this last night.
To solve this problem, I have defined the CSP string in tauri's settings. https://tauri.app/v1/api/config/#csp
See: https://github.com/btpf/Alexandria/commit/c71161182f9a71c8be1f5070bebc0cefc35690ba
I think this should block all outbound requests to malicious URLs
I went ahead and ran a build for you, I would appreciate if you could run your testing again.
https://github.com/btpf/Alexandria/actions/runs/9010574904
Let me know if you spot anything and if the CSP solution is working.
Thanks
Hey,
I can verify that the CSP solution is working for inline scripts. However, inline styles are allowed, which may open up other possibilities. I don't have enough knowledge about that attack vector to give any informed opinion.
Why not set allowScriptedContent = false
at this point, because the CSP already blocks every inline script (which includes legit ones). CSP bypasses are a lot more common than flatout breaking the security guarentees of an iframe.
Personally, I'd allow the users to toggle that setting themselves.
Quick follow-up:
@johnfactotum provided an explanation for why CSP might be a better fit here.
To add,
However, inline styles are allowed, which may open up other possibilities.
This is generally OK, I believe. style-src
is only for the styles themselves. The resources that can be loaded by CSS would be governed by img-src
, font-src
, etc.
Also the CSP in c71161182f9a71c8be1f5070bebc0cefc35690ba probably needs to have data:
in img-src
or it would break images in FB2: https://github.com/btpf/Alexandria/blob/c71161182f9a71c8be1f5070bebc0cefc35690ba/src/shared/scripts/Parser/formats/fb2.ts#L313-L314
@theGEBIRGE Thanks for the follow up and raising awareness. I ran into the issues of iframe events not being propagated early on in development, and realized I had to keep scriptedContent enabled. As John said in the post you linked, annotations would not work and for Alexandria nor did page flipping (When clicking on the page). This would be the case on both linux and MacOS builds.
I think a CSP will be a better choice until this bug is resolved. https://bugs.webkit.org/show_bug.cgi?id=218086
@johnfactotum
Thanks for the clarification on style-src and once again solving a bug in Alexandria. Ill be sure to update the CSP to support data:
This issue will remain open for potential further discussion or until the next release for visibility.
Thanks!
Hey, I've discovered a vulnerability in
Alexandria
. I'm sticking to GitHub's default template for advisories (maybe consider adding aSECURITY.md
):Summary
An ebook containing malicious scripts has read-access to every file the current user has access to. The book needs to be opened by the user for this to work. Testing was done on version 0.12.0 on Windows.
Details
The
epub.js
configuration optionallowScriptedContent = true
makes it possible to execute arbitrary JavaScript code from within an epub file: https://github.com/btpf/Alexandria/blob/8221c77d793cab5c694707ea09f96ba41aaa3ba3/src/routes/Reader/ReaderView/ReaderView.tsx#L315epub.js
itself uses aniframe
to display the epubs. While it does set thesandbox
attribute, it also setsallow-same-origin
.This can't be changed by the consumer of the library. A combination of
allow-scripts
andallow-same-origin
renders the sandboxing obsolete (see here).The developers of
epub.js
warn about this.In the case of
Alexandria
, every function annotated with#[tauri::command]
is accessible to the script. An attacker might get creative with those, especially if more get added.I've chosen a different route:
Tauri
is configured to enable the customasset
protocol: https://github.com/btpf/Alexandria/blob/8221c77d793cab5c694707ea09f96ba41aaa3ba3/src-tauri/tauri.conf.json#L24Because a wildcard is used, every file accessible to the user can be served that way. Using
fetch
orXMLHttpRequest
, the file contents can then be exfiltrated (see PoC video).PoC
An ebook can be crafted with Calibre to include this bare minimum script (with a different file path):
Impact
Users have to download a malicious book and open it, so the impact is not that severe. However, the attacker doesn't have to prepare a book specifically for
Alexandria
, but can use some fingerprinting to determine in what environment it's running.Distribution of malicious books could be done via pirate sites or even (online) conversion services, which could inject those malicious scripts.
Overall, I wouldn't be too worried. :^)
Some ideas
In an ideal world, scripted content would be turned off. There are, however, limitations with that approach. The author of
foliate
sums it up nicely here. Maybe the user could be given the option to toggle scripted content.Furthermore, the
asset
protocol could be confined to known paths.That's it! If something's unclear, please ask away.
Cheers Frederic
PS: Audio warning for the PoC video!
https://github.com/btpf/Alexandria/assets/36849099/80ebad37-761b-40ce-bd50-5a5723545d8b