Skip to main content

How Data Breaches happen and why Secure by Default software is the future

ยท 11 min read
Chris Thompson

Writing a few lines of code is pretty easy. You might have taken an Intro to CS class or taught yourself from a programming language book, and eventually you became pretty comfortable going from an idea in your head to code that actually runs.

You probably have a GitHub account with a few personal projects that you work on occasionally when you feel inspired. Looking at the code after some time, you might ask yourself "did I really write this?" It's with a fresh perspective that you notice the same code copy and pasted a few times in odd places.

For a personal project, that's probably okay. For a professional project involving a team of developers, it can quickly become a painful problem.

personal project

Example Personal Project

Professional Software Development Is Hard Work!

At work, every line of code you push to production is important. Writing a line of broken code could cause a problem for you, your team, the company, or even customers. Even just adding an extra space can create chaos!

Constant Vigilance!

mad eye moody from Harry Potter

Pictured: The author before his morning coffee...

Every day you either have a stand-up or send chat messages with your coworkers to stay in sync. Constant communication ensures the design is being adhered to, or change it when it's not working well. There is likely a task board where you and your team keep track of what's being worked on. Features that need to be added, bugs that need to be squashed, code that needs to be refactored, integrated, benchmarked, upgraded, cherry-picked, formatted, etc.

Keeping up-to-date with your team is a key part of your job, even if it's grueling. We often joke about Jira tickets and Java design patterns (like Enterprise FizzBuzz), but reality is that these tools exist to help you stay organized and avoid stepping on each other's toes.

Where does security come in?

At many companies, whenever you're working on a project that touches something sensitive or is otherwise critical to the business (like GDPR or PCI compliance), you're required to undergo a security review before deploying your code to production. This is often a grueling and time-consuming process that takes weeks (or months) for a Security Engineer to complete.

Because security reviews are expensive, lengthy, and painful to undergo, they're often reserved only for large changes like building an entirely new service. Instead, for the rest of the code, security reviews are often replaced in favor of security scanners that developers run themselves.

Self-Service Security

checkmarx application security testing

Static analysis tools, such as Checkmarx, have a limited set of vulnerabilities they look for. Even when a potential vulnerability is found, time is still required to verify the vulnerability is real, determine if it's actually important enough to fix, write and validate the code to patch it, and finally deploy it.

Unfortunately, security scanners are often more trouble than they're worth. They often create a lot of false positives, and they often don't have enough information to validate or fix the issues that they find. It's on you as the developer to sort through the issues and fix them.

That's not even the worst part: The green checkmark the scanner shows you frequently lulls you into a false sense of security. After all, you spent hours dealing with the issues it told you about! Surely, that means something, right?

Well, unfortunately, even if it looks like you've fixed all the issues with the code, it's often not enough to keep attackers from finding bugs anyway.

Frequently, the most impactful security vulnerabilities are found after code has been released. This is really painful because it gives external entities (like hackers) the opportunity to exploit the bug. By the time you're aware that a bug is being exploited by somebody, you're on the verge of a PR disaster. You've got to move quickly to patch it, figure out the impact, and notify all everybody involved of the hack.

Business > Security

Imagine you needed to ship a feature for a fast approaching deadline. And, as a part of quickly reaching that deadline, you imported a line of code from Stack Overflow, generated some code with GitHub Copilot), or installed a package from NPM. Because the business needed the feature urgently, and you were only modifying existing code, you only needed to run the security scanners. No issues found, you're good!

But, a few months later, you're still hacked. Only then do you realize: The line of code used by the hacker to gain access to your company's most sensitive data was the one you added without fully understanding the security implications of it.

You might feel silly, but you shouldn't feel beat yourself up about it because you're not alone. Even Facebook deals with these types of issues. The needs of the business often trump security, and that's just reality!

Accepting Reality

A clever solution to this problem is to just let the hackers hack you and to just directly pay them when they find bugs.

For many years now, companies have been creating Bug Bounty Programs to directly pay hackers for bugs they find. These programs are great for helping to find, but they only partially remedy the problem. Your company will likely need to have an entire team dedicated to monitoring this program. It takes a lot of time to review reports, validate them, and then work developers to fix the issues. That often puts these programs out of scope for smaller teams, or requires outsourcing the triage to contractors that aren't deep experts of your business.

And, even with a Bug Bounty Program, you're still at the mercy of the hacker. You don't know whether they are going to ethically disclose their vulnerability to you or not, or if they can make more money by exploiting it.

The DevSecOps Movement

The phrase "DevSecOps" is used to describe a trend that aims to continuously improve the security of software while it is being developed. With a DevSecOps process, developers are empowered by security teams to address security requirements directly, rather than waiting for the security team to perform a code review.

Security Scanners are often employed as a part of DevSecOps, but they're insufficient to rely on alone (for the reasons described above). Because of that, additional tools and strategies are being employed like Secure by Default and Zero Trust Architecture that are designed to make true DevSecOps possible. We'll explain what that means in the next section.

Flipping the Equation

What if security vulnerabilities just simply couldn't exist? Or if they did, have them be as useful to an attacker as dull safety scissors? What if, when a bug is found, it's no longer a security issue?

Those are the questions that have led many companies to implement a "Secure by Default" policy for their code.

A good example of this in action is the dangerouslySetInnerHTML function of the ReactJS framework. ReactJS is a Javascript library for building websites, and one of its key features is that it creates a virtual DOM before writing to the page's actual DOM. Building pages like this means that there is no opportunity for a hacker to inject HTML into the page since the ReactJS component, which could contain hacker controlled data, only ever treats this data as just data.

This pattern makes Cross-Site Scripting(XSS) attacks very difficult to perform by limiting the number of places they can even be performed. An XSS attack is only possible where dangerouslySetInnerHTML is used. A developer needing to insert some legacy HTML code isn't an uncommon task so XSS still happens, but the beauty of this function is that it is an escape hatch for a developer. It makes it easier for a developer to realize that what they are doing is dangerous. It lets developers remember, without needing a security expert to tell them, that it must be used sparingly (unless they like to live dangerously, in which case probably, they probably will have it everywhere in their code).

function createMarkup(content: string) {
return {__html: content};
}

function DangerousComponent(content: string) {
return <div dangerouslySetInnerHTML={createMarkup(content)} />;
}

function SecureComponent(content: string) {
return <div>{content}</div>;
}

Even though these two components look similar, the DangerousComponent contains an XSS vulnerability while the SecureComponent is not vulnerable since React protects code from XSS by default.

The Great Migration

As businesses begin to identify core issues in their technology, many of which are the catalysts for the innumerable breaches which happen every year, a stronger push will emerge for shifting the focus of security from retroactive analysis to proactive protections. The Secure by Default design is not a new idea, but it is a relatively new trend in software security that is just starting to gain traction along with Zero Trust Architecture.

The Building Security in Maturity Model (BSIMM) identifies that the majority of large companies are focused on this task of building security tools for developers in "Integrate and deliver security features" where it is suggested that companies centralize efforts to deliver security features to its developers to coalesce efforts that individual teams might be working on, or unaware of.

The sibling project Software Assurance Maturity Model (SAMM) by OWASP, echos this point in the Security Architecture section: "Direct the software design process toward known secure services and secure-by-default designs.".

Our Involvement with Security

We're building an Open Source project called LunaSec to help developers address these problems. The goal of LunaSec is to create drop-in, Secure by Default components that provide strong security and compliance guarantees, while not impacting a team's speed or efficiency when meeting deadlines. It's possible through the clever usage of Data Encryption through a process known as Tokenization.

Here's an example of the LunaSec React SDK in action:

// This React Component is vulnerable to XSS, and it leaks data to attackers.
export function renderInsecureComponent(props) {
return (
<form onSubmit={props.onSubmit}>
<label dangerouslySetInnerHTML={props.ssnLabel} />
<input name="ssn" value={props.value} onChange={props.onChange} errorHandler={props.handleError} />
<input type="submit" />
</form>
);
};

Now if we take the same code, and modify it slightly to use a LunaSec component:

import {SecureForm, SecureInput} from '@lunasec/react-sdk';

// This is still vulnerable to XSS, but it doesn't leak data to attackers anymore because of LunaSec.
// The only data that's leaked is an encrypted version of the SSN that does not give an attacker anything valuable.
export function renderInsecureComponent(props) {
return (
<SecureForm onSubmit={props.onSubmit}>
<label dangerouslySetInnerHTML={props.ssnLabel} />
<SecureInput name="ssn" token={props.value} onChange={props.onChange} errorHandler={props.handleError} />
<input type="submit" />
</SecureForm>
);
};

Even if the same vulnerable code path or configuration exists, because of LunaSec's Secure by Default design, the sensitive user data cannot be leaked without multiple points of compromise. (The SSN is encrypted, and decryption happens in a hardened environment with limited surface area for an attacker to find bugs in.)

Continuous Security

We believe Secure by Default is the future of Security Software because it's the only way to guarantee security every time a developer writes a line of code. It's not just us either -- even the US Government is adopting this security model now by embracing Zero Trust Architecture everywhere!

The next few years will see a lot of companies adopting this model, and we're excited to see what the future holds.

Help Us Make Secure By Default a Reality!

If you enjoyed this article, please take a moment to star our LunaSec GitHub repository, share this post with others, and consider adding yourself the list of companies protecting their data with LunaSec. It's Open Source and free to use!

To get started, you can check out our Live Demo and Documentation to learn more about what we're building, how it works, and how to get started using it with your production software.

For any questions about LunaSecs, this post, or about security in general, feel free to contact us. We're always happy to hear your feedback and learn about the problems people are facing!


Credits:

  • Photo of random number generator from here
  • Logo of Checkmarx from here
  • Photo of Mad Eye Moody here