Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Recommendations for CSP and Avoiding 'unsafe-eval' #156

Open
rujep opened this issue Jan 21, 2025 · 13 comments
Open

Updated Recommendations for CSP and Avoiding 'unsafe-eval' #156

rujep opened this issue Jan 21, 2025 · 13 comments

Comments

@rujep
Copy link

rujep commented Jan 21, 2025

Hello Dynamsoft Team,

We are a team developing an Angular web app with PWA capabilities and are integrating the dynamsoft-barcode-reader-bundle (version 10.4.3100). Our application hosts the required Dynamsoft resources locally to ensure quick and seamless caching via our service worker. These resources include the following:

/assets/dynamsoft-capture-vision-std/std.js
/assets/dynamsoft-capture-vision-std/std.wasm
/assets/dynamsoft-image-processing/dip.wasm
/assets/dynamsoft-core/core.js
/assets/dynamsoft-core/core.worker.js
/assets/dynamsoft-core/core.wasm
/assets/dynamsoft-license/license.js
/assets/dynamsoft-license/dls.license.dialog.html
/assets/dynamsoft-license/license.wasm
/assets/dynamsoft-utility/utility.js
/assets/dynamsoft-barcode-reader/dbr.js
/assets/dynamsoft-barcode-reader/dbr.wasm
/assets/dynamsoft-barcode-reader/DBR-PresetTemplates.json
/assets/dynamsoft-capture-vision-router/cvr.js
/assets/dynamsoft-capture-vision-router/cvr.wasm
/assets/dynamsoft-capture-vision-router/cvr.worker.js
/assets/dynamsoft-camera-enhancer/dce.js
/assets/dynamsoft-camera-enhancer/dce.ui.html

Currently, we are concerned about having to use 'unsafe-eval' in our Content Security Policy (CSP). Our CSP configuration is defined in a web.config file and looks like this:

<add name="Content-Security-Policy"
     value="default-src 'self' login.microsoftonline.com; 
            script-src 'self' 'unsafe-eval'; 
            style-src 'self' 'unsafe-inline'; 
            img-src http: https: data:; 
            connect-src 'self' login.microsoftonline.com mdls.dynamsoftonline.com sdls.dynamsoftonline.com data:; 
            frame-ancestors 'none'; 
            font-src 'self' data:" />

This setup works but requires 'unsafe-eval' for the library to function, which we would like to avoid for security reasons. Ideally, we aim to:

  • Use 'wasm-unsafe-eval' instead of 'unsafe-eval' (or a similarly scoped policy).
  • Specify more restrictive CSP rules (e.g., per-directory or per-file rules) for Dynamsoft resources to minimize the risk.

We came across Issue #102 from October 2021, which provides minimum CSP requirements. However, that post is over three years old, and we were wondering if there have been any updates since then.

Additionally, we attempted to set CSP-specific rules for Dynamsoft files by using <location> nodes in web.config:

<location path="<path-to-dynamsoft-files>">
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Content-Security-Policy" 
             value="...specific CSP rules here..." />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</location>

Unfortunately, this approach resulted in an error when trying to load core.worker.js.

Questions:

  1. Are there updated recommendations for configuring CSP to avoid 'unsafe-eval' with Dynamsoft libraries?
  2. Is there a roadmap or consideration for removing the reliance on 'unsafe-eval' in the library?
  3. Are there best practices for hosting Dynamsoft resources locally while maintaining a secure CSP?

Thank you for your guidance and support!

Best regards,
Rune

@Keillion
Copy link
Collaborator

wasm-unsafe-eval

I'll do a quick test.

@Keillion
Copy link
Collaborator

For resources self deployment:

The resources are located at the path node_modules/<pkg>, without @<version>. You must copy “dynamsoft-xxx” packages elsewhere and add @<version>. The <version> can be obtained from package.json of each package. Another thing to do is to specify the engineResourcePaths so that the SDK can correctly locate the resources.

I guess this is why you failed to load core.worker.js.

===

As for CSP, I failed to remove 'unsafe-eval' in my test.
Webassembly needs to call js. It uses eval in std.js. I tried strict-dynamic but it does not work for webworker.

===

Your approach should be the most reasonable one, exposing only the scan barcode page to a looser CSP and ensuring strict security for other pages.

Also refer: https://stackoverflow.com/questions/9522348/add-custom-header-based-on-file-type

@rujep
Copy link
Author

rujep commented Jan 23, 2025

Thank you for taking a look at this.

We do set the engineResourcePaths

CoreModule.engineResourcePaths = {
  std: 'assets/dynamsoft-capture-vision-std/',
  dip: 'assets/dynamsoft-image-processing/',
  core: 'assets/dynamsoft-core/',
  license: 'assets/dynamsoft-license/',
  cvr: 'assets/dynamsoft-capture-vision-router/',
  dbr: 'assets/dynamsoft-barcode-reader/',
  dce: 'assets/dynamsoft-camera-enhancer/',
  utility: 'assets/dynamsoft-utility/',
}

I will try with looking more into custom headers.

@Keillion
Copy link
Collaborator

CoreModule.engineResourcePaths = {std: dip: core: xxxxxx}

As it is overly complex, Some months ago, I suggested to remove this from the guide and only keep the usage of rootDirectory. 😂 Well, anyway, it also works.

==

If you still have problem loading core.worker.js. Maybe you miss blob: in worker-src.

You can check CSP in https://github.com/dynamsoft-rd-0/dbrjs-mass-samples/blob/master/CSP-for-dbrjs10.4.3100.html.

You can remove all https://cdn.jsdelivr.net/xxxx sha384- nonce-, in angular + self deployment.

@Keillion
Copy link
Collaborator

Good news, @rujep
our colleagues have made a new discovery: if you deploy resources in the same domain of page, you don't need unsafe-eval.
🎉🎉🎉

e.g.
page: https://a.b.c/somewhere/index.html
resource: https://a.b.c/assets/

@michael-yx-wu
Copy link

michael-yx-wu commented Jan 27, 2025

The dynamsoft demos online are not self-hosted, but that shouldn't really matter when it comes to whether unsafe-eval is required in the CSP, unless self-hosting changes the code that is actually being run. I can't imagine that being the case, but let me know if that's an invalid assumption.

Based on my testing, it seems unsafe-eval is still required whenever the page has a CSP (which I imagine is most production applications). Details below.

I applied the following CSP without unsafe-eval to the Common 1D + 2D demo on the dynamsoft website and the demo failed to render the camera view. I did this by overriding the response header of the HTML document response in Chrome dev tools.

default-src 'self' ;
script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' https://* ;
connect-src 'self' https://* ;
worker-src 'self' blob: ; style-src 'self' 'unsafe-inline' ;
img-src 'self' data: https://*;
frame-src 'self' https://*

Image

(Note the https://* are for the various CDN domains that are hosting the frontend assets and wouldn't be necessary in production.)

When I added unsafe-eval to script-src, the camera view renders as expected.

default-src 'self' ;
script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' https://* ;
connect-src 'self' https://* ;
worker-src 'self' blob: ; style-src 'self' 'unsafe-inline' ;
img-src 'self' data: https://*;
frame-src 'self' https://*

Image

@rujep
Copy link
Author

rujep commented Jan 28, 2025

Sorry for the lack of feedback the last few days.
I have tried different approaches as well, and always come to the same conclusion, that for now 'unsafe-eval' is required.

I created this issue because it wasn't easy to find anything on it in existing documentation and wanted to know if I was missing something obvious, as well as hopefully have the team looking into the possibility of only requiring 'wasm-unsafe-eval' or none of the above in the future.

@Keillion
Copy link
Collaborator

@michael-yx-wu

I had the same idea as you at first. But I verified my colleague's discovery, and indeed, unsafe-eval is not needed when the resource and page are in the same domain. When they are in different domains, we fetch URL first, then load blob as worker (to solve the cross-domain problem). When they are in the same domain, the worker loads directly through the URL.

I guess wasm-unsafe-eval needs to be passed through the worker, which only works when the resources are in the same domain.

@rujep I'll try to give you a sample, with all resources self-host and nodejs server (any server is OK. file:// can't work)

Sorry for rely late because of my vacation.

@Keillion
Copy link
Collaborator

The code generated by the wasm compiler (emsdk) naturally has eval. Although according to some issues, we can remove some of them. But some of these functions have no alternatives. I have a idea but I am not sure if they will work. It is very likely that these changes will bring huge performance and size sacrifices.
I guess this might be why wasm-unsafe-eval came into being.

@Keillion
Copy link
Collaborator

Keillion commented Jan 29, 2025

https://drive.google.com/file/d/1LHM75cUZSoKH2I8d79dK4Wr0DHVynF6T/view?usp=sharing (share removed)

Please try this zip. Node.js as server.

@Keillion
Copy link
Collaborator

Keillion commented Jan 29, 2025

I will continue to try to solve it perfectly after vacation (one week left).

It is expected to be time-consuming and require research compilation and detailed usage for emsdk.

I can't predict the time, please don't wait for me. ❤

@rujep
Copy link
Author

rujep commented Jan 29, 2025

@Keillion Thank you for your efforts. I will try the zip later today.
And I (almost 😄) don't care about the time frame. I am just happy that you are looking into it.

@Keillion
Copy link
Collaborator

Keillion commented Feb 17, 2025

I believe you have received a response from our technical support. For the completeness of this issue, I still put the zip package that solves the problem here.

Here I use nodejs as server. You can find CSP rules in app.js.

The relevant solution is expected to be included in the next major version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants