 Hello, and welcome to my talk about web packages. Web packages is probably one of the greatest opportunities to make the web more secure and reliable. I know this title is too long, and I know this talk is not about web pack. So JavaScript tool, it's about web package, an upcoming specification on how to build and distribute websites. Let's deep dive. But before we go into web packages, I have two things to do. First of all, introduce myself. I'm Vladimir Dutukem. I joined Datadog as a senior software engineer earlier this year with the acquisition of Screen, which was a startup I've been working at for five years. Screen is a cybersecurity app sec-oriented company. And now at Datadog, I'm technical lead of the AppSec Tracer division. I'm also a Node.js core collaborator and an Node.js security working group member. Also, you can reach out to me at Paul Defet on Twitter. That's probably the easiest way to contact me. And my DMs are open. OK, quick disclaimer. I don't work on the web package specification when neither for any organism, when neither for Datadog. The content of this talk is about my own opinions about web packages in terms of security. And I'm not involved with web package and I'm not involved with web package in the scope of the organization I am a member of, whether this is Node.js or Datadog. So all of that is very personal and I am the sole responsible for the content of this talk. What is web package? And still, it's not about web pack. Web package is actually a set of three specs that define how to bundle a web application in a single file, how to distribute it with a signature and how to load it with a signature check. So basically, it's about building a website in a single file, signing it and loading it in a browser. Web bundle, well, it's basically a single bundle, a single file, and we'll see that in the live demo, which can contain anything you want as assets in a web application, whether that's HTML pages, JavaScript files, images, CSS or anything else. All of that in a single standardized distributed distributable file. You can distribute a full web application with that. Okay, let's go for the demo and let's hope everything goes all right. So on my screen, you should be able to see a terminal I haven't cleared out properly. We've got a small tic-tac-toe application that basically enables you to play tic-tac-toe and lose against yourself. This is a really cool app and I found it directly on GitHub by Googling Vania.js tic-tac-toe. So here is the original repo I took it from. So the question is, can we bundle this application and redistribute it? Hopefully, yes. So I will use a command named genbundle and I will provide as a first argument a directory which contains the source of a web application. Then I will say that I want as an output site.webbundle and I need to provide URLs. Base URLs and primary URLs will still be used to identify the resources. So here I say that my base URL is localhost port 3000. So I bundle it and here it tells me a lot of things that it has bundled it and you can see that it has generated URLs for each of the entries game.js and index.html style.css. If I refresh, I see that there is a new file in my directory which is site.wbn. So let's open that with our explorer and open a new window here and drag and drop the website to Chrome. Okay, so as you can see, we've got the whole website working without actually loading it from the localhost. I don't have any local server outside of the one from my AD and this has been loaded only through the web bundle. Okay, so to get there, I had to enable flag on Chrome. So you can check the Chrome page about web bundle if you want to do the same but basically, yes, that's still an experimental feature. So you need to enable it yourself. If we check what's in the network tab, we can see that the first thing that has been loaded is actually the file with a query string pointing to the base URL and the response is index.html because that's a default entry of a web bundle. Then the CSS and the JS file have been loaded exactly as if they have been served by a web server. That's actually pretty cool because all the assets of the web application have been loaded as if I had a running web server but only by dragging and dropping a file on my browser. That's pretty exciting. So the question you may have is what's inside this file and if I open it, well, we can see some stuff but it's unreadable properly by my ID. So we will use another command that is called dump bundle. Now I can see the content of the bundle in a human-friendly way and at the top, let me zoom in a bit. Oh, okay, definitely not what I wanted to do. So let's keep it this way, sorry about this miss. You have first a version. This is temporary while the spec is under building but then you've got details about the manifest telling the base URL and then for multiple URLs, you've got a URL, the statue code and the actual headers to use when serving the content. This means that we can actually set the distribution header within the web bundle. There's a comment for that. And when your website will be loaded in the browser, these headers will be added automatically when loaded in the browser. So here we've got our main entry point with our index page, our HTML code. I probably have missed something here, sorry. So here we've got another page which is our JS code here. We've got the JS code file that is also loadable properly. If we go under, we've got a redirection. So if you ask for index.html, it will actually answer with a 301 HTTP code and redirect to slash. That's actually really cool. You can even have complex flows like redirections within a web bundle. And the last file we have is the style file. So to get there, I used actually the tools available in the web package GitHub repo. Which are called GenBundle and DumpBundle. You can use also SignBundle to sign the bundle if you've got an HTTPS certificate available to sign it. That's the up-to-date way of building web bundles now. It's a go command. So you have to install it using go get and you have to install go on your machine. There's also a JavaScript implementation on NPM named WBM, but I haven't tested it, so I can't recommend it right now. That's you to test it. Okay, so we have seen the demo and that's really cool because this bundle you can distribute offline. If you want to give this bundle to someone else from your mobile phone, well, that's as easy as sharing a WhatsApp message or any other message service provider you use. The headers used to serve the apps are part of the deliverable. That's actually really important for the rest of this talk. Now a word about signed exchange. Signed exchange basically is about having the HTTPS signature in the bundle. So as you have noticed, every item in the bundle has a URL. So you can actually rely on HTTPS if you own the domain used for the URL. You just need to use the same certificate you would use on your domain, so you need to own this and you can sign the bundle with that, which means that from the URL, the web browser can check the certificate for the domain and check for integrity. That means that your web bundle can be distributed offline, but still has integrity check and that's actually pretty powerful. So this is a talk about security. So let me give you my opinions about the opportunities this brings to a more secure and reliable JavaScript world and web world. There are multiple opportunities here. Some of them are for the web browser. We have a standard way of adding security headers. And before I explain why security headers are important, I have to tell you a secret. It's a secret about web browsers. They don't instantiate web content. They instantiate web content under certain constraints. Basically, these constraints are defined by headers mostly and it's the equivalent of compiler flags for compiled languages. So let's take an example of security headers. If you haven't heard about content security policy, you're missing out on something really exciting. That's a header you can set when you distribute web content that actually defines the allowed origin for resource types. So in your CSP, you can say, hey, images can only be served by this hostname self or by this URL, this domain, like imagehosting.com. Or you can say that JavaScript code cannot be loaded unless they are sent from your current domain. And that's actually really powerful because it prevents people from exploiting some kind of XSS. Also, that's what you use to enforce trusted types. Trusted types are not well known yet, but they are one of the most exciting evolution of the front-end web security in terms of XSS protection. The TLDF of trustee type is that there won't be any eval injection that can't be prevented in the front-end anymore. That's the content for a whole totally different talk and I encourage you to check a talk that Mike Samuels gave at this conference two years ago. It's actually really, really, really exciting, a bit complex to handle, but so exciting. And both of them, origin definitions in CSP, entrusted types in CSP are actually hard to handle because in a world where security is defined by headers, well, these headers have impact on what assets the browser can load. So if you say, hey, I allow this CDN to serve JavaScript code, well, this is burnt, this is set by the CDN level, by the person that handled the Apache or the Nginx that serves your website, not the developer. So website developers know where to load the assets from. The website poster doesn't. So there is always a gap here. By bundling that into the web bundle, by having that part of the deliverable, the developer is so responsible of knowing where the assets come from and there is no lack of ownership because lack of ownership brings security issues. Another example of security header ex-fram options enable you to prevent your website from being loaded in a frame and avoid clickjacking. Once again, usually security headers are set by the people distributing the web content, CDN, CSADMINS, and not by developers. In that case, developers can have the control about the security headers configuration. Also, no need to configure all CDNs because Fastify is a way to configure, Cloudflare is a way to configure. I don't think GitHub as a CDN allows configuration of headers. Well, now there would be a standard way to actually set security headers and headers at large in web applications. Then you can have things to signed exchange, a way to provide integrity check, not only for script links. You can have real resource integrity checks for the whole application and that's great. If you don't trust your CDNs or the delivery chain, like the ISPs, well, you are sure they can't tamper with the web content anymore. There's also opportunities for Node.js on the server side. You probably know about supply chain attacks. Well, if the author of a package can sign it and if their NPM credentials gets stolen, well, you can still check that they were the one who published a version of the package because they would sign it with a private key that hopefully is not stolen. Meaning that it gets way harder to actually do what happened with the ESLint incident where the malicious actor actually published over stolen NPM credentials. You are scared because of the key might be stolen, but it's actually easier to steal a password and a username because some of them can leak rather than stealing a private key. So package signing is a good thing to create trust in the supply chain of web application building. This is promising, but the question is about key management and distribution. Not everyone has SSL certificate, so how do you do that? That's complicated. The other thing I really like and that's an opportunity for the Node.js side is that, well, we have a real concept of package cause right now we don't have a concept of package in Node.js. We have a table with a package.json file, but how do you define the package? Is it something that relies on a package.json, but how do you make sure this link is strong? Is it something in the same directory what about subdirectories? It's complex. We don't have a clear definition of what a package is. We have definitions of what a module is, what a script is, and we even have policies in Node.js that offers a way to check resource integrity at runtime, but only pair file, which is very powerful and related an amazing work with this feature, but it might be complicated in terms of user friendliness. If we move that at a bundle level, at a package level, meaning that with the signature, you are sure that there is no supply chain attacks, but also at runtime, you are sure that there have been no supply chain attacks and that the package you execute is the one that has been built by the package maintainer. But it goes beyond a friendly way of doing integrity check. What about per package authorization? Everyone is asking about OS access policies, C-Score policies, and there's a PR for that. And probably, I mean, I might be outdated, but you can do stronger things by relying on operating system features for that, but we could still membrane and prevent packages from accessing certain part of the code by package. But that might be terrible in terms of path because I will still need a bit of stack-trace exploration and introspection, and I haven't tested anything so don't get too excited. Even Dino does not provide this feature. Let's go to the next slide right now. You could also imagine to resign package in enterprise contexts who have a list of audited and usable dependencies, meaning that you are sure that as a security team, developers don't choose things that have not been validated, and that's actually very powerful. Okay, a few final thoughts. I love web packages. Yes, I do. Web package open multiple doors. For the browser, security header management is easier, resource integrity wants for all. For Node.js, we can have resource integrity by the author and a standard concept of package, which opens a lot of doors. Again, I have a confession. I am ambivalent regarding the signature part. It brings cool goodies, but it can break ad blockers. But signature is optional. Probably it's okay then. We could distribute code around the world in a better way with web package. We can standardize web application delivery. It's a vendor-neutral package concept, meaning that you are not tied to the configuration of a single CDN. And all of that is still under active discussion, so if you have strong opinions, now is the right time to probably spam some people who should not be named in this talk because I don't want them to be mad at me. Thanks so much for your attention. Let's keep in touch. Once again, Twitter is the best way to contact me. And the slides are already on iCloud. Feel free to browse them. Thanks so much again for your attention. I hope we will see each other soon in physical conferences. Until then, take care of yourself.