Skip to main content

LunaDefend can help protect against Open Source vulnerabilities

· 8 min read
Forrest Allison

From the beginning of the log4shell issue, we have been delivering actionable advice and tools which can automatically find and fix Log4Shell. We were quick to see the seriousness of the vulnerability, and helped the community to coalesce into an organized remediation effort. From experience, we know that those responding to Log4Shell are in a stressful situation.

It's easy to imagine walking into a meeting and not being able to tell your boss if data has been leaked. Even worse, to not be able to say for sure if an attack has happened or not. While many are having these uncomfortable meetings about security, there has never been a better time to lobby for more attention to security and the installation of stronger defences.

We want to make it known that there are ways to protect data against attacks like Log4Shell. For the better part of a year, we've been building an Open Source framework to make it so these vulnerabilities, even full RCEs like Log4Shell, can't leak the sensitive data that attackers are really after. It feels more relevant now than ever.

Modern attack surface

In security, we use the word "attack surface" to talk about how much territory we need to defend. I think of this like the walls and gates around an ancient city. The bigger the city is, the harder and more expensive it becomes to build walls and maintain fortifications.

Modern web applications are bigger and have more functionality than ever before, and this surface is becoming unmanageable. They use many tools and libraries, all of which could have a potential issue like Log4Shell. Looking forward to the next inevitable vulnerability like Log4shell, let's look at ways to reduce the size of that attack surface to a much smaller area of well-audited code.

Compliance focused tools

Getting sensitive data out of these potentially vulnerable web apps is becoming a popular strategy to help with legal compliance. The most popular tools to do this are token proxies which convert sensitive fields like a social security number, 435-12-9745, into some identifier token, token-1234-5678, which only refers to the sensitive field. While a company using a proxy such as this can quickly become compliant given they are no longer storing sensitive data themselves, these tools typically provide next to no actual data security. Their focus is mainly just on helping to comply with regulations.

In fact, our security researchers have identified actual vulnerabilities in some of these tools which may be trivially exploited, but more on that and the problems with token proxies in a future post. The short explanation is: there are just too many ways to easily get the protected data.

Some tools are better than others, but they all seem to have compromises and some attacks which they simply don't protect against. None of them seem to protect data once it reaches the browser. We wanted a way to truly protect data against every common type of attack, from browser attacks such as Cross Site Scripting (XSS), to full Remote Code Execution (RCE) like Log4Shell.

Tools that are ACTUALLY secure

There's one set of tools with a proven track record for protecting sensitive data on the web, and that's payment processors. We're talking about tools like Stripe and PayPal that collect your credit card number when you make an online purchase.

They are, in essence, a very small and dedicated web app that works alongside your main app. In the browser, your app launches an iFrame containing the payment processor's app. Users see a nice box with a trustworthy logo and get to type their credit card information into a safe place. iFrames (in cross-domain mode) are completely secure when done right because the browser treats them as a totally separate process. This is the strictest security tool the browser has. It's like the iFrame is running in a separate tab next to your site, only appearing to be a part of it.

After the user is done, the credit card number goes up to the payment processor's server. Your server talks to their server, and you get the bare minimum information you need to make the sale.

The sensitive data is isolated from your system every step of the way. Even if attackers break in, it will be very difficult to break through to the payment processor and get the credit card number. The attack surface for the payment processor is small because it's isolated from your site. Their security teams can audit the changes they make to their small system without worrying about the rest of your app.

Making that work for any data

This is a great strategy, and it's worked for decades. It makes sense: credit cards and the laws protecting them have been around for quite a while. Now that similar laws and concerns are expanding to more types of data, we need a more generic solution.

Those iFrames loaded by payment processors are designed to be obviously distinct from the app they're in. That's great for payments, but ideally a solution that could store any data wouldn't be so obvious to the user. We wanted to create an iFrame that visually and functionally disguises itself as a part of the surrounding website. Ideally it could be dropped into any form or output that handles sensitive data, all while looking like a native part of the web page.

We call them "Secure Components"

Dealing with all the DOM information to make the elements look and behave like normal ones took months, but we did it. The end result is something that looks and behaves just like a native element, even working well with popular component frameworks like Material UI. You can see for yourself in our Live Demo app. We've written more extensively about how Secure Components work in our docs.

A Secure Component in React, replaces a normal <input>
<SecureInput name="ssn" token={props.value} onChange={props.onChange} errorHandler={props.handleError} />

Just like how payment processors give you a "payment ID" instead of a credit card number, the components return a token that you can store legally and safely in your database, in the same place you used to put sensitive data. The secure data is handled by a small and secure backend that's blindingly fast, very cheap, and scales without limit.

Secure Functions

I personally think this is one of the coolest parts of LunaDefend.

Processing data serverside is sometimes needed. Sometimes you need to resize a photo, send something to another service, capitalize a line of text, send a GDPR report, etc. We want to give users a secure place to do these tasks. We knew there must be a way for a server to safely use secret data, even in the event of an RCE.

So now we are building Secure Functions. They look and act like normal functions in your server code, but in fact run in an ephemeral, sandboxed environment. Your server can pass a token into the function. The function can exchange that for real data, do what needs to be done, and return anything, just like a normal function would. Here's how these will look in Javascript:

Secure Photo Resize Example
import resizeImg from 'resize-image-buffer'

@secureFunction // this decorator transforms the function into a lambda
async function resizePhoto(token, width, height){
const {value} = await lunasecTokenizer.detokenize(token);
const resizedImage = await resizeImg(value, width, height);
const newResizedToken = lunasecTokenizer.tokenize(resizedImage);
return newResizedToken;

These functions are seamlessly deployed along with your actual application, requiring only a few changes. Because they're deployed to a hardened environment, Secure Functions reduce the impact of attacks like an RCE. You still need to make sure these parts of your code are secure, but it's much easier to audit something so small compared to auditing your entire server.


We haven't built a pay-as-you-go SASS for LunaDefend (at least not yet), because the tool is Open Source and most of our users have wanted to have their own deployments. Instead of leaving users on their own in terms of deployment, we wrote a CLI that uses AWS CDK to deploy everything needed to AWS with a single line:

lunasec deploy

Unlike token proxies, LunaDefend provides a method for testing your application locally, or in CI with AWS LocalStack, a containerized AWS emulator, which will also work in an offline environment. Calling

lunasec start

brings up everything you need on your development machine, including that local copy of AWS. Pretty neat! Soon we'll have a stubbed-out dev mode that doesn't need any servers running at all.


There are ways to protect data against attacks like Log4Shell, and we are working to make them accessible and affordable (actually, free), for normal companies and developers. We've also worked hard to make our docs a great resource, so please take a look or use the search bar if this article has left you curious. Thanks for reading!