Hardening Drupal with WebAssembly
wasmlabs.dev
wasmlabs.dev
No explanation for what vulnerabilities standard Drupal is actually being hardened against.
But... Are you not afraid of these unknown, not-yet-public vulnerabilities that this solution clearly protects us against?!
Having said that, searching Druapl on the CISA know exploited list shows a number of remote code execution vulnerabilities that this would help mitigate: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No, not really. First of all, a heavy disclaimer: I am speaking as a rather cynical, old, downright ancient PHP developer and not in any other capability. Not as a former Drupal security team lead, not as a developer for whatever clients I have, just plain old me.
The biggest threat in my opinion on a properly hosted Drupal is information disclosure and privilege escalation within that Drupal instance. Arbitrary code execution is utterly pointless because the user that runs Drupal will have no privileges and there'll be nothing installed on the host, nothing to run anyways. And guess what, none of that benefits from this WASM sorcery. SQL injection and XSS -- and potentially allowing private files to be downloaded -- is the real problem while this protects from arbitrary code execution.
Just stuffing something in a sandbox is easy. Set up a VM and don't add a network card and you've got a near perfect sandbox without any performance overhead. Maybe even do so for each request through Firecracker if you fear memory persistence. What matters is all the added complexity and the downsides of each solution.
Without any comparison, this attempted sales pitch for WASM is little more than a showcase, like when someone runs WINE in the browser.
Once all that is in place, you can move into the "make it fast" part, but for many scenarios where security is an issue (high profile websites) even a significant performance penalty (that can be offset with beefier hardware or caching) may be desirable.
I applaud this development but at the same time any kind of run-time code translation imposes performance penalties. WASM is not exception. It would be enlightening to hear the authors' stance on this topic. CPU utilization factor is a big thing for hosting companies, so they will be hesitant to use something like this in production.
I do want to see the WASM ecosystem grow and thrive, but it will take some time, although what I have seen so far is amazing. I am most excited for WASI. Havent checked up on it in a moment but its basically the WebAssembly version of nodejs but as a spec anyone implementing a WASM runtime can support, so there will be various options to run your code ultimately.
While the lag is small, it is unpleasant enough to make my work less comfortable when compared to the native ARM64 images.
The story repeats itself with Windows 11 ARM64 - it can run x86 and x64 images but there is a price to pay - they are not as snappy as native ARM64 images due to the dynamic translation costs.
Having a WASM on board poses the same kind of dilemma which directly impacts hosting bills.
Translating x86_64 code to arm64 requires more CPU cycles than JITting Wasm into arm64 or x86_64.
Buy even more: in the use case covered in this article, the PHP interpreter won't change so it can be AoT compiled upon deployment to the target architecture. No JIT compilation needed :-)
I wonder if that's changed over time, for instance I could see GPT3.5 doing a good job of summarily inspecting modules systematically.
1. https://www.drupal.org/drupal-security-team/security-advisor...
I kind of like it because CGI is architecturally elegant, but what about performance implications? By default, the CGI is not the fastest thing on Earth. Every time a HTTP request arrives, a CGI process should be initialized over and over again wasting CPU time on BSS section / runtime library initialization. Does it work any differently when it comes to WASM?
In mod_wasm, there are some differences with a pure CGI implementation. When Apache boots, it loads the configuration and initializes the WasmVM. When a new HTTP request arrives, the VM is ready so you don't need to initialize a different process to manage it.
You still need to process the request and pass the data to the Wasm module. This step is done via STDIN through the WebAssembly System Interface (WASI) implementation [0]. The same happens in the opposite direction, as the module returns the data via STDOUT.
So, the CGI pattern is still there, but it doesn't require new processes and all the code runs in a sandbox.
However this is not the only way you can run a Wasm module. In this specific case, we use CGI via WASI. In other cases, you may compile a module to fulfill a specific API, like ProxyWasm [1] to create HTTP filters for proxies like Envoy.
- [0] https://wasi.dev/
I suspected that, pretty smart. I presume that a WASM module state can be cached in a similar way, essentially imitating a "fork" syscall semantics while keeping the pool of request handlers in a always-ready hot state.
(Wasm Labs dev here) We haven't yet measured performance in a meaningful way that we can use to compare, mainly because our PHP builds also have certain limitations mentioned in the article, such as not having OPcache available at PHP. It is however an iterative process, and we are interested in this, as well as we understand that it's interesting for the community.
> Every time a HTTP request arrives, a CGI process should be initialized over and over again wasting CPU time on BSS section / runtime library initialization. Does it work any differently when it comes to WASM?
It's a little different in Wasm, in the sense that there is no need to fork/exec (if talking about bare CGI). The PHP executable gets loaded into the runtime once (what will compile it from Wasm -> native ISA), and then for every request we create a Wasm execution context, and run the PHP Wasm module that interprets the PHP script.
Creating a Wasm execution context is certainly much lighter than a fully fledged fork/exec.
So no WASM inside Drupal, but Drupal run as, and in WASM.
- [0] https://github.com/vmware-labs/webassembly-language-runtimes
The Apache HTTP server and the Drupal packages remain unchanged. However, instead of loading the libphp.so extension module, it incorporates mod_wasm.so. In addition, instead of relying on the traditional PHP interpreter, it utilizes a PHP build in the WebAssembly binary format.
- No errors (even fatal) from the Wasm module will bring down Apache HTTPD. - mod_wasm's code base is small enough to inspect thoroughly and test thoroughly to ensure it is secure - Indeed you will now have to trust the embedded Wasm runtime (wasmtime as of today). As a naïve analogy, this is the equivalent of trusting a virtual CPU(Wasm)+OS(WASI), which gets tested in thousands of other scenarios than the ones used in mod_wasm and issues get fixed and corrected asap.
Why on earth are they using both?
> Why on earth are they using both?
You lost the chance for a great pun here.What? Since when does WebAssembly natively ship with a "capabilities-based security model"?
> protecting against a wide range of vulnerabilities, including those that may not be public yet but can be preemptively mitigated through these mechanisms
Not yet public vulnerabilities?
Who was this article/summary written by? Reeks of GPT or at least someone who doesn't actually know the subject very well.
Not yet public means exactly that. You may have a buffer overflow issue in your code that you are unaware of. There are technologies that help mitigate those when/if discovered. Wasm is one of them but not the only one (ie most modern compilers have specific settings to harden the binaries against some issues)