Tag Archives: secure coding

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.

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

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?

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

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:

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

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.

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.

Using the AWS disruption to your advantage

By now you have heard of the amazon issues that plagued many websites a few days ago. I want to talk about one key part of the issue that often gets overlooked. If you read through their message describing their service disruption (https://aws.amazon.com/message/41926/) you will notice a section where they discuss some changes to the tools they use to manage their systems.

So let’s take a step back for a moment. Amazon attributed the service disruption to basically a simple mistake when executing a command. Although following an established playbook, something was entered incorrectly, leading to the disruption. I don’t want to get into all the details about the disruption, but rather, lets fast forward to considering the tools that are used.

Whether we are developing applications for external use or tools used to manage our systems, we don’t always think about all the possible threat scenarios. Sure, we think about some of the common threats and put in some simple safeguards, but what about some of those more detailed issues.

In this case, the tools allowed manipulating sub-systems that shouldn’t have been possible. It allowed shutting systems down too quickly, which caused some issues. This is no different than many of the tools that we write. We understand the task and create something to make it happen. But then our systems get more complicated. They pull in other systems which have access to yet other systems. A change to something directly accessible has an effect on a system 3 hops away.

Now, the chances of this edge case from happening are probably pretty slim. The chances that this case was missed during design is pretty good. Especially if you are not regularly reassessing your systems. What may have not been possible 2 years ago when the system was created is now possible today.

Even with Threat Modeling and secure design, things change. If the tool isn’t being updated, then the systems it controls are. We must have the ability to learn from these situations and identify how we can apply them to our own situations. How many tools have you created that can control your systems where a simple wrong click or incorrect parameter can create a huge headache. Do you even understand your systems well enough to know if doing something too fast or too slow can cause a problem. What about the effect of shutting one machine down has on any other machines. Are there warning messages for things that may have adverse effects? Are there safeguards in place of someone doing something out of the norm?

We are all busy and going back through working systems isn’t a high priority. These tools/systems may require an addition of new features, which makes for a perfect time to reassess it. Like everything in security, peripheral vision is very important. When working on one piece, it is always good to peek at other code around it. Take the time to verify that everything is up to date and as expected. Not any changes and determine if any enhancements or redesign is in order. Most of the time, these are edge case scenarios, but they can have a big impact if they occur.

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.

Insulin Pump Vulnerability – Take-aways

It was recently announced that there were a few vulnerabilities found with some insulin pumps that could allow a remote attacker to cause the pump to distribute more insulin than expected. There is a great write up of the situation here. When I say remote attack, keep in mind that in this scenario, it is someone that is within close proximity to the device. This is not an attack that can be performed via the Internet.

This situation creates an excellent learning opportunity for anyone that is creating devices, or that have devices already on the market. Let’s walk through a few key points from the article.

The Issue

The issue at hand was that the device didn’t perform strong authentication and that the communication between the remote and the device was not encrypted. Keep in mind that this device was rolled out back in 2008. Not to say that encryption wasn’t an option 8 years ago, for these types of devices it may not have been as main stream. We talk a lot about encryption today. Whether it is for IoT devices, mobile applications or web applications, the message is the same: Encrypt the communication channel. This doesn’t mean that encryption solves every problem, but it is a control that can be very effective in certain situations.

This instance is not the only one we have seen with unencrypted communications that allowed remote execution. It wasn’t long ago that there were computer mice and keyboards that also had the same type of problem. It also won’t be the last time we see this.

Take the opportunity to look at what you are creating and start asking the question regarding communication encryption and authentication. We are past the time where we can make the assumption the protocol can’t be reversed, or it needs special equipment. If you have devices in place currently, go back and see what you are doing. Is it secure? Could it be better? Are there changes we need to make. If you are creating new devices, make sure you are thinking about these issues. Communications is high on the list for all devices for security vulnerabilities. Make sure it is considered.

The Hype, or Lack of

I didn’t see a lot of extra hype over the disclosure of this issue. Often times, in security, we have a tendency to exaggerate things a bit. I didn’t see that here and I like it. At the beginning of this post I mentioned the attack is remote, but still requires close physical proximity. Is it an issue: Yes. is it a hight priority issue: Depends on functionality achieved. As a matter of fact, the initial post about the vulnerabilities states they don’t believe it is cause for panic and the risk of wide scale exploitation is relatively low. Given the circumstances, I would agree. They even go on to say they would still use this device for their children. I believe this is important because it highlights that there is risk in everything we do, and it is our responsibility to understand and choose to accept it.

The Response

Johnson and Johnson released an advisory to their customers alerting them of the issues. In addition, they provided potential options if these customers were concerned over the vulnerabilities. You might expect that the response would downplay the risk, but I didn’t get that feeling. They list the probability as extremely low. I don’t think there is dishonesty here. The statement is clear and understandable. The key component is the offering of some mitigations. While these may provide some inconvenience, it is positive to know there are options available to help further reduce the risk.

Attitude and Communication

It is tough to tell by reading some articles about a situation, but it feels like the attitudes were positive throughout the process. Maybe I am way off, but let’s hope that is true. As an organization it is important to be open to input from 3rd parties when it comes to the security of our devices. In many cases, the information is being provided to help, not be harmful. If you are the one receiving the report, take the time to actually read and understand it before jumping to conclusions.

As a security tester, it is important for the first contact to be a positive one. This can be difficult if you have had bad experiences in the past, but don’t judge everyone based on previous experiences. When the communication starts on a positive note, the chances are better it will continue that way. Starting off with a negative attitude can bring a disclosure to a screeching halt.


We are bound to miss things when it comes to security. In fact, you may have made a decision that years down the road will turn out to be incorrect. Maybe it wasn’t at the time, but technology changes quickly. We can’t just write off issues, we must understand them. Understand the risk and determine the proper course of action. Being prepared for the unknown can be difficult, but keeping a level head and honest will make these types of engagements easier to handle.

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.

Password Storage Overview

Start reading the news and you are bound to read about another data breach involving user credentials. Whether you get any details about how the passwords (that were stolen) were stored, we can assume that in many of these cases that they were not well protected. Maybe they were stored in clear text (no, it can’t be true), or use weak hashes. Passwords hold the key to our access to most applications. What are you doing to help protect them?

First, lets just start with recommending that the users don’t re-use their passwords, ever. Don’t share them across applications, just don’t. Pick a password manager or some other mechanism to allow unique passwords for each application. That doesn’t mean using summer2015 for one site and summer2016 for another. Don’t have them relatable in any way.

Now that we have that out of the way, how can the applications better protect their passwords? Lets look at the storage options:

  • Clear Text
  • Encrypted
  • Hashed

Clear Text

While this may seem harmless, since the data is stored in your highly secured, super secret database, it is looked down upon. As a developer, it may seem easy, throwing a prototype together to have the password in plain text. You don’t have to worry if your storage algorithm is working properly, or if you forget your password as you are building up the feature set. It is right there in the database. While convenience may be there, this is just a bad idea. Remember that passwords should only be known by the user that created it. They should also not be shared. Take an unauthorized breach out of the picture for a moment, the password could still be viewed by certain admins of the system or database administrators. Bring a breach back into the picture, now the passwords can be easily seen by anyone with no effort. There are no excuses for storing passwords as plain text. By now, you should know better.


Another option commonly seen is the use of reversible encryption. With encryption, the data is unreadable, but with the right keys, it is possible to read the actual data. In this case, the real password. The encryption algorithm used can make a difference on how long it takes to reverse it if it falls into the wrong hands. Like the clear text storage, the passwords are still left exposed to certain individuals that have access to the encrypt/decrypt routines. There shouldn’t be a need to ever see the plain text version of the password again, so why store it so that it can be decrypted? Again, not recommended for strong, secure password storage.


Hashing is process of transforming the data so that it is un-readable and not reversible. Unlike when the data is encrypted, a hashed password cannot be transformed back to the original value. To crack a hashed password you would typically run password guesses through the same hashing algorithm looking for the same result. If you find a plaintext value that creates the same hash, then you have found the password.

Depending on the hashing algorithm you use, it can be easy or very difficult to identify the password. Using MD5 with no salt is typically very easy to crack. Using a strong salt and SHA-512 may be a lot harder to crack. Using PBKDF or bcrypt, which include work factors, can be extremely difficult to crack. As you can see, not all hashing algorithms are created equally.

The Salt

The salt, mentioned earlier, is an important factor in hashing passwords to create uniqueness. First, a unique, randomly generated salt will make sure that if two users have the same password, they will not have the same hash. The salt is appended to the password, to basically create a new password, before the data is hashed. Second, a unique salt makes it more difficult for people cracking passwords because they have to regenerate hashes for all their password lists now using a new salt for each user. Generating a database of hashes based on a dictionary of passwords is known as creating a rainbow table. Makes for quicker lookups of hashes. The unique salt negates the rainbow table already generated and requires creating a new one (which can cost a lot of time).

The salt should be unique for each user, randomly generated, and of sufficient length.

The Algorithm

As I mentioned earlier, using MD5, probably not a good idea. Take the time to do some research on hashing algorithms to see which ones have collision issues or have been considered weak. SHA256 or SHA512 are better choices, obviously going with the strongest first if it is supported. As time goes on and computers get faster, algorithms start to weaken. Do your research.

Work Factor
The new standard being implemented and recommended is adding not only a salt, but a work factor to the process of hashing the password. This is done currently by using PBKDF, BCRYPT, or SCRYPT. The work factor slows the process of the hashing down. Keep in mind that hashing algorithms are fast by nature. In the example of PBKDF, iterations are added. That means that instead of just appending a salt to the password and hashing it once, it gets hashed 1,000 or 10,000 times. These iterations increase the work factor and can slow down the ability for an attacker to loop through millions of potential passwords. When comparing BCRYPT to SCRYPT, the big difference is where the work factor is. For BCRYPT, the work factor effects the CPU. For SCRYPT, the work factor is memory based.

Moving forward, you will start to see a lot more of PBKDF, BCRYPT and SCRYPT for password storage. If you are implementing these, test them out with different work factors to see what works for your environment. If 10,000 iterations is too slow on the login page, try decreasing it a little. Keep in mind that comparing a hash to verify a user’s credentials should not be happening very often, so the hit is typically on initial login only.


Password storage is very important in any application. Take a moment to look at how you are doing this in your apps and spread the word to help educate others on more secure ways of storing passwords. Not only could storing them incorrectly be embarrassing or harmful if they are breached, it could lead to issues with different regulatory requirements out there. For more information on storing passwords, check out OWASP’s Password Storage Cheat Sheet.

Keep in mind that if users use very common passwords, even with a strong algorithm, they can be cracked rather quickly. This is because a list of common passwords will be tried first. Creating the hash of the top 1000 passwords won’t take nearly as long as a list of a million or billion passwords.

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.

Disabling Paste for Passwords?

Passwords, while a simple concept, are one of the most complex issues in security. A majority of user authenticated systems rely on a password to verify the end user. Over the years we have seen many different recommendations for strong passwords. I have talked about this subject many times.

The complexity, while difficult to define, has gotten more difficult over time. At first, it was 8 characters with upper, lower case characters and a number or special character. The focus has shifted away from the types of characters and toward the length of the password. Common recommendations now say a strong password is at least 15 characters.

A popular recommendation from security professionals has been to use a password manager. A password manager allows you to store your passwords and protect them with a master password. The master password means that you only have to remember one long, complex password.

Using a password manager has many benefits. First, it allows you to store long, complex passwords without worrying about forgetting them. Second, it allows you to just copy and paste your passwords when signing into an application. This may not seem like that big of a deal, but many malicious programs use key loggers to steal passwords. If you paste the password in, and don’t type it, a key logger is useless. There are ways to grab data from the clipboard, but they are a less used tactic.

Some applications have started disabling the paste feature on password fields. This exists on some change password forms. The concern is that a typo entered in the password field would go unnoticed if pasted into the verify password field. The risk is the escalated customer support costs for lost passwords or account lockouts. Whether this is a valid risk is up to you. Few good reasons exist for disabling the paste feature on a password field.

The concern of recent is that the password field on the login form disables paste. In turn, this breaks many password managers. The benefits of good password management become degraded. Often, the reasons are due to a misunderstanding of how passwords are attacked.

Attackers do not rely on paste functionality for brute force attempts. In most situations, the attacker doesn’t even use the user interface for the attack. These type of attributes become useless against an attacker. Unfortunately, they only have a negative effect on the end user.

Don’t confuse disabling paste with disabling the autocomplete feature of a password field. Autocomplete is used for browsers to remember data for specific fields. While this is like what a password manager does, they are different. Autocomplete has been abused in the past and represents different issues.

Applications should be encouraging the use of password managers. They provide better password hygiene and ultimately help reduce the risk to the application. If you are making the decision to block the paste feature, prepare to answer to that decision. If the decision is well thought out and understood it will be easier to accept. Understand the reasoning behind the decision. It will generate a more enjoyable user experience.

If you experience an application that blocks your password manager, let them know. It is possible that they don’t even know it is an issue. As a customer, your opinion should matter. Stay positive and provide accurate information. Stay away from a negative stance. It will just make the business ignore your position.

Input Validation: Keep It Simple

Attackers take advantage of an application by manipulating the inputs to the system. For example, a first name field or even a request header like the user-agent. Applications wouldn’t be very useful if they didn’t accept any input from the end user. Unfortunately, this is the key attack vector. One of the basic techniques used to help protect a system is to us input validation, which assesses the input to determine if it is should be accepted.

Many development groups have fought with the concept of input validation in regards to how much should be done. Get to extreme with it and you may never implement it at all. It is important to understand what your goals are for the input validation, goals that should align with what the application does. Make the validation to complex and it is too easy to introduce errors. Start out with a simple plan, don’t go for the gusto out of the start gate. Here are some tips for starting out with input validation.

One of the easiest checks to implement is checking the data type of the input field. If you are expecting a date data type and the input received is not a valid date then it is invalid and should be rejected. Numbers are also fairly simple to validate to ensure they match the type expected. Many of the most popular frameworks provide methods to determine if a string matches a specific data type. Use these features to validate this type of data. Unfortunately, when the data type is a free form string then the check isn’t as useful. This is why we have other checks that we will perform.

You have determined that the input is of the correct type, say a number or a date. Now it is time to validate that it falls within the correct range of acceptable values. Imagine that you have an age field on a form. Depending on your business cases, lets say that a valid age is 0-150. It is a simple step to ensure that the value entered falls into this valid range. Another example is a date field. What if the date represents a signed date and can’t be in the future. In this case, it is important to ensure that the value entered is not later than the current day.

This is really more for the free form text fields to validate that the input doesn’t exceed the expected length for the field. In many cases, this lines up with the database or back end storage. For example, in SQL Server you may specify a first name field that is 100 characters or a state field that only allows two characters for the abbreviation. Limiting down the length of the input can significantly inhibit some of the attacks that are out there. Two characters can be tough to exploit, while possible depending on the application design.

White Lists
White lists can be a very effective control during input validation. Depending on the type of data that is being accepted it may be possible to indicate that only alphabetical characters are acceptable. In other cases you can open the white list up to other special characters but then deny everything else. It is important to remember that even white lists can allow malicious input depending on the values required to be accepted.

Black Lists
Black lists are another control that can be used when there are specifically known bad characters that shouldn’t be allowed. Like white lists, this doesn’t mean that attack payloads can’t get through, but it should make them more difficult.

Regular Expressions
Regular expressions help with white and black lists as well as pattern matching. With the former it is just a matter of defining what the acceptable characters are. Pattern matching is a little different and really aligns more with the range item discussed earlier. Pattern matching is great for free form fields that have a specific pattern. A social security number or an email address. These fields have an exact format that can be matched, allowing you to determine if it is right or not.

Test Your Validation
Make sure that you test the validation routines to ensure they are working as expected. If the field shouldn’t allow negative numbers, make sure that it rejects negative numbers. If the field should only allow email addresses then ensure that it rejects any pattern that doesn’t match a valid email address.

Validate Server Side
Maybe this should have been first? Client side validation is a great feature for the end user. They get immediate feedback to what is wrong with their data without having that round trip to the server and back. THAT IS EASILY BYPASSED!! It is imperative that the validation is also checked on the server. It is too easy to bypass client side validation so this must be done at the server where the user cannot intercept it and bypass it.

Don’t Try To Solve All Problems
Don’t try to solve all output issues with input validation. It is common for someone to try and block cross site scripting with input validation, it is what WAFs do right? But is that the goal? What if that input isn’t even sent to a browser? Are you also going to try and block SQL Injection, LDAP Injection, Command Injection, XML Injection, Parameter Manipulation, etc. with input validation? Now we are getting back to an overly complex solution when there are other solutions for these issues. These types of items shouldn’t be ignored and that is why we have the regular expressions and white lists to help decrease the chance that these payloads make it into the system. We also have output encoding and parameterized queries that help with these additional issues. Don’t spend all of your time focusing on input validation and forget about where this data is going and protecting it there.

Input validation is only half of the solution, the other half is implemented when the data is transmitted from the application to another system (ie. database, web browser, command shell). Just like we don’t want to rely solely on output encoding, we don’t want to do that with input validation. Assess the application and its needs to determine what solution is going to provide the best results. If you are not doing any input validation, start as soon as possible. It is your first line of defense. Start small with the Type/Range/Length checks. When those are working as expected then you can start working into the more advanced input validation techniques. Make sure the output encoding routines are also inplace.

Don’t overwhelm yourself with validating every possible attack. This is one cog in the system. There should also be other controls like monitoring and auditing that catch things as well. Implementing something for input validation is better than nothing, but don’t let it be a false sense of security. Just because you check the length of a string and limit it to 25 characters, don’t think a payload can’t be sent and exploited. It is, however, raising the bar (albeit just a little).

Take the time to assess what you are doing for input validation and work with the business to determine what valid inputs are for the different fields. You can’t do fine validation if you don’t understand the data being received. Don’t forget that data comes in many different forms or encodings. Convert all data to a specific encoding before you perform any validation on it.