Hacker News new | past | comments | ask | show | jobs | submit login
How Shopify Uses WebAssembly Outside of the Browser (shopify.engineering)
243 points by oedmarap on Dec 19, 2020 | hide | past | favorite | 130 comments



The underlying platform is ahead-of-time compiled WebAssembly but AssemblyScript, a variant of TypeScript, will be the only supported language:

> Theoretically any language with a Wasm target can be supported, but the effort developers spend to conform to our API is better focused on solving problems for merchants. That’s why we’ve chosen to provide first class support to a single language that includes tools that get developers up and running quickly.


I think that misses part of the point.

WASM meets their feature needs. WASM is at the core of it.

But, they needed a widely accessible language to tell people to use. This helps with examples and guidance. They chose AssemblyScript due to their customers being familiar with JS.

It looks like I could write what I need in Go or Rust, for example, and build for WASM. They’re just not putting that up front. This is about making an easy path for most people.

The way it’s put together is about n making their customers successful rather than building all that’s possible


In my experience GO is not a good language for WASM. The simplest wasm binary you will create, will be at least ~3mb in size, even if it only prints "hello world", because GO will need to embed its internals and the garbage collector in the wasm bundle. In a browser scenario this is not particularly attractive...

It's really a pity especially since Go is marketed as "a better C". So far C/C++ has been the best optimal target for wasm. Rust on the other hand is extremely promising but I don't have enough experience with it or data to make a case for or against :)

AssemblyScript looks amazing though. One thing to consider is that many times you do not need to make your whole project in wasm. Instead you should find crucial bottlenecks (eg matrix math for light calculations, or some blur operation, or some physics calculation or whatever) and take that part out and put it in wasm. That part may already be written in JS and might be very difficult to rewrite in C (time consuming, web dev team might have weak C skills, tougher to debug). For such a scenario AssemblyScript looks fantastic, and this is actually the most common scenario I 've personally encountered (and sometimes I 'd end up writing asm.js by hand or go and recreate my logic in C...). So yeah, I have not used AssemblyScript yet but there are many pain points that a good implementation could blow away.

edit: what I describe above is for browser scenarios. I have not used wasm outside of the browser (didn't find a reason to, since I can run native binaries compiled specifically for the target OS - why add one more layer of complexity through wasm?). So, outside of the browser, your experiences might be different.


TinyGo builds WASM fine from my experience. There are a few minor gotchas (especially running in the browser with callbacks, but that can affect a number of languages compiled to WASM) but it does work.


It's not missing the point if TS is a bad fit for WASM, which it kind of is.

Frankly, it's not really TS, it's an odd, unofficial subset of it - kind of like hacking some nice things about TS to 'make it work'.

Not only is there the fact that it's OO, it needs a VM, it doesn't even support Strings ... so many questions marks.

V8 as it turns out is a pretty good black box. Every one of us runs completely untrusted code on our machines ever day.

Pretty most (all?) Shopify staffers and devs are, every day, running untrusted JS code on V8.

So it's nice to see progress, and I can't wait to see more details, but it looks tricky from the start ... and TS was never going to be the obvious starting point for WASM.


Like always, browsers are a funny ecosystem and very unpredictable. In all this time I thought that I could see a rise in the adoption of C and Rust libs by the community through WASM but now instead we are building around AssemblyScript. Touche.


I've spent a good amount of time this last year playing around with WASM options in anticipation of it being a major runtime environment for cloud computing.

Rust has the most developed ecosystem but the best experience I've had otherwise was with Zig. It's reasonably easy to write and can produce excellent final wasm size. The only problem is that the compiler is currently exporting every public symbol in the standard library but when I hacked up the compiler to only export a hard coded list of symbols I got ~150 bytes for add (the WASM hello world) and easily sub 1k for the type of modules the post is discussing.


Do you have a fork of the compiler online?


No and it's not useful. It's literally just editing `src/link/Wasm.zig` and changing the `--export-all` line to `--export=addInc` (to use the zig wasm example's naming) and copy/pasting the line if I wanted to export more stuff. The compile invocation is:

    zig build-lib add.zig -O ReleaseSmall -target wasm32-freestanding -static
You can debug the linker invocation with `--verbose-link` on the end of that.

The issue tracking the problem is: https://github.com/ziglang/zig/issues/7133


We just have to compile Rust and C to AssemblyScript, à la asm.js, and come full circle (again).


It's interesting that this seems on one hand "unpredictable" while also being logical. If a company has employees familiar with TypeScript (or even JS) and they have to make a choice between yet another flavor of that or a new language like C/Rust... well the choice is understandable. Once again the path of least resistance to a new web technology ended up being JavaScript - it just wasn't immediately obvious when WASM first emerged.


A JavaScript SuperSet becoming the de facto standard of writing for WASM - I think one can file this under „worse is better“.


JavaScript SubSuperSet


I know I'm deliberately misinterpreting you, but

> a new language like C

is a funny thought ^_^


Yes, funny ecosystem and unpredictable because smart people contribute innovative and interesting things. This is the best feature of an open, truly shared ecosystem. Everyone owns it and feel safe contributing to it. The web rules!


I wish I could share your enthusiasm. Good on you. To me the web of today is an ever-expanding ball of shit being rolled in different directions by giant corporations. I agree it's fun to work with, but it isn't healthy.


I agree with your take on the web today. I am trying to do my part to promote the things outside that bubble. I thought this was a good place to do that :)


I'm keen on Kotlin Multiplatform. Seems like a pipe dream that might have legs.


This is PR about Shopify’s use/promise of WebAssembly—cool. I get WebAssembly tech is cool.

I’m interested why Shopify is practically the only sales platform that gets ‘airtime’ at HN.

Is this because partner apps are using Ruby? Does it have something to do with the governance of Shopify? Community of Canadians on HN?

I have some experience with Square, and a few others.

I’m an interested party.


Amazon gets lots of airtime and is a Shopify competitor. Stripe gets lots of airtime and is a Shopify competitor.

Anyway, Shopify’s engineering blogs can be worthwhile, so they make it to the front page. They do interesting work at pretty big scale, provide in depth writeups from time to time, and folks like me enjoy reading them. I see nothing suspicious about it.


> "I see nothing suspicious about it."

I didn't intend to imply anything of the sort. I gather from your response including Amazon you might have a different perspective.

I'm interested in sales platforms for small business retail. Platforms which let business owners put a store on the web and maintain their own website design. Shopify's turn-key solution lets you have a stores without all of the Platform cruff. You can seel goods on Amazon, but you're just a another 'seller' under the branding of Amazon.com (unless there is another competing service I'm unaware of).

Personally, I get to see a lot of small businesses from the Admin side. And Shopify's partner platform is one of the most robust. Pricing is competitive (for the businesss) and they're very developer friendly.

No. I really like Shopify, and I was curious why others _like_ it so much.

haha. I understand where you might default to thinking I'm suspicious. We're all suspicious. And I see a lot of businesses who go full-in on a platform (POS, online retail) and when it comes to getting financial reports or API access you might want, they are unhelpful and very costly. (Don't get me started on Third-Party Online Ordering Services like DoorDash or Ubereats).


> Stripe gets lots of airtime and is a Shopify competitor.

Barely. AFAIK Shopify Payments is built on top of Stripe. They only compete on their Capital products, though given that most of Shopify's financial products seem to be built on Stripe, I'm not even sure if that's true.


Do Shopify's competitors produce similarly high-quality engineering content? (if you know some, please link!)


Bigcommerce does have a developer blog, but it seems a bit more limited in scope:

https://medium.com/bigcommerce-developer-blog


Maybe because it is the largest platform alternative to Amazon [1]:

> The company reported that it had more than 1,000,000 businesses in approximately 175 countries using its platform as of June 2019. The total gross merchandise volume exceeded US$61 billion for calendar 2019.

[1] https://en.wikipedia.org/wiki/Shopify


An interested party in Ecom or ..?


Not sure why you're downvoted. I'm in retail small business. Easy to get started on a turn-key platform, but due to different governance strategies they are more or less cooperative about their deficiencies.


Could someone eligthen me. Why not just use JavaScript? It is being used by Cloudflare on the edge, and AWS lambda. Why need to go to WASM?


We are talking about two alternative architectures, Cloudflare Workers and Fastly Compute@Edge, solving the same problem: how to run server-side untrusted code. Cloudflare runs a sandboxed V8 runtime in-process with its Nginx servers while Fastly chose a Function-as-Service platform using Lucet compiled WebAssembly modules with minimal runtime and fast startup. Fastly’s Varnish servers invoke FaaS modules and it sounds like Shopify's Ruby centric platform is better suited to this architecture.


> Cloudflare runs a sandboxed V8 runtime in-process with its Nginx servers

Maybe nitpicking, but that's not quite right. The Workers Runtime is a separate process from nginx and is inside a heavy second-layer sandbox separating it from the rest of the system. Multiple Workers Runtime instances exist on each machine to serve different tiers of customers, and each instance may additionally create further subprocesses to provide extra sandboxing adaptively.

Here's a diagram: https://blog.cloudflare.com/mitigating-spectre-and-other-sec...

(In that diagram, the "Inbound/Outbound HTTP Proxy" boxes are, at least at present, nginx, but the big middle box is a new server architecture written from scratch.)


That is not nitpicking at all. Definitely not in-process. Thanks for pointing that out.


Aah, that's why Fastly's involved. Thanks!


The issue is quite symmetrical, isn't it? Somebody could ask: why not use just WASM? Why need to go to JavaScript?

This is a better question, actually, if you already have a codebase in another language that can you can easily compile to wasm, but not to javascript.


Because as the article states, JavaScript is widely used by their plugin developers, while AssemblyScript is still nascent (little-used, missing features, has bugs).


Like what? This is like me saying I have a mostly html/css/js website, and I just need it converted to a native Android app.

Well no right? I have website. I don’t have mobile app that just needs to switch platforms.

Do you have a website built in another language already? Then sure, all you need to do compile it via WASM. What I bet most of you have is a program for a totally different platform. In that case, you have to redo it, so why not just do it right.


* Predictable performance.

* A wide ecosystem of mature language toolchains.

* Simplicity: JS implementation contain sophisticated JITs, which are harder to prove correct compared to a simple ASM translator.

* Portability: not tied to a specific HW architecture.


? Those are reasons to use JS not WASM.

"A wide ecosystem of mature language toolchains." - yes, for Javascript, not for WASM, which isn't deployed really anywhere in production and there aren't even best practices for it.

What language are devs going to even write these scripts in? That's not clear.

"Simplicity" - nothing is more 'simple' than JS, which is why it's used the world over.

"Portability" - again, nothing more portable than JS.

The reasons to use WASM are 'performance' along with 'black box' - but in most cases performance is not necessary and the black box for all intents and purposes exists with v8.


I am not following WASM closely, but it appears to be deployed in all modern browsers: Chrome, Firefox, Safari, Edge. That counts as 'large scale production deployment', even if there aren't that many websites that take advantage of this capability (yet?). https://caniuse.com/wasm


> "Simplicity" - nothing is more 'simple' than JS, which is why it's used the world over.

Not in terms of implementing the language.


Not in terms of using the language either. And the reason it is used the world over is because it was dictated to developers by browser makers. That's the single and only reason.


I agree, but I'd still rank JavaScript as one of the more approachable major languages.


How often does portability ever appear as a tie-breaker between to different languages?


Rarely. Over a long enough time period though, the probability of a portability event nears 1, and the cost of such event is enormous. Right now there is a credible challenge for the x86 domination in the server, laptop and desktop markets raised by ARM, via AWS A1, Apple M1 and many others. Would be foolish to bootstrap an ecosystem locked-in to the loser, and we don't know the winner / loser over a 5-10 year timeframe.


For clarity, do you work at Shopify? These all sound like valid reasons, I'm just curious if they're the ones that motivated the Scripts team at Shopify.


> you cannot express anything malicious in Wasm

This feels like a comment that will as age as badly as “you can’t get a virus just from looking at an email”


You can’t express anything malicious in JavaScript either, yet vulnerabilities are constantly found in web browsers, including WebAssembly JITs.

You can express malicious things in Go, yet the number of RCEs in Go apps is pretty much zero.


That's a bit of apples and oranges. JS/WASM are runtimes executing hostile code, whereas Go apps are trusted code.


> You can’t express anything malicious in JavaScript either

You have to be more specific because lots of fraud is possible by misleading the user through JavaScript tricks.



What about something like https://github.com/IAIK/rowhammerjs ?


Sounds like the promises made about the jvm.


can u elaborate on these jvm promises?


The "sandbox" promise was/is still offered as the primary line of defense for Java.

"The first version of Java was released by Sun Microsystems in 1995 [2]. One year later, researchers at Princeton University identified multiple flaws enabling an analyst to bypass the sandbox [3]. The authors identified weaknesses in the language, bytecode and object initialization, to name a few, some of them still present in Java at the time of writing."[0]

[0] https://www.exploit-db.com/papers/45517

[2] http://www.oracle.com/technetwork/java/javase/overview

[3] Drew Dean, Edward W. Felten, Dan S. Wallach. "Java security: From HotJava to Netscape and beyond." In Security & Privacy, IEEE, 1996


The Java sandbox trusted any code signed with a SSL certificate by design, what didn't stop Sun from announcing it was secure and everything.


Depends - eBPF is statically verified pretty well, but spectre (and all its brothers) is a cruel mistress


The article starts with "what is webassembly", but doesn't breathe the keyword WASI [0], although they are using a service that's implementing it?

[0] https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webas...


The linked page on Lucet does call out WASI if that make it any better.


What does this mean for Shopify merchants? Is it all just faster apps?

I'm still at a loss that Shopify still does not have a subscriptions product. :/


Pro: You don't need server infrastructure to customise a Shopify flow.

Con: You need coders knowledgeable in WASM.

However, I could imagine that an ecosystem of "plugins" could emerge, i.e. ready-made WASM apps that merchants could plug into their stores.

There might be more security issues though, if the developer of the WASM and the merchant using it aren't the same party. I think it will be interesting to see how this will play out.

Then again, it might be sufficient to to code something in an LLVM-supported language of choice, then compile it to WASM and just hook it into Shopify, without needing to understand the WASM code that was generated. Good luck troubleshooting or debugging this though...


Why do you need coders knowledgeable in WASM? The majority of coders will use something else (C, C++, Rust, C#, etc.) The majority of them don't need to know the details of the processor their compiler is targeting.


You're right, but I think nonexistent monitoring/debug capabilities are still a problem. For JS, if something goes wrong, you have a vast array of tools available to troubleshoot the problem. The amount of tools for WASM in the browser are smaller, but at least the code runs in an environment you know and can control. With the WASM plugin approach presented here, you're dependant on the tools the host service (in this case Shopify) provides. There is probably not much hope that they will offer step-through debugging or stack traces in the language the code was originally written, so being able to understand the actual WASM might become more important.

There might also be the point of APIs. I'm no expert, but I imagine in-browser WASM must have access to some set of browser-specific APIs to communicate with JS and the DOM. Shopify won't have those APIs available in its runtime environment, but will probably offer different APIs to communicate with the purchase flow etc. I don't know how the WASM tooling landscape looks, but if most tools assume the browser APIs to be available, this could make it harder to develop WASM for other contexts. E.g., you can compile Unity games to WASM, but that WASM will assume that it runs in a browser. You probably couldn't use Unity to write a Shopify plugin.


At the moment, knowing how to compile X to WASM and have it run is a kind of expertise.

I hope that changes, the sooner the better, but right now it's not trivial.


The Blazor tutorials just run (C#). It is trivial

Same with Unity. Click build. Trivial

I suspect others are similarly trivial


I think it is why they have gone with AssemblyScript as the main supported language. Since it is similar to Typescript, Web developers will likely have a easier time learning it.


It’s mainly about the runtime (lack of it) that language brings, ie. garbage collected language brings garbage collector runtime with it that has to be included with every binary. Even rust and c have (relatively thin) runtimes. AssemblyScript has optional/controllable very thin runtime.

What their decision means in practice is that you can execute any language if you want but they won’t expose any specific runtimes to thin your binary. They will also actively support workflows based on AssemblyScript.


The article ends with:

> As we tear down the boundaries between Partners and Merchants, we connect merchants with the entrepreneurs ready to solve their problems.

"Partners" are a key part here, I think. Merchants can run their own code or possibly install 3rd party partner plugins. This is similar to the way 3rd party Wordpress Plugins work except, unlike PHP, they are small, fast, and safe. They can also run in a multi-tenant Shopify environment that scales safely.

As far as I can tell, the use case is similar to database triggers or custom web request filters: enhance the standard request flow with custom actions.


They do allow merchants to sell subscriptions - https://help.shopify.com/en/manual/products/subscriptions


I think this is super new - there are only two apps that offer subscriptions that integrate with Shopify Checkout, and one of them launched in November it seems and is still in beta:

https://apps.shopify.com/collections/checkout-subscription


Yes, I work at Shopify and our first party subscription support just recently launched a few months ago.


Awesome! Very exciting. I recently launched a small business which has a natural subscriptions element (https://narwallmask.com - a mask with replacement filters, which you may want regularly) but without subs integrated into shopify checkout, I decided simply not to offer it. Maybe now I can!

Can you say whether wasm helped make this happen? Seems quite plausible to me...


Perhaps in the future (on the team that added subscriptions at Shopify)


So how about garbage collection?

WASM doesn't have GC in the machine model, right? So either customers have to use a language with manual memory management, which is hard work, or use one with GC and then compile the collector into their binaries, which means bloat, and possibly a sub-par GC.

I guess what I'm saying is that it seems like it would have been better to have used a JVM.


How would that work? Secure multi tenancy is a difficult problem in its own right. You would now have to build a security layer outside the JVM because the JVM is exposing too many interfaces. You can use containers but the amount of interfaces a container exposes is still high enough that a container escape is possible. Then you need a security layer on top of containers based on VMs. At this point rolling your own security solution is either going to be highly inefficient because you are allocating too many resources to individual customers or expensive because developing infrastructure management to stay secure doesn't make your company more profitable. Your last hope would be to use an off the shelf solution like firecracker to run each JVM in a VM.

Alternatively you can just use a runtime that is sandboxed by default and avoid the cat and mouse game.



Something like this seems really important to (some branches of) the future of WASM, but this is still just a proposal, right?


It is still a proposal, but it's one of the proposals most worked on atm, there's a lot of activity.


It looks like AssmeblyScript has GC already https://www.assemblyscript.org/runtime.html


Shopify is a waste of money. Use SendOwl with your own stack instead.


Since we're here talking about Shopify - nearly every small shop (1-10 person makers) I buy from who uses the platform could not (in the past 30 days):

(a) change the email address associated with an existing account with history, and

(b) could not delete or change or transfer the orders from the old account to the new

I'm working through an email change and have discovered the above via hundreds of my logins - Shopify by far is the largest defunct platform which locks your account in using an email address, neither the user nor admins can "fix" it. All shop owners indicate to me they've emailed Support and gotten no help, every solution has been "just make a new account".


What's the problem with making a new account? Should take a few minutes at most?


Losing years worth of order history with that vendor? Having ghost accounts in a vendor database you can't delete, which has your previous order's PII (home address, etc.) tied to? The problem is not making a new account, it's appropriately dealing with the one containing personal information you're leaving behind.


You can’t change the email on existing accounts however you can definitely delete it.

See the docs https://help.shopify.com/en/manual/your-account/privacy/GDPR...

Their account management is definitely poor. But you seem to make it a bigger deal than it is. You don’t have to lose the order history, even if you don’t have access to the email anymore nothing would prevent you from logging again with the user/pass. And the order history is really the only valuable info... you can also save the email with your receipt. It’s not ideal but again, how much it actually impacts your life is about close to nothing. Request the account to be deleted under GDPR and then save the emails with your order history.


> You can’t change the email on existing accounts however you can definitely delete it.

I am an end user and cannot do anything other than email the shop support and hope. I am not a resident of EU or California, you might be surprised at the vast number of websites which tell you to go pound sand if you try and delete your account. As a user, you can do nothing but hope someone deletes something for you if they feel like it; not all shop owners bother to respond as well, adding another layer of consternation.

> But you seem to make it a bigger deal than it is.

You seem to lack empathy for how other people are sensitive to their PII (which in this case may and does include credit card purchase information, shipping addresses and other "I really don't want this floating around more than I need it to be" information about my life) being retained by Shopify based stores.

The GDPR you keep leaning on to support your reply means nothing to a vast majority of the world and many sites happily only perform the minimum required actions required by law for those to whom it does apply.


Technically you can accomplish the same thing using seccomp, I.e. the way most services run third party native code to process untrusted data, e.g. imagemagick.

That’s what I would probably do since it’s more efficient and simpler. No need for a compilation step or an interpreter. No need to trust the (likely complex) webassembly runtime to be bug free.

Edit: most responses are being made under the assumption that seccomp is the same as seccomp-bpf. The two are different and designed for different use cases. For example it is not possible to run a wasm JIT entirely under seccomp but is possible under seccomp-bpf. Seccomp was specifically designed for the use case described in this article by Shopify. You can read more about the differences here https://en.wikipedia.org/wiki/Seccomp


There is a big difference between running "third party native code" that you have some level of trust of (eg: image magick) vs having customers upload code to your infrastructure.

In the latter case I'm not aware of a single service that uses seccomp to do this. The closest to a non WASM setup is either things like Firecracker or to enforce some sense of sandboxed language like JavaScript. Seccomp quite often plays a role in keeping those sandboxes safe, but it's generally not used to have people execute arbitrary binary blobs on SaaS.

Having people compile code to WASM to execute it in a sandbox is becoming quite widespread. Shopify is not the first company to do that.


> Having people compile code to WASM to execute it in a sandbox is becoming quite widespread. Shopify is not the first company to do that.

Whether or not a technical solution is good is not dependent on it being employed by other companies. Using seccomp to run untrusted code is a better solution than wasm because it’s less code and more efficient.


That's a pretty bold statement. I'd like to see an in depth analysis between the two before supporting that.


It’s readily apparent:

More efficient: using wasm has a necessary compilation or interpretation overheard. Seccomp doesn’t.

Simpler: wasm requires deploying running an entire wasm runtime, likely >= 50K LOC in additional complexity and attack surface. Seccomp uses a small 100 line shim.


"readily apparent" is not good evidence. Security isn't as simple as number of lines of code. You need actual in depth analysis to even know the attack surface.

The reason why people view wasm as more secure is the runtimes used for it are VM's that control execution at an instruction level along with the wasm instruction set being far simpler than x86. Not saying wasm is magically secure because of this, there's not much actual security analysis of existing runtimes - but there are good reasons for why it can be viewed as more secure.


Wasm execution doesn’t exist in the abstract. Lucet, the vm in question, does no theoretical instruction-level mitigations of which you speak. It does, however, expose a larger attack surface than simply using seccomp (not seccomp-bpf).


By definition a WASM runtime running within seccomp does not increase the attack surface. That's in fact the whole point of layering such systems. I'm not exactly sure what your point is or why you're talking about seccomp-bpf here.


You can run WASM to grant fine grained access to certain APIs. You might be able to do this with a sidecar that provides the API over HTTP and then let the untrusted process only access the side car but why do this when you can just grant API access to a WASM module? From the perspective of the third party user the API can be called directly via a function instead of doing a HTTP request.


> Whether or not a technical solution is good is not dependent on it being employed by other companies

You said it's state of the art and simpler as WASM. I'm not actually aware of a single company using seccomp for what Shopify is doing (letting people upload custom code) so I would be quite curious to hear who does.


I never said anything was “state of the art” or made any claim that any company is using seccomp to accomplish what Shopify is doing.

I said that companies typically run third party native code, e.g. imagemagick, in seccomp to process untrusted data, e.g. user-uploaded image files.

If I were tasked with doing what Shopify is doing with wasm here, I would employ the seccomp-based solution since it’s equally applicable, it requires less code, and it’s more efficient. Whether or not other companies use a seccomp solution for this particular use case has no technical basis in determining its applicability for this use case. Seccomp was specifically designed for running untrusted code on your infrastructure, this exact use case.


And i would run wasm with a seccomp profile: You have the benefit of language designed which is hard to not do anything malicious (i guess theres still some possibility) and harden the execution environment (wasm runner) within a rootless pofman/docker container with a seccomp profile and restrictive selinux labels.

The world is not black and white, you can mix multiple solutions for more security. For what shopify is doing you need the most security you can get. Your example running a trusted application (imagemagick) with untrusted input is a lot easier to make secure than running untrusted binaries.


Using wasm in addition to seccomp-bpf (what you’re calling seccomp) strictly increases your attack surface. If you want to maximize security you would only use seccomp.

Imagemagick is not trusted to process arbitrary data, otherwise there would be no need to use seccomp. Seccomp was specifically designed for running untrusted binaries. Check references if you do not believe me: https://en.wikipedia.org/wiki/Seccomp#History


In a WASM + seccomp implementation, the whole WASM runtime runs inside seccomp. Breaking out of WASM leaves one running arbitrary asm inside seccomp, which has exactly the same attack surface as directly running untrusted binaries inside seccomp. The WASM layer in WASM + seccomp simply requires an additional exploit.


You’re referring to seccomp-bpf, not seccomp. Seccomp-bpf + wasm has a dramatically larger attack surface than just seccomp. Please check references if you do not know the difference between seccomp-bpf and seccomp: https://en.wikipedia.org/wiki/Seccomp


> Using wasm in addition to seccomp strictly increases your attack surface. If you want to maximize security you would only use seccomp.

Huh? How so?


The wasm vm has to parse, validate, and compile untrusted input. It also exposes host calls. Those are all potential attack vectors. That’s at least roughly 50K LOC.


>It also exposes host calls.

Only if you grant explicit access to them. What usually happens is that there is a vendor provided API that only gives you access to exactly what you need which is significantly less powerful than a complete linux process that can write to files, spawn background threads, etc all by default.

Yes you can block access to these things but you're going to miss something at some point.


In seccomp the only syscalls available are read, write, exit, and sigreturn. There is nothing to miss


I think WASM has the added benefit of being platform-independent - which is generally a good thing but can even be a security feature: With native code, even if run without privileges, you need to expose a lot of details about your hardware that malicious users could use to find vulnerabilities.

With WASM, the host can keep the actual hardware architecture and even the actual machine code that is generated a secret.


Yeah but there’s a nearly 100% chance your server platform is x86 and in the case that it changes, it will be a gradual change in the long term.

While it’s nice to have the platform independence, it has nearly zero practical utility here.

If you’re making a security argument, using seccomp over a complex webassembly runtime reduces your attack surface.


Security by obscurity?


Shopify is already a known seccomp user (for running Ruby in the mruby VM), so I think there's no reason to assume the WebAssembly runtime is not in a seccomp jail too.


That’s just redundant


Redundancy is sometimes good. When it comes to containing exploits, surely it's better to be safe than sorry.


I don't think you get security. It's about threat mitigation. There is nothing secure, including seccomp jails.

You want defence in depth - that is using multiple layers of defence to reduce the risk. You can never get it to 0, but if you combine two mechanisms that are each 99% effective, then your risk is now 0.01% instead of 1%. That's obviously an improvement.

You don't run your database without a password (hopefully) just because its behind a firewall. You want to have the password as well in case an attacker finds a way around your firewall (compromises a system on the inside) or you misconfigure your firewall.

Security in the physical world works the same way. You don't turn off the alarm and leave the bank doors open at the end of the day just because your vault is quite secure.


I don’t think you get the difference between seccomp and seccomp-bpf


You've been downvoted to oblivion. Don't you think that's a sign that maybe you're wrong?


Whether or not people who likely have no actual experience in this space dislike what I’m saying about the pointlessness of using wasm for this use case has no bearing on my correctness. Most of them demonstrated they didn’t know the difference between seccomp and seccomp-bpf and there have been no rational counter arguments that hold their weight.

Usually downvotes without rational rebuttals are a sign of the OP’s correctness.


I mention the downvotes because when you find yourself thinking you're right and everyone is wrong usually it's you that's mistaken.

In this case anyone with experience in computer security can tell you multiple layers of defense are always better than one.

Seccomp is great, and I think you actually have a point about it, but it's hard to get right without locking out all system calls entirely - and that's hard to do and still run a program, even a barebones C program.

With higher level languages it's immediately insufficient.


There’s no need for me to guess if I’m wrong or not, prove to me that I’m wrong. Thus far most replies have confused seccomp for seccomp-bpf.

Seccomp locks out every system call except for read, write, exit, and sigreturn. That’s why the extra defense afforded by wasm is superfluous here.


You're totally ignoring the parts I called you out on, which I'm tempted to view as a tacit admission you see your position there as indefensible.

The trouble is you can't run much in that environment - not even mmap or sbrk to allocate heap memory. It's basically embedded C without even malloc. In reality WASM is a more practical target because many high level languages can compile to it. Or you end up needing seccomp-bpf and now the burden is on you to provide enough functionality to run something without also providing so much to allow a sandbox escape.


Are you serious? You just allocate a large section of virtual memory before entering seccomp mode. This is not hard. I have used seccomp in production myself.

Not to mention sandboxed wasm is similarly restrictive and you need third-party library support to operate in that “embedded” environment. You don’t just get a normal runtime environment for free. Wasm simply gets you memory “bounds checks” but it’s not necessary if the isolate owns the entire process, as in the seccomp model.


Are you serious? You want to ask partners to write embedded C programs using a pre allocated virtual memory range?

It's obvious why they went for WASM instead.


My point was exactly that you don’t necessarily write your code for an embedded environment in the seccomp model. You provide code in a dynamic library format and the normal dynamic linker links the necessary calls (e.g. malloc) at runtime, exactly as a wasm would provide that environment (via WASI or whatever). Since those calls are all only implemented in terms of write,read,exit,and sigreturn you are guaranteed a high level of security.

Wasm is no different in this regard. You don’t get libc for free with wasm. The only thing you get with a wasm format is memory bounds checking but again that isn’t necessary in the seccomp model.


The big difference is the tooling gives you that for free with WASM. You can even run Go programs in WASM. You don't get that with seccomp.


Exactly, and there is probably a third redundancy too.


It's not an either/or. Most likely Shopify runs WASM inside an seccomp enclosure. Possibly inside a VM as well. Defense in depth.


Running untrusted code in a wasm vm doesn’t add any extra defense over just using seccomp. It just adds unnecessary overhead and increases attack surface.


Assuming that Intel / ARM microarch implementations are bug free, that is correct. In the real world there are no bug free implementations.

Edit. This is the strategy Chrome sandboxing uses: a hardened runtime (JS/WASM) inside a seccomp enclosure. https://chromium.googlesource.com/chromiumos/docs/+/master/s...


Running code in a wasm vm doesn’t magically prevent user code from exploiting uarch bugs. Lucet specifically does not mitigate spectre variant 2.


seccomp escapes are a thing and if you're inside a restrictive environment such as WASM, it is harder to achieve it.


I think you’re referring to seccomp-bpf. seccomp has never been escaped and it is unlikely such a bug could happen due its simplicity. If you do not know the difference between seccomp and seccomp-bpf, please check references: https://en.wikipedia.org/wiki/Seccomp


Unlikely? Sounds like you think it could happen.


Nothing is 100%. It’s effectively impossible.


This disproves your point. How many "effectively impossible" exploits have come out recently?


The semantic gymnastics here are pretty interesting. It’s about as secure / impossible to penetrate as anyone could reasonably guarantee in the face of future uncertainty. If you don’t understand why, please check references on how seccomp works: https://en.Wikipedia.org/wiki/Seccomp




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: