Some test text!
Web / FAQ / Use a Content Security Policy
MDN says a Content Security Policy (CSP) is:
"an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks."
WebViewer requires certain CSP directives to be used. If you do not need to support embedded JavaScript then the current recommended policy is:
script-src 'self' 'wasm-unsafe-eval' blob:; font-src 'self' data: blob:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; connect-src https://www.pdftron.com/ https://pws-collect.pdftron.com/ https://proxy.pdftron.com/
If you use this policy and want to make sure the embedded JavaScript warnings/errors don't show up because of the CSP then you can disable embedded JavaScript in WebViewer .
If you need to enable to embedded JavaScript then you'll currently need to enable unsafe-inline
and unsafe-eval
for script-src
.
script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; font-src 'self' data:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; connect-src https://www.pdftron.com/ https://pws-collect.pdftron.com/ https://proxy.pdftron.com/
connect-src https://www.pdftron.com/
necessary?The https://www.pdftron.com/
domain hosts fonts that WebViewer will download when necessary for certain documents.
It is possible to self-serve these fonts on another domain by following the guide for self serving substitute fonts .
connect-src https://pws-collect.pdftron.com/
necessary?When WebViewer is provided a license key that transmits usage data back to Apryse, then this is needed to ensure that the API server hosted at https://pws-collect.pdftron.com/ can be reached.
If the license key used is not a usage-based license key, then adding this URL to the connect-src
directive is not necessary.
connect-src https://proxy.pdftron.com/
necessary?The proxy server is used in cases where WebViewer needs to contact a Certificate Revocation List (CRL) server or Online Certificate Status Protocol (OCSP) server for a subset of Digital Signature Verification calls.
This Proxy server can be substituted for any other Proxy server via the API Core.PDFNet.VerificationOptions.setRevocationProxyPrefix.
Otherwise, if your instance of WebViewer is not utilizing Digital Signature Verification , then this can be removed.
script-src 'wasm-unsafe-eval'
necessary?WebViewer leverages WebAssembly for several native modules, and therefore requires a CSP directive that allows WebAssembly to execute.
While the term "unsafe" is used, we are currently unaware of any security risks related to the wasm-unsafe-eval
directive, as it is distinct from the more dangerous unsafe-eval
directive. For avoidance of doubt, wasm-unsafe-eval
does not allow for the JavaScript eval
method to be invoked, whereas unsafe-eval
does allow for the eval
method to be invoked.
Furthermore, as of this writing, the official WebAssembly documentation recommends this directive when WebAssembly compilation and instantiation is required.
style-src 'unsafe-inline'
necessary?WebViewer requires the following Content Security Policy (CSP) setting for the style-src directive:
style-src 'self' 'unsafe-inline'
The unsafe-inline
source is required because the built and minified WebViewer code contains HTML elements that use the style attribute.
When the unsafe-inline
source is used strictly with the style-src
directive, only inline changes related to styling on a web page are possible.
Any risks beyond styling changes are mitigated by the self
source, meaning that any attempts to use style
attribute logic to make network requests outside of the source web page where WebViewer is hosted is not possible, given that the self
source will use the same CSP rule to prevent communication outside of the hosting domain.
script-src blob:
directive?There is a WebViewer constructor option disableObjectURLBlobs
that will remove the need for script-src blob:
, that can be called like so:
WebViewer({
// ...
disableObjectURLBlobs: true,
// ...
}, document.getElementById('viewer')).then(instance => {
// ...
});
For additional context, WebViewer by default loads various compressed JavaScript worker files that are compressed as the G-Zip (.gz
) or Brotli (.br
) compression types. In order for WebViewer to uncompress these file extensions, they need to be opened with the browser's URL.createObjectURL method, which returns a Blob
that is then loaded as a blob:
URL.
If the CSP directive script-src blob:
is not available, then this operation is not permitted.
Please note that the downside of this is that WebViewer then needs to load uncompressed versions of these worker files, which may have a minor impact on performance, depending on the client's network speed, though it is worth noting that the size difference between the compressed and uncompressed assets are not major.
script-src 'wasm-unsafe-eval'
directive?WebViewer can operate in a non-WebAssembly context with disableObjectURLBlobs
, like so:
WebViewer({
// ...
disableObjectURLBlobs: true,
backendType: WebViewer.BackendTypes.ASM,
// ...
}, document.getElementById('viewer')).then(instance => {
// ...
});
However, this does require uncompressing the non-WASM PDF & Office worker files manually, as Apryse does not ship the uncompressed versions of these files due to the file size of the uncompressed files.
WebViewer has a fullAPI
option as part of the constructor, which would look like this extending from the code example above:
WebViewer({
// ...
disableObjectURLBlobs: true,
backendType: WebViewer.BackendTypes.ASM,
fullAPI: true,
// ...
}, document.getElementById('viewer')).then(instance => {
// ...
});
If fullAPI: true
is being used, then the following commands should be run in lib/core/pdf/full
, otherwise if fullAPI
is not being used, perform the commands in lib/core/pdf/lean
.
# Copy and rename the new JavaScript worker file to end with .gz
cp PDFNetC.gz.js.mem PDFNetC.js.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d PDFNetC.js.gz
# Copy and rename the Binary worker file to end with .gz and move it up one level, as this is where PDFNetC.js expects to load the uncompressed binary mem worker
cp PDFNetC.gz.mem ../PDFNetC.js.mem.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d ../PDFNetC.js.mem.gz
For modern Office files (.docx
, .xlsx
and .pptx
), perform the following commands in lib/core/office
:
# Copy and rename the new JavaScript worker file to end with .gz
cp WebOfficeWorker.gz.js.mem WebOfficeWorker.js.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d WebOfficeWorker.js.gz
# Copy and rename the Binary worker file to end with .gz
cp WebOfficeWorker.gz.mem WebOfficeWorker.js.mem.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d WebOfficeWorker.js.mem.gz
Please note that the instructions for the PDF workers also need to be completed for the Office workers to operate correctly.
For legacy Office files (.doc
, .xls
and .ppt
), perform the following commands in lib/core/legacyOffice
:
# Copy and rename the new JavaScript worker file to end with .gz
cp WebB2XOfficeWorker.gz.js.mem WebB2XOfficeWorker.js.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d WebB2XOfficeWorker.js.gz
# Copy and rename the Binary worker file to end with .gz
cp WebB2XOfficeWorker.gz.mem WebB2XOfficeWorker.js.mem.gz
# Uncompress the newly copied G-Zip compressed file
gzip -d WebB2XOfficeWorker.js.mem.gz
Please note that the instructions for the PDF workers also need to be completed for the Office workers to operate correctly.
Trial setup questions? Ask experts on Discord
Need other help? Contact Support
Pricing or product questions? Contact Sales