libkiwix
libkiwix copied to clipboard
Relax the Content-Security-Policy to allow `mailto:` links in the Kiwix Serve iframe
This relates to issue https://github.com/kiwix/kiwix-tools/issues/680 on Kiwix Tools. Most links that are not considered secure are blocked by the CSP and/or sandbox, and that includes mailto: links, which are blocked in Chromium browsers (whereas they seem not be blocked by Firefox). This also affects Kiwix JS Browser Extension and the PWA.
I have determined (in the PWA) that relaxing the CSP for the content in the iframe should fix this. All that is needed is to add mailto: to the list of exceptions in the internalServer.cpp code. I am pretty sure it won't be necessary to alter the CSP of the outer document, but that would need testing. The code is here:
https://github.com/kiwix/libkiwix/blob/main/src/server/internalServer.cpp#L1110
A Zimit2 ZIM with a maitlo: link is given in the linked issue for testing.
As there are plenty of other protocols, like magnet:, maps:, zoomus: and indeed an infinity of such protocols that Web manifests can define for Web apps, it might be worth considering making any PR addressing this issue more generic. As @benoit74 explains in https://github.com/kiwix/libkiwix/issues/1138, Zimit2 won't rewrite these, so it should be safe just to compare the protocol of the article document's defaultView (the window of the iframe) with the protocol of the clicked link, and process it as an external link if they differ. This would only cover static cases, but that will be the vast majority. In the case of mailto: if the suggestion here to add it to the CSP accepted protocols list is accepted, then that would be excluded from any more generic function.
This may be a separate issue, or this issue could be generalized to deal with custom protocols as well as mailto:.
Thinking about it, comparing the protocols / URI Scheme could be problematic in a few situations:
- There are protocols that should be handled internally, like
javascript:(inline JS in links), orabout:(?) - Wombat patching of links messes with the output of
anchor.protocoloranchor.getAtrribute('href'), reporting them as absolutehttps:even if a link is relative to a context likehttp://localhostorchrome-extension://. Even in Zimit2 (confirmed).
Second bullet-point above can be dealt with by using the getRealHref() function. But there are probably some other, unforeseen cases...
EDIT: Apart from about: and javascript, it would be necessary to consider how to handle /blob:|data:|file:/. While not meaningful as static links, they could be constructed dynamically, e.g. by a function that downloads data requested by a user.