Category Archives: General

XSS in a Script Tag

Cross-site scripting is a pretty common vulnerability, even with many of the new advances in UI frameworks. One of the first things we mention when discussing the vulnerability is to understand the context. Is it HTML, Attribute, JavaScript, etc.? This understanding helps us better understand the types of characters that can be used to expose the vulnerability.

In this post, I want to take a quick look at placing data within a <script> tag. In particular, I want to look at how embedded <script> tags are processed. Let’s use a simple web page as our example.

<html>
	<head>
	</head>
	<body>
	<script>
		var x = "<a href=test.html>test</a>";
	</script>
	</body>
</html>

The above example works as we expect. When you load the page, nothing is displayed. The link tag embedded in the variable is rated as a string, not parsed as a link tag. What happens, though, when we embed a <script> tag?

<html>
	<head>
	</head>
	<body>
	<script>
		var x = "<script>alert(9)</script>";
	</script>
	</body>
</html>

In the above snippet, actually nothing happens on the screen. Meaning that the alert box does not actually trigger. This often misleads people into thinking the code is not vulnerable to cross-site scripting. if the link tag is not processes, why would the script tag be. In many situations, the understanding is that we need to break out of the (“) delimiter to start writing our own JavaScript commands. For example, if I submitted a payload of (test”;alert(9);t = “). This type of payload would break out of the x variable and add new JavaScript commands. Of course, this doesn’t work if the (“) character is properly encoded to not allow breaking out.

Going back to our previous example, we may have overlooked something very simple. It wasn’t that the script wasn’t executing because it wasn’t being parsed. Instead, it wasn’t executing because our JavaScript was bad. Our issue was that we were attempting to open a <script> within a <script>. What if we modify our value to the following:

<html>
	<head>
	</head>
	<body>
	<script>
		var x = "</script><script>alert(9)</script>";
	</script>
	</body>
</html>

In the above code, we are first closing out the original <script> tag and then we are starting a new one. This removes the embedded nuance and when the page is loaded, the alert box will appear.

This technique works in many places where a user can control the text returned within the <script> element. Of course, the important remediation step is to make sure that data is properly encoded when returned to the browser. By default, Content Security Policy may not be an immediate solution since this situation would indicate that inline scripts are allowed. However, if you are limiting the use of inline scripts to ones with a registered nonce would help prevent this technique. This reference shows setting the nonce (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src).

When testing our applications, it is important to focus on the lack of output encoding and less on the ability to fully exploit a situation. Our secure coding standards should identify the types of encoding that should be applied to outputs. If the encodings are not properly implemented then we are citing a violation of our standards.

JavaScript in an HREF or SRC Attribute

The anchor (<a>) HTML tag is commonly used to provide a clickable link for a user to navigate to another page. Did you know it is also possible to set the HREF attribute to execute JavaScript. A common technique is to use the onclick event of the anchor tab to execute a JavaScript method when the user clicks the link. However, to stop the browser from actually redirecting the HREF can be set to javascript:void(0);. This cancels the HREF functionality and allows the JavaScript from the onclick to execute as expected.

In the above example, notice that the HREF is set with a value starting with “javascript:”. This identifier tells the browser to execute the code following that prefix. For those that are security savvy, you might be thinking about cross-site scripting when you hear about executing JavaScript within the browser. For those of you that are new to security, cross-site scripting refers to the ability for an attacker to execute unintended JavaScript in the context of your application (https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)).

I want to walk through a simple scenario of where this could be abused. In this scenario, the application will attempt to track the page the user came from to set up where the Cancel button will redirect to. Imagine you have a list page that allows you to view details of a specific item. When you click the item it takes you to that item page and passes a BackUrl in the query string. So the link may look like:

https://developsec.com/item.php?backUrl=/items.php

On the page, there is a hyperlink created that sets the HREF to the backUrl property, like below:

<a href=”<?php echo $_GET[“backUrl”];?>”>Back</a>

When the page executes as expected you should get an output like this:

<a href=”/items.php”>Back</a>

There is a big problem though. The application is not performing any type of output encoding to protect against cross-site scripting. If we instead pass in backUrl=”%20onclick=”alert(10); we will get the following output:

<a href=”” onclick=”alert(10);“>Back</a>

In the instance above, we have successfully inserted the onclick event by breaking out of the HREF attribute. The bold section identifies the malicious string we added. When this link is clicked it will prompt an alert box with the number 10.

To remedy this, we could (or typically) use output encoding to block the escape from the HREF attribute. For example, if we can escape the double quotes (” -> &quot; then we cannot get out of the HREF attribute. We can do this (in PHP as an example) using htmlentities() like this:

<a href=”<?php echo htmlentities($_GET[“backUrl”],ENT_QUOTES);?>”>Back</a>

When the value is rendered the quotes will be escapes like the following:

<a href=”&quot; onclick=&"alert(10);“>Back</a>

Notice in this example, the HREF actually has the entire input (in bold), rather than an onclick event actually being added. When the user clicks the link it will try to go to https://www.developsec.com/” onclick=”alert(10); rather than execute the JavaScript.

But Wait… JavaScript

It looks like we have solved the XSS problem, but there is a piece still missing. Remember at the beginning of the post how we mentioned the HREF supports the javascript: prefix? That will allow us to bypass the current encodings we have performed. This is because with using the javascript: prefix, we are not trying to break out of the HREF attribute. We don’t need to break out of the double quotes to create another attribute. This time we will set backUrl=javascript:alert(11); and we can see how it looks in the response:

<a href=”javascript:alert(11);“>Back</a>

When the user clicks on the link, the alert will trigger and display on the page. We have successfully bypassed the XSS protection initially put in place.

Mitigating the Issue

There are a few steps we can take to mitigate this issue. Each has its pros and many can be used in conjunction with each other. Pick the options that work best for your environment.

  • URL Encoding – Since the HREF is meant to be a URL, you could perform URL encoding. URL encoding will render the javascript benign in the above instances because the colon (:) will get encoded. You should be using URL encoding for URLs anyway, right?
  • Implement Content Security Policy (CSP) – CSP can help limit the ability for inline scripts to be executed. In this case, it is an inline script so something as simple as ‘Content-Security-Policy:default-src ‘self’ could be sufficient. Of course, implementing CSP requires research and great care to get it right for your application.
  • Validate the URL – It is a good idea to validate that the URL used is well formed and pointing to a relative path. If the system is unable to parse the URL then it should not be used and a default back URL can be substituted.
  • URL White Listing – Creating a white list of valid URLs for the back link can be effective at limiting what input is used by the end user. This can cut down on the values that are actually returned blocking any malicious scripts.
  • Remove javascript: – This really isn’t recommended as different encodings can make it difficult to effectively remove the string. The other techniques listed above are much more effective.

The above list is not exhaustive, but does give an idea of ways to help reduce the risk of JavaScript within the HREF attribute of a hyper link.

Iframe SRC

It is important to note that this situation also applies to the IFRAME SRC attribute. it is possible to set the SRC of an IFRAME using the javascript: notation. In doing so, the javascript executes when the page is loaded.

Wrap Up

When developing applications, make sure you take this use case into consideration if you are taking URLs from user supplied input and setting that in an anchor tag or IFrame SRC.

If you are responsible for testing applications, take note when you identify URLs in the parameters. Investigate where that data is used. If you see it is used in an anchor tag, look to see if it is possible to insert JavaScript in this manner.

For those performing static analysis or code review, look for areas where the HREF or SRC attributes are set with untrusted data and make sure proper encoding has been applied. This is less of a concern if the base path of the URL has been hard-coded and the untrusted input only makes up parameters of the URL. These should still be properly encoded.

Understanding Your Application Platform

Building applications today includes the use of some pretty impressive platforms. These platforms have so much built in capability, many of the most common tasks are easily accomplished through simple method calls. As developers, we rely on these frameworks to provide a certain level of functionality. Much of which we may never even use.

When it comes to security, the platform can be a love/hate relationship. On the one hand, developers may have little control over how the platform handles certain tasks. On the other, the platform may provide excellent security controls. As we mature these platforms, we see a lot of new, cool security features enabled by default. Many view engines have cross-site scripting protections built in by default. Many of the systems use ORM to help reduce SQL Injection vulnerabilities. The problem we often run into is we don’t really know what our platform does and does not provide.

A question was posed about what was the most secure application platform, or which would you recommend. The problem to that question is that the answer really is “It depends.” The frameworks are not all created equally. Some have better XSS preventions. Others may have default CSRF prevention. What a framework does or doesn’t have can also change next month. They are always being updated. Rather than pick the most secure platform, I recommend to people to take the time to understand your platform of choice.

Does it matter if you use PHP, Java, .Net, Python, or Ruby? They all have some built in features, they all have their downfalls. So rather than trying to swap platforms every time a new one gets better features, spend some time to understand the platform you have in front of you. When you understand the risks that you face, you can then determine how those line up with your platform. Do you output user input to a web browser? If so, cross site scripting is a concern. Determine how your platform handles that. It may be that the platform auto encodes that data for you. The encoding may only happen in certain contexts. it may be the platform doesn’t provide any encoding, but rather leaves that up to you.

While the secure by default is more secure, as it reduces the risk of human oversight, applications can still be very secure without it. This is where that understanding comes into play. If I understand my platform and know that it doesn’t encode for me then I must make the effort to protect that. This may even include creating your own function or library that is used enterprise wide to help solve the problem. Unfortunately, when you don’t understand your platform, you never realize that this is a step you must take. Then it is overlooked and you are vulnerable.

I am also seeing more platforms starting to provide security guidelines or checklists to help developers with secure implementation. They may know of areas the platform doesn’t create a protection, so they show how to get around that. Maybe something is not enabled by default, but they recommend and show how to enable that. The more content like this that is produced the more we will understand how to securely create applications.

Whatever platform you use, understanding it will make the most difference. If the platform doesn’t have good documentation, push for it. Ask around or even do the analysis yourself to understand how security works in your situations.

Validation: Client vs. Server

Years ago, I remember being on a technical interview phone call for a senior developer position. What stood out was when the interviewer asked me about performing input validation. The question was in regards to if validation should be on the client or the server. My answer: The server.

What took me by surprise was when the response was that my answer was incorrect. In fact, I was told that Microsoft recommends performing validation on the client. This was inaccurate information, but I let it go and continued with the interview.
Recently, I have been having more conversations around input validation. In particular, the question of client or server side. While it is easy to state that validation should always be performed on the server, lets dig into this a little more to better understand your situation.

From a pure security perspective, input validation must be performed on the server. There is one simple reason for this: Any protections built using client-side techniques can be bypassed by using a simple web proxy. Using JavaScript to enforce that a field contains an email address can be easily bypassed by intercepting the request and changing it after the JavaScript has executed.

If you look at the threat model of your application, requests from the client to the server cross a trust boundary. Because of this trust boundary we know that the data needs to be validated again. Why? There is no way to know what happened to the data before it was received. We can assume the request was sent from a browser, used by a typical user. However, we don’t know if the data was manipulated after leaving the browser, or even sent from a browser at all.

That, however, is from a strict security standpoint. We must not forget that client-side validation serves a purpose as well. While client-side validation may not be trusted by the server, it tends to be more focused on immediate feedback to the user. Not only does this save a round trip, or many round trips, to the server, it cuts down on the processing the server needs to handle.
If we take an example of purely validating required fields on a form, we can immediately see the benefit of client-side validation. Even a small form, if not complete can create a lot of inefficiency if the user is constantly posting it without all the required fields. The ability to alert to this on the client makes it much quicker and cuts down on the number of invalid requests to the server.

Of course, this doesn’t mean that the user can’t fill in all the required fields to pass the client-side validation, intercept the request, and then remove some of those fields. In this case, server-side validation would catch this. The goal, however, of client-side validation is to provide a reactive user interface that is fast.

Understanding how each validation location functions and what the real purpose is helps us identify when to use each. While server-side validation is always required, client-side validation can be a great addition to the application.

Properly Placing XSS Output Encoding

Cross-Site Scripting flaws, as well as other injection flaws, are pretty well understood. We know how they work and how to mitigate them. One of the key factors in mitigation of these flaws is output encoding or escaping. For SQL, we escape by using parameters. For cross-site scripting we use context sensitive output encoding.

In this post, I don’t want to focus on the how of output encoding for cross-site scripting. Rather, I want to focus on when in the pipeline it should be done. Over the years I have had a lot of people ask if it is ok to encode the data before storing it in the database. I recently came across this insufficient solution and thought it was a good time to address it again. I will look at a few different cases that indicate why the solution is insufficient and explain a more sufficient approach.

The Database Is Not Trusted

The database should not be considered a trusted resource. This is a common oversight in many organizations, most likely due to the fact that the database is internal. It lives in a protected portion of your production environment. While that is true, it has many sources that have access to it. Even if it is just your application that uses the database today, there are still administrators and update scripts that most likely access it. We can’t rule out the idea of a rogue administrator, even if it is very slim.

We also may not know if other applications access our database. What if there is a mobile application that has access? We can’t guarantee that every source of data is going to properly encode the data before it gets sent to the database. This leaves us with a gap in coverage and a potential for cross-site scripting.

Input Validation My Not Be Enough

I always recommend to developers to have good input validation. Of course, the term good is different for everyone. At the basic level, your input validation may limit a few characters. At the advanced level it may try to limit different types of attacks. In some cases, it is difficult to use input validation to eliminate all cross-site scripting payloads. Why? Due to the different contexts and the types of data that some forms accept, a payload may still squeak by. Are you protecting against all payloads across all the different contexts? How do you know what context the data will be used in?

In addition to potentially missing a payload, what about when another developer creates a function and forgets to include the input validation? Even more likely, what happens when a new application starts accessing your database and doesn’t perform the same input validation. it puts us back into the same scenario described in the section above regarding the database isn’t trusted.

You Don’t Know the Context

When receiving and storing data, the chances are good I don’t know where the data will be used. What is the context of the data when output? Is it going into a span tag, an attribute or even straight into JavaScript? Will it be used by a reporting engine? The context matters because it determines how we encode the data. Different contexts are concerned with different characters. Can I just throw data into the database with an html encoding context? At this point, I am transforming the data at a time where there is no transformation required. Cross-site scripting doesn’t execute in my SQL column.

A Better Approach

As you can see, the above techniques are useful, however, they appear insufficient for multiple reasons. I recommend performing the output encoding immediately before the data is actually used. By that, I mean to encode right before it is output to the client. This way it is very clear what the context is and the appropriate encoding can be implemented.
Don’t forget to perform input validation on your data, but remember it is typically not meant to stop all attack scenarios. Instead it is there to help reduce them. We must be aware that other applications may access our data and those applications may no follow the same procedures we do. Due to this, making sure we make encoding decisions at the last moment provides the best coverage. Of course, this relies on the developers remembering to perform the output encoding.

Sub Resource Integrity – SRI

Do you rely on content distribution networks or CDNs to provide some of your resources? You may not consider some of your resources in this category, but really it is any resource that is provided outside of your server. For example, maybe you pull in the jQuery JavaScript file from ajax.googleapis.com rather than hosting the file on your server.
These CDNs provide a great way to give fast access to these resources. But how do you know you are getting the file you expect?

As an attacker, if I can attack multiple people vs just one, it is a better chance of success. A CDN provides a central location to potentially affect many applications, vs. targeting just one. Would you know if the CDN has modified that file you are expecting?

Welcome Sub Resource Integrity, or SRI. SRI provides the ability to validate the signature of the file against a predetermined hash. It is common for websites that provide files for downloads to provide a hash to validate the file is not corrupt. After downloading the file, you would compute the hash using the same algorithm (typically MD5) and then compare it to the hash listed on the server.

SRI works in a similar way. To implement this, as a developer you create a hash of the expected resource using a specified hashing algorithm. Then, you would add an integrity attribute to your resource, whether it is a script element or stylesheet. When the browser requests the resource, it will compute the hash, compare it to the integrity attribute and if successful, will load the resource. if it is unsuccessful, the file will not be loaded.

How it works

Lets look at how we would implement this for jQuery hosted at google. We will be including the reference from https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js

Initially, we might start by just creating a script tag with that as the source. This will work, but doesn’t provide any integrity check. There are a few different ways we can create the digest. An easy way is to use https://www.srihash.org/. The site provides a way to enter in the url to the resource and it will create the script tag for you.

Another option is to generate the hash yourself. To do this you will start by downloading the resource to your local system.

Once the file is downloaded, you can generate the hash by executing the following command:


openssl dgst -sha384 -binary Downloads/jquery.min.js | openssl base64 -A

Make sure you change Downloads/jquery.min.js to your downloaded file path. You should see a hash similar to:

xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f

Now, we can build our script tag as follows (Don’t forget to add the hashing algorithm to the integrity attribute:

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js” integrity=”sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f” crossorigin=”anonymous”></script>

Notice that there is a new crossorigin attribute as well. This is set to anonymous to allow CORS to work correctly. The CDN must have CORS set up to allow the integrity check to occur.

If you want to test the integrity check out, add another script tag to the page (after the above tag) that looks like the following:

<script>alert(window.jQuery);</script>

When the page loads, it should alert with some jQuery information. Now modify the Integrity value (I removed the last character) and reload the page. You should see a message that says “undefined”. This means that the resource was not loaded.

Browser support is still not complete. At this time, only Chrome, Opera, and Firefox support this feature.

Handling Failures

What do you do if the integrity check fails? You don’t want to break your site, right? Using the code snippet we tested with above, we could check to make sure it loaded, and if not, load it from a local resource. This gives us the benefit of using the CDN most of the time and falling back to a local resource only when necessary. The following may be what the updated script looks like:

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js” integrity=”sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f” crossorigin=”anonymous”></script>
<script> window.jQuery || document.write(‘<script src=”/jquery-.min.js”><\/script>’)</script>

When the integtrity check fails, you can see the local resource being loaded in the image below:

SRI-1

If you are using resources hosted on external networks, give some thought about implementing SRI and how it may benefit you. It is still in its early stages and not supported by all browsers, but it can certainly help reduce some of the risk of malicious files delivered through these networks.

Jardine Software helps companies get more value from their application security programs. Let’s talk about how we can help you.

James Jardine is the CEO and Principal Consultant at Jardine Software Inc. He has over 15 years of combined development and security experience. If you are interested in learning more about Jardine Software, you can reach him at james@jardinesoftware.com or @jardinesoftware on twitter.

Security Tips for Copy/Paste of Code From the Internet

Developing applications has long involved using code snippets found through textbooks or on the Internet. Rather than re-invent the wheel, it makes sense to identify existing code that helps solve a problem. It may also help speed up the development time.

Years ago, maybe 12, I remember a co-worker that had a SQL Injection vulnerability in his application. The culprit, code copied from someone else. At the time, I explained that once you copy code into your application it is now your responsibility.

Here, 12 years later, I still see this type of occurrence. Using code snippets directly from the web in the application. In many of these cases there may be some form of security weakness. How often do we, as developers, really analyze and understand all the details of the code that we copy?

Here are a few tips when working with external code brought into your application.

Understand what it does

If you were looking for code snippets, you should have a good idea of what the code will do. Better yet, you probably have an understanding of what you think that code will do. How vigorously do you inspect it to make sure that is all it does. Maybe the code performs the specific task you were set out to complete, but what happens if there are other functions you weren’t even looking for. This may not be as much a concern with very small snippets. However, with larger sections of code, it could coverup other functionality. This doesn’t mean that the functionality is intentionally malicious. But undocumented, unintended functionality may open up risk to the application.

Change any passwords or secrets

Depending on the code that you are searching, there may be secrets within it. For example, encryption routines are common for being grabbed off the Internet. To be complete, they contain hard-coded IVs and keys. These should be changed when imported into your projects to something unique. This could also be the case for code that has passwords or other hard-coded values that may provide access to the system.

As I was writing this, I noticed a post about the RadAsyncUpload control regarding the defaults within it. While this is not code copy/pasted from the Internet, it highlights the need to understand the default configurations and that some values should be changed to help provide better protections.

Look for potential vulnerabilities

In addition to the above concerns, the code may have vulnerabilities in it. Imagine a snippet of code used to select data from a SQL database. What if that code passed your tests of accurately pulling the queries, but uses inline SQL and is vulnerable to SQL Injection. The same could happen for code vulnerable to Cross-Site Scripting or not checking proper authorization.

We have to do a better job of performing code reviews on these external snippets, just as we should be doing it on our custom written internal code. Finding snippets of code that perform our needed functionality can be a huge benefit, but we can’t just assume it is production ready. If you are using this type of code, take the time to understand it and review it for potential issues. Don’t stop at just verifying the functionality. Take steps to vet the code just as you would any other code within your application.

Jardine Software helps companies get more value from their application security programs. Let’s talk about how we can help you.

James Jardine is the CEO and Principal Consultant at Jardine Software Inc. He has over 15 years of combined development and security experience. If you are interested in learning more about Jardine Software, you can reach him at james@jardinesoftware.com or @jardinesoftware on twitter.

Secure Notification Updates in FireFox and Chrome

There has been a steady increase in the number of applications that have switched to using HTTPS instead of HTTP for communication. Even sites that have no sensitive information or authentication mechanisms. Using HTTPS provides authentication and a secure channel to transmit data between client and server. The authentication verifies that you are communicating with the organization you thought you were. This secure transmission is meant to stop other parties from being able to read or manipulate the user’s traffic. For non-sensitive applications, it is that ability to manipulate the traffic that we are trying to protect against.

Mozilla announced that the next version of FireFox, Firefox 51, will be changing how it presents the lock icon to represent security issues with the site. Traditionally, there would be a green lock icon for secure sites and no lock icon for sites that use HTTP. The new changes will introduce a grey lock icon with a red slash through it when a site is using HTTP and collects passwords. In addition, there will be a note indicating that “Logins entered on this page could be compromised.”

Mozilla also hints at some additional changes on the roadmap. In particular, a potential indicator on the password field that will alert the user that the account details are insecure and may be compromised. It will be interesting to see how this feature will be implemented, especially if the browser will inject code into the application code. This could raise some concerns for many others out there.

Back in September, 2016, Google announced that Chrome was making similar changes that would take effect in January. I did a podcast on this which is included here.

Google is going further than just passwords and including credit card number fields. There wasn’t much mentioned for FireFox about anything other than passwords. In both browsers, changes should be available soon. Help spread the word about the new changes so your users, your friends, and your family know what the new indicator really means.

You may be surprised at the number, or type of sites that may be affected by this. There are many forums and other community sites that get created without using HTTPS for transmission. This may be because the site owner doesn’t realize the benefits of using HTTPS. They may also not think that the site contains sensitive information, so why add the overhead. However, many of these sites do require you to create an account and log in with a password. Unfortunately, many people re-use passwords so na attacker getting that forum password may have also just gotten your password for other sites. Not to mention, they could impersonate you on the specific site.

In the absence of sensitive or account information, using HTTPS provides protection from traffic manipulation. Even rising a corporate landing page, an attacker on the same network could inject malicious code into the response to attempt malicious activity on your system.

What are your thoughts? Are you for the browsers making these types of changes? Do you think it is an overreach? If so, why? Share your thoughts on twitter or join our slack channel to join the conversation (send me an email for an invite).


Jardine Software helps companies get more value from their application security programs. Let’s talk about how we can help you. James Jardine is the CEO and Principal Consultant at Jardine Software Inc. He has over 15 years of combined development and security experience. If you are interested in learning more about Jardine Software, you can reach him at james@jardinesoftware.com or @jardinesoftware on twitter.

Remember Me Features

Tired of constantly logging into your applications? Don’t you wish they would just remember you each time you visit, logging you right in? It isn’t as always easy to achieve such a status. There are multiple ways remember me can be implemented. Lets take a look at some of them.

Remember UserName

One of the most common ways for a site to implement the remember me functionality is to remember the username only. The username is typically stored in a cookie on the client’s computer. Remembering the username helps speed up the authentication process, but doesn’t eliminate it. The user still has to enter their password to gain access to the application. Although this is a common technique, some organizations may have data classification policies that don’t allow displaying the username in the application. This can also carry over to the username and the login screen. For these organizations, they may not implement a remember me feature at all. Remembering the username does contain some risk, as it instantly provides the username to an attacker on the user’s computer. This leaves just the password for the attacker to determine, which may be feasible if the user re-uses passwords that have been previously breached.

Long-term Auth Cookies

Another common technique for remembering a user is to set an authentication cookie that has a long life. Once you login, a cookie is created that may not expire for a year or longer. This allows you to be automatically logged in each time you visit the site. I am sure you can think of a few sites that provide this functionality. It is common among some of the social media sites people visit all the time. This is not recommended for any type of sensitive applications because it would allow immediate access to anyone that gains access to the user’s device.

Storing Password Locally (Remember Password)

Another option, that probably shouldn’t be an option, is storing the password on the user’s computer. This was recently seen on a web application, however we won’t mention the site that did this. We can, however learn from their decisions. In the application, they used CryptoJS to encrypt and decrypt this type of sensitive data. In this case, they stored the password in a cookie. With the encryption routines available on the client, it is possible to use them to decrypt the encrypted password with very little effort. This is typically the case any time the routines are made available, especially if the keys are available as well. While I am sure this was done with good intentions, the implementation is not very secure. As a matter of fact, it provides more of a false sense of security. This is most likely due to the use of encryption. It is not recommended to perform this type of encryption client-side, nor is it recommended to store the user’s password on the client like this.

What Next?

There are multiple options to help ease the burden of frequently logging into an application. Depending on the type of application, data stored, and sensitivity of the transactions, the options should be considered carefully. Providing the option to remember a username is convenient with some residual risk. Keeping a user logged in for extended periods of time increase the risk, but may be acceptable depending on the application and its use. Stay away from storing the user’s password locally on the computer they are using. Secure implementation is not easy or straightforward, increasing the risk levels.


Jardine Software helps companies get more value from their application security programs. Let’s talk about how we can help you. James Jardine is the CEO and Principal Consultant at Jardine Software Inc. He has over 15 years of combined development and security experience. If you are interested in learning more about Jardine Software, you can reach him at james@jardinesoftware.com or @jardinesoftware on twitter.

The 1 thing you need to know about the Daily Motion hack

It was just released that Daily Motion suffered a hack attack resulting in a large number of usernames and email addresses being released. Rather than focusing on the number of records received (the wow factor), I want to highlight what most places are just glancing over: Password Storage.

According to the report, only a small portion of the accounts had a password associated with it. That is in the millions, and you might be thinking this is bad. It is actually the highlight of the story. Why? Daily Motion used bcrypt to hash their user passwords before storing them.

Bcrypt uses both a salt value and a work factor when hashing the data. The salt has been a long time recommendation when hashing passwords as it can help reduce rainbow table attacks. The work factor, which has been recommended much more in recent years makes brute forcing passwords work intensive. This means that it requires more time per password, slowing down large cracking attacks.

Bcrypt is not the only option either. PBKDF and Scrypt are other available options that work in a similar way.

Using a strong algorithm makes it much more difficult to crack the passwords in the event that they are hacked some how. The use of any of these algorithms doesn’t rule out the possibility of cracking the passwords. They just make it much more difficult or time intensive. There are always circumstances that can change this. However, using one of these algorithms can go a long way in helping protect that data.

How are you storing passwords?

Take a moment to look at how you are storing passwords and consider how it will stand up in the event of breached account details. Do you use a unique salt for each password? Do you implement a work factor to slow cracking attempts down?

How would you handle this type of breach?

If accounts were to be breached like this, how would you handle it? Do you have a process in place? Would you force password resets? How would you notify users? Consider these types of questions to verify you have a plan in place.

James Jardine is the CEO and Principal Consultant at Jardine Software Inc. He has over 15 years of combined development and security experience. If you are interested in learning more about Jardine Software, you can reach him at james@jardinesoftware.com or @jardinesoftware on twitter.