Here is the thing about HTTP(s) remote imports in #javascript server-side runtimes
(this is in no way a thread against the current PR in @nodejs that actually (will) cover the content of this thread in an elegant way)
1/11
(this is in no way a thread against the current PR in @nodejs that actually (will) cover the content of this thread in an elegant way)
1/11
This upcoming statement will be bold:
Web browsers don't run JavaScript
... they run JavaScript given a certain level of constrains
2/11
Web browsers don't run JavaScript
... they run JavaScript given a certain level of constrains
2/11
Some of these constrains are actually defined by the end user: "you run JavaScript, but I don't grant you certain APIs" (namely, position, webcam, microphone, you name it)
3/11
3/11
Some of these constrains are actually defined through headers from the source of the current website.
And they are a huge part of the security model of the code execution. Examples: #HPKP, #CSP, #trustedTypes.
4/11
And they are a huge part of the security model of the code execution. Examples: #HPKP, #CSP, #trustedTypes.
4/11
One could answer "Yes but ES imports are static and are loaded from a local cache, not from the remote URL directly". That's correct...
enters `import(url)` -> this returns a promise containing a dynamically loaded module
5/11
enters `import(url)` -> this returns a promise containing a dynamically loaded module
5/11
(Let's cut a myth right now: don't rely on static analysis in JavaScript, this is an illusion - not the topic of this thread, but I see someone at the back of the room about to suggest solving the problem with this)
5.5/11
5.5/11
basically, you can't predict what strings will be used as arguments with `import()`. And if your runtime allows network access, well, some code could be vulnerable to #RemoteFileInclusion (yeah #PHP!).
6/11
6/11
In the #threatModel of JavaScript in the browser, this is not RFIs but #XSS. That's why the current security tooling of the browsers provide...XSS protections.
So what are the solutions?
7/11
So what are the solutions?
7/11
Solution 1: disabling `import()`
in this case, `import()` is pretty similar to `eval()` and there are ways to disable it (usually a flag)
8/11
in this case, `import()` is pretty similar to `eval()` and there are ways to disable it (usually a flag)
8/11
Solution 2: having a manifest allowing imports
yeah, I know, you all want to get rid of package.json, but, if you want shinny things, you will need some protection here.
9/11
yeah, I know, you all want to get rid of package.json, but, if you want shinny things, you will need some protection here.
9/11
Before conclusion, side note on HPKP:
I understand the main things people think of when downloading packages is #integrity. That's fair and a checksum do the job here.
However, #confidentiality must be covered too (probably a topic for another thread).
10/11
I understand the main things people think of when downloading packages is #integrity. That's fair and a checksum do the job here.
However, #confidentiality must be covered too (probably a topic for another thread).
10/11
conclusion: Web browsers have decades of security hardening to prevent #XSS.
In the scope of a server-side runtime, XSS through dynamic imports become #RemoteFileInclusion.
A JS-based server-side runtime MUST provide alternatives to browser XSS protections
11/11
In the scope of a server-side runtime, XSS through dynamic imports become #RemoteFileInclusion.
A JS-based server-side runtime MUST provide alternatives to browser XSS protections
11/11