How Shopify Uses WebAssembly Outside of the Browser
shopify.engineering
shopify.engineering
> 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.
> a new language like C
is a funny thought ^_^
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.
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
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
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.
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.
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.
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.
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.
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).
> 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.
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.
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.
* 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.
"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.
Not in terms of implementing the language.
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.)
This feels like a comment that will as age as badly as “you can’t get a virus just from looking at an email”
"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
You can express malicious things in Go, yet the number of RCEs in Go apps is pretty much zero.
You have to be more specific because lots of fraud is possible by misleading the user through JavaScript tricks.
[0] https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webas...
I'm still at a loss that Shopify still does not have a subscriptions product. :/
Can you say whether wasm helped make this happen? Seems quite plausible to me...
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...
I hope that changes, the sooner the better, but right now it's not trivial.
Same with Unity. Click build. Trivial
I suspect others are similarly trivial
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.
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.
> 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.
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.
Alternatively you can just use a runtime that is sandboxed by default and avoid the cat and mouse game.
(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".
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.
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.
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
With WASM, the host can keep the actual hardware architecture and even the actual machine code that is generated a secret.
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.
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.
Usually downvotes without rational rebuttals are a sign of the OP’s correctness.
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.
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.
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.
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.
It's obvious why they went for WASM instead.
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.
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.
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.
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 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.
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.
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
Huh? How so?
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.
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.
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.
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...