Insecure default variable initialization
Default values can lead to unsafe outcomes
JavaScript
What is insecure default variable initialization?
Insecure default variable initialization is a common programming oversight where variables, particularly those related to security, are initialized with insecure default values. This can happen, for example, when a variable related to user permissions is set to true
by default, which might grant unnecessary or unsafe permissions to users, or when boolean flags controlling sensitive operations are set to false, bypassing important checks or resulting in unsafe behavior. Recognizing and avoiding this pitfall is a fundamental part of secure programming practices.
About this lesson
In this lesson, you will learn how insecure default variable initialization works and how to protect your applications against it. We will begin by exploiting an insecure default variable initialization vulnerability in a simple application. Then, we will analyze the vulnerable code and explore some options for remediation and prevention.
Let's break down what happened in the story above where Ella determined that the cookies were not properly secured. The backend code of the login endpoint is the following:
At first sight, nothing seems off, but that is precisely the danger of default variable initialization.
As you might have noticed, the res.cookie
function takes in a name, a value and an optional options config. This config contains a range of options, such as when the cookie expires, the path, and some other cookie flags like secure
and httpOnly
, which are responsible for making the cookie not be transmitted over cleartext connections and preventing JavaScript from accessing the cookie.
In their initial state, these boolean variables are configured to the false
value. This leads to the secure
and httpOnly
flags being left on false
when they are not explicitly initialized.
Not only boolean values can be dangerous in their default state. The cookie configuration contains several other flags and options as well. One of these is a string type named samesite
which holds either none
, lax
or strict
as value. Leaving this value empty will result in the browser picking a default value rather than the server.
Depending on the browser used, this could default to none
as well, making the cookie even more insecure than initially thought.
What is the impact of insecure default variable initialization?
You might wonder, "how bad can insecure default variable initialization really be?" Well, it can have big consequences for your application's security, opening doors to sensitive data or functions that should remain locked.
Think back to our story about Ella and Social.corp
. Because the auth
and tracking
cookies didn't have the secure
flag, they could be sent over less secure HTTP connections. It's like sending private letters in clear envelopes; anyone can read them if they get intercepted! This is what we call a man-in-the-middle (MITM) attack. While this is not such an issue with the tracking cookie, the session cookie could be used by an attacker to take over the entire account.
But the problems didn't stop there. Without the httponly
flag, these cookies could be reached via client-side scripting, opening them up to cross-site scripting (XSS) attacks. Picture a scenario where an attacker sneaks a harmful script into the website. The XSS payload could fetch the session cookie, and just like that, they have everything they need to impersonate the user.
When we step back and look at the larger picture, insecure default variable initialization could create holes in your security without you knowing they were there in the first place. They might bypass your security checks, do things they shouldn't be able to, leading to data leaks, or even worse, they might take over the entire system.
Let's make this more tangible. Imagine you have a variable that decides whether user input should be cleaned up or not. If left as no cleanup
by default, this is like leaving your front door wide open while you're on vacation. It gives attackers a chance to play with SQL injection, XSS, and other nasty attacks. They could slip harmful code into your application, messing up your database or leaking sensitive data.
In the end, the impact of insecure default variable initialization can stretch wide and run deep. There is no single impact to define, as it all depends on the context of the variable and how this variable is used.
Neither does default variable initialization always have to happen because the developer forgot to initialize a variable. In some cases, it could be possible that you forward user input, where if the user input is left empty (on purpose by the attacker), the application will fall back to the default value.
A simple rule to remember is to always give your variables a secure initial value right when you create them. That way, even if you forget to set the value later, you don't leave any doors open to exploitation later on.
If you use objects that contain variables, make sure you understand what options they present and what their default values are (as with our cookie configuration example). This applies to practically all programming languages, but depending on the language, you also need to check how new classes and other instances are initialized and used when you don’t explicitly define a value to each property.
If you use objects that contain variables, make sure you understand what options they present and what their default values are (as with our cookie configuration example). This applies to practically all programming languages, but depending on the language, you also need to check how new classes and other instances are initialized and used when you don’t explicitly define a value to each property.
When creating JavaScript applications, pay attention to the following items:
- From the moment you create a variable, give it a secure value. Next to that, declare variables as close as possible to where they're used. If a variable is only needed in a function, keep it inside that function.
- Make sure you check and clean any data coming from the user. This helps to stop attackers from sending you anything that could harm your application.
- When writing functions, you can set default values for parameters in case they get left out. This helps prevent unexpected behavior. For example,
function doSomething(sensitiveData = safeDefault) {...}
. This also applies the other way around. If you are using functions, check out what the default values for left out parameters are. - When using third party libraries, read the documentation and understand the choices it makes (default values) when you implicitly use the API (functions, etc).
Let's apply these rules to our vulnerable Social.Corp code and mitigate the issue:
We’ve added a simple check to see if the username and password parameters were even set before we check them in the auth()
function.
Also, our session cookie now has secure: true
and httpOnly: true
, meaning they can only be sent over safe HTTPS connections and can't be grabbed through client-side scripting. This makes it much harder for attackers to get these cookies.
Additionally, we added sameSite: 'strict'
which enforces a stricter cookie scope on requests. By explicitly defining this variable, we do not rely on the browser's choice anymore. All Express cookie options can be found here.
Keep learning
To learn more about insecure default variable initialization, check out some other great content:
- The Mitre CWE classification: https://cwe.mitre.org/data/definitions/453.html
- A different but very similar default value CWE: https://cwe.mitre.org/data/definitions/1188.html