Secure & Reliable

Privacy preserving products that run forever

As IoT has become embedded in our homes, the requirements from customers, manufacturers, and even governments for products to operate safely and securely for years at a time continue to grow.

The goal is simple: to efficiently deliver products that operate safely and correctly while respecting the user's privacy. Few companies have achieved this. Embedded JavaScript can help.

The Connection between Security and Reliability

Security and reliability are often treated as separate topics, but they are deeply intertwined. A mistake that causes the product to be unstable can be exploited as a vulnerability by an attacker.

There is an inevitable interplay between adding new features to a product and maintaining its security and reliability. The more a product does, the more complex its software architecture becomes. More code and more complexity increase the opportunities for subtle mistakes that can cause product malfunctions and allow security breaches.

Products need features. An IoT product would be more secure without a network connection, but it wouldn't be an IoT product. The IoT market is competitive. A product manager isn't going to agree to leave out a feature customers demand to minimize their security risks.

The solution is to build products on a foundation that eliminates vulnerabilities. Rather than teaching developers how to avoid introducing vulnerabilities in their code, we can give them a foundation to build on that takes care of those details for them. That way, developers focused on features don't also have to learn to be security experts.

Build on a secure foundation

Because of its heritage on the web, JavaScript has to be secure. If not, it would put at risk our financial data, personal conversations, medical information, and more. As a result, the JavaScript language has been designed with security as a core feature. No one wants their web pages crashing their computers, so JavaScript is also designed to be extremely reliable.

Good design isn't enough. An implementation of JavaScript needs to be correct. Thanks to the investments of the major browser vendors -- Google, Mozilla, Microsoft, and Apple -- there are tremendous amount of tools to confirm that JavaScript implementations are secure, reliable, and consistent.

Moddable uses these same tools to ensure that our XS JavaScript engine provides the foundation that embedded developers need to deliver feature-rich products that are also secure and reliable.

Key Tools Tools that we can tap into because of open source and open standards:
test262 The official JavaScript language test suite. Ensures every language feature is implemented correctly. 70,000+ individual tests.
Fuzzilli A fuzz tester from Google's Project Zero. Working together with Agoric Labs, we run at least 100,000,000 tests each day to search for vulnerabilities. We've extended Fuzzilli to test areas of XS that are unique to its implementation of JavaScript for embedded systems.
oss-fuzz A cloud-based fuzzing service provided by Google free of charge to select open source projects. This runs different fuzzing engines against the JavaScript engine and JSON parser in XS. It runs thousands of compute-hours of tests daily and has uncovered some very obscure issues.

Developers using a Moddable foundation have improved security and reliability, allowing them to focus on their product. Integrating fixes for fuzz testing issues has resulted in measurable improvements in product reliability during large-scale deployments, identifying and eliminating rare issues before they can occur in production.

Silicon-level security

Securing an IoT product requires more than just a single solution. The security of an IoT product involves multiple layers of protection against various types of attacks.

One way to enhance the security of an IoT product is to use Moddable, which focuses on securing the application layer. However, the manufacturer of the silicon used in the IoT product is responsible for securing the firmware itself.

Most commercial IoT products use silicon that includes several security features, such as secure boot, tamper resistance for firmware, firmware encryption, and one-time fuses. These features protect the firmware from being modified or reverse-engineered and prevent attackers with physical access to the microcontroller from initiating an attack.

To protect an IoT product, Moddable collaborates with clients to utilize the built-in security features of the microcontroller.

Secure Communication

Everyone knows that communication between IoT products and the cloud needs to be secure. There's even industry consensus that connections should be secured using TLS (Transport Layer Security). As long as you are using TLS, you are secure. Right? No. TLS has the potential to be secure, but it is the implementation of TLS in your product that actually makes it secure.

Because we have a secure foundation in JavaScript, we use that to build our TLS implementation. Implementing TLS involves a parsing several different data formats in addition to the protocol itself. An attacker can carefully craft malicious data that trigger vulnerabilities in native C implementations of TLS. But because of JavaScript's design, these attacks don't trigger vulnerabilities and the connection simply fails.

But it turns out that securing the TLS layer isn't enough. Because TLS is used as a secure transport layer for IoT application layer protocols include MQTT, HTTP, and WebSocket. If an attacker can't trigger a vulnerability in the TLS layer, they will go after higher layers. In the Moddable SDK, these protocols - HTTP, MQTT, and WebSocket - are also implemented in JavaScript, ensuring that they aren't vulnerable to parsing layers. In systems implemented in pure C, it is common to test the TLS layer for vulnerabilities but then pair it with an application protocol implementation that isn't tested for security vulnerabilities to the same degree.

Even that's not enough. The application protocols deliver data that is parsed by your product's code. A JSON payload, for example, can be crafted to trigger vulnerabilities. But because the our JSON parser is continuously tested for vulnerabilities, an attacker isn't going to find a way to initiate an attack. And if your product code does its own parsing in JavaScript, it won't be vulnerable to attacks using malicious data.

That's a lot of layers to get right. Just knowing to use TLS is the staring point. If attackers can't succeed at one layer, they will move to another. So they all need to be secure. And using embedded JavaScript is the most straightforward way to secure all of those layers in your IoT products.

Embedded JavaScript takes care of other details that can lead to security vulnerabilities. For example, there is no uninitialized data in JavaScript, making it impossible for a product to accidentally leak private user data to the network by forgetting to fully initialize a data buffer.

Ensuring the Reliability of your Code

Your code may not have security vulnerabilities, but how do you know it is working correctly?


Unit testing

Unit testing of JavaScript modules is common on the web platform, and Moddable brings it to Embedded JavaScript. Unit tests usually small focused test scripts that exercise a feature to ensure that it works correctly. An important aspect of unit tests is validating the modules handle error cases properly. Unit tests are a great way to quickly know that the individual modules in your system are behaving as expected.

The Moddable SDK integrates a unit test runner into the xsbug debugger. That makes it easy to both run and debug tests one place. Unit tests are written just like the JavaScript language tests in test262.

Some developers using Moddable SDK have adapted popular JavaScript testing frameworks, like Jest, for their unit tests.

Static analysis

The JavaScript ecosystem has created effective tools for identifying coding errors in JavaScript code. These tools can be used during the development process, and can catch a wide range of mistakes early on, which saves time. This is particularly helpful for rarely used sections of code, like error handling, which can take a long time to discover and correct. Our two favorite tools for this are Microsoft's TypeScript and eslint.

Eslint is an excellent tool for checking JavaScript code for potential errors. It has many built-in checks that can help ensure that code follows best practices. Teams can customize which checks are used to suit their specific project needs.

TypeScript is an extension of JavaScript that includes type annotations, which allows it to detect many types of mistakes. TypeScript compiles into standard JavaScript, which means it is 100% compatible with Embedded JavaScript. It is popular with teams that work on shared code bases because it can enforce conventions between modules developed by different groups.

Both eslint and TypeScript are fast enough to be used on every build. This means developers can take advantage of their checking capabilities throughout the entire development process. Additionally, both tools can be configured to report warnings instead of errors, allowing for gradual adoption in a code base.

Best practices for native code

One of the most powerful features of the XS JavaScript engine is the ability to call native C code from JavaScript. This is essential for projects to integrate with existing native libraries, integrate hardware features, and optimize performance. Native C code is outside the safe zone created by Embedded JavaScript. To avoid introducing vulnerabilities developers should follow best practices.

First, avoid introducing native C code whenever possible. Experienced Embedded JavaScript developers will often implement in JavaScript first, if at all possible,
Only switch to C where absolutely necessary. The XS in C API provides functions for writing the code that bridges between JavaScript and C. Using these functions ensures that your code will safely handle unexpected data types, missing parameters, and more. There are also functions for safely accessing binary data provided by scripts and to perform "brand checks" on native objects to make sure they are of the expected types.
Control access to native functions. For example, a module might have a native C function for its own use. By making sure not to export that function, it can ensure that no untrusted or malicious code can call the function.

Hardened JavaScript

Hardened JavaScript extends standard JavaScript that enhances security by providing least privileged access to untrusted code, using the Zero Trust approach. Let's say you want to use a third-party JavaScript module that offers classes for interacting with AWS. Without Hardened JavaScript, the code in the module has access to every part of your system, such as files, hardware, and screen, which could pose a security risk if the code comes from an untrusted source. Even if you trust the author of the module, modern systems rely on both trusted and untrusted sources, and you may need to integrate an untrusted module in the future. Hardened JavaScript offers the necessary tools to safely incorporate untrusted code into your product.

Hardened JavaScript introduces the concept of a compartment to JavaScript, which serves as a lightweight sandbox to limit the access of modules running within the compartment. Using a compartment can prevent the AWS module from accessing the file system, hardware resources, and more. Moreover, compartments can restrict the cloud servers that the AWS module can communicate with, preventing unauthorized sharing of the user's private data.

Moddable, Agoric, and Salesforce are among the organizations working to formally standardize Hardened JavaScript. The ECMA-419 standard for Embedded JavaScript recommends Hardened JavaScript in IoT products to eliminate unintended interactions between modules.