Really enable Chromium to display PDFs in the viewer iframe

The previous "fix" (merged PR #924) was buggy. It not only didn't work
in Chromium v90, but in more recent versions too.

I verified that this fix works in Firefox (v111) and Chromium (v90):

- Attempts by the ZIM content to break out of the viewer iframe are
blocked.
- PDFs are displayed in the viewer.
This commit is contained in:
Veloman Yunkan 2023-04-10 16:34:28 +04:00
parent 453f02cc85
commit 9fd7f7da34
3 changed files with 31 additions and 7 deletions

View File

@ -1123,6 +1123,29 @@ ParameterizedMessage suggestSearchMsg(const std::string& searchURL, const std::s
});
}
///////////////////////////////////////////////////////////////////////////////
// The content security policy below is set on responses to the /content
// endpoint in order to prevent the ZIM content from interfering with the
// viewer (e.g. breaking out of the viewer iframe by performing top-level
// navigation).
const std::string CONTENT_CSP_HEADER =
"default-src 'self' "
"data: "
"blob: "
"about: "
"'unsafe-inline' "
"'unsafe-eval'; "
"sandbox allow-scripts "
"allow-same-origin "
"allow-modals "
"allow-popups "
"allow-forms "
"allow-downloads;";
// End of content security policy
///////////////////////////////////////////////////////////////////////////////
} // unnamed namespace
std::unique_ptr<Response>
@ -1184,6 +1207,13 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
auto response = ItemResponse::build(*this, request, entry.getItem());
response->set_etag_body(archiveUuid);
if ( !startsWith(entry.getItem().getMimetype(), "application/pdf") ) {
// NOTE: Content security policy is not applied to PDF content so that
// NOTE: it can be displayed in the viewer in Chromium-based browsers.
response->add_header("Content-Security-Policy", CONTENT_CSP_HEADER);
response->add_header("Referrer-Policy", "no-referrer");
}
if (m_verbose.load()) {
printf("Found %s\n", entry.getPath().c_str());
printf("mimeType: %s\n", entry.getItem(true).getMimetype().c_str());

View File

@ -412,12 +412,6 @@ ContentResponse::ContentResponse(const std::string& root, bool verbose, const st
m_mimeType(mimetype)
{
add_header(MHD_HTTP_HEADER_CONTENT_TYPE, m_mimeType);
if ( !startsWith(m_mimeType, "application/pdf") ) {
add_header("Content-Security-Policy",
"default-src 'self' data: blob: about: chrome-extension: 'unsafe-inline' 'unsafe-eval'; "
"sandbox allow-scripts allow-same-origin allow-modals allow-popups allow-forms allow-downloads;");
add_header("Referrer-Policy", "no-referrer");
}
}
std::unique_ptr<ContentResponse> ContentResponse::build(

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' data: 'unsafe-inline' 'unsafe-eval';
frame-src 'self' moz-extension: chrome-extension:;
frame-src 'self';
object-src 'none';">
<title>ZIM Viewer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">