What does the testing process incur with most applications today? The fact is that it is almost entirely functional in nature, done with automated tools run with preconfigured scripts that have little to do with security. Furthermore, most of the testing is done by testers, not developers. OK, the unit testing was done by developers, but what developer with time constraints writes JUnit tests that have anything to do with security? Managers and executives are only concerned with the functionality anyway so why waste your time right? Well, that depends on one question: Do you, the developer/manager/senior executive consider security as a feature of your application, or is it considered something that just adds time, resources, and therefore expense to the project's total cost?
Since you are reading this post I will assume that you are one of the enlightened ones that consider security a feature. For that, I applaud you and hope that you evangelize as much to the rest of your organization and to everyone that you meet. So the question now becomes, how do you do proper security testing of an application? You actually have many options available though they can be categorized into three somewhat broad categories: Manual Testing Only, Automated Testing Only, and Automated Testing along with Manual Testing and Review. Obviously, the last option is the best as it provides a quick overview of the application and will in most cases find almost all the low hanging fruit through the use of the automated tools, but it also provides in depth analysis through human intervention by having security testers probe the application in ways that the scanning tool may not be able to. The other two options, though still somewhat viable for those that do not have a large enough budget or time frame for option three, will always lead to problems and undiscovered vulnerabilities. If you are wondering, there are also various issues in regards to option three, and most of these issues will lead to undiscovered vulnerabilities in any application no matter what technology is used.
The problem with current testing practices is that is mostly performed by testers. If you are wondering what I mean look at it this way - many testers have no development background, they simply know the tools they are accustomed to and have no knowledge of the underlying infrastructure required to produce the applications they are testing. Some are not even familiar with simple HTML and JavaScript. A subsequent issue is that many testers are not even aware of many of the security issues plaguing applications today. So how do you handle this situation?
In my opinion, Microsoft has a good strategy. They actually have a position known as a Software Development Engineer in Test. These people actually write code, but the code that they write is to scrutinize the production code and applications that they are testing. They know how the applications work and are in a great position to find both functional and security related issues. Another option would be to hire testers that have proven security relevant experience. The testers should be quizzed thoroughly before being hired and prior experience should be mandatory and verified. As a third option, and best when used in conjunction with one of the previous two options, is to establish an application security team that consults with developers as they write applications and gets awareness out to the developers to further educate them of the risks present in today's world.
In any case, the only way to get "good" security testing results and maximize ROI is to have testers who understand the technologies in todays applications and have solid security testing knowledge. If these testers happen to be developers or even previous developers who are now testers, it doesn't really matter. The point is to have testers that understand the technologies. not testers who are experts at pushing the "test now" button on the latest and greatest functional testing software package.
SSH Hacking with Telnet
So, just today I was on a call with a vendor's "technical people" and they were trying to SSH into one of our servers. No problem, they were in through VPN and all seemed well until they told me they couldn't get into the box. "What are you doing?" I casually asked, and to my surprise, without missing a beat I hear "I opened a command prompt and typed telnet servername". That's right ... no port specified, not PuTTY, but regular old telnet. As I fell to the floor laughing, with the phone on mute of course, I thought to myself these people must be nuts. OK, enough about them, although this sets the context of my next discovery, and I apologize if this is old news: you can easily do banner grabbing of the specific version of SSH a server is running with telnet.
Take a look at this:

This little command will get you this:

As you can see, SSH gives you everything about it. Considering the recent Debian SSH debacle that also affects Ubuntu this makes it that much easier for attackers. So, if you are running SSH make sure you are up to date.
Take a look at this:
This little command will get you this:
As you can see, SSH gives you everything about it. Considering the recent Debian SSH debacle that also affects Ubuntu this makes it that much easier for attackers. So, if you are running SSH make sure you are up to date.
Simple robust input validation
In many of today's web applications input validation is either non-existent, only occurs on the client via JavaScript, or in a few cases actually happens on the server (where it should be regardless of whether it occurs on the client side or not). So you may say, "Ok I have mine on the server so I am ok right?". Well, the real answer is maybe. The reason I say maybe is because that complex logic that you have is of no use if it is not maintainable.
This brings me to my first issue with the way most input validation is implemented today. The problem is that all of this input validation is not centralized in the application. On the contrary, it is tightly coupled with the business logic, oftentimes located in the same class as the business logic implementation. So, I hear you asking, "Why is this bad?" and "That is just good OOP principles to have the validation logic in the same object that controls and manipulates the data. Its called Object Relevance". Well, I let me offer a slightly different perspective on that. Tightly coupling the validation logic with the business logic and/or data also violates a key principle of OOP: Single Responsibility.
The problem with this tight integration is that you now have duplicate logic throughout your application, which inevitably will become a nightmare to maintain when the time arises. Secondly and also attributed to the distribution of validation logic, multiple endpoints in the application are trapping and reporting back errors to the user. With all the endpoints, this reporting can become very difficult and many times impossible to keep consistent throughout the application. This becomes highly apparent in large scale enterprise applications when user testing starts. Lastly, these same endpoints are also most likely logging potential security related exceptions such as failed login attempts and database exceptions to the application's audit logs. (You do have audit logs don't you?)
So, where should all of this validation occur? The answer is surprisingly simple and draws on those OOP principles you so tightly clung to earlier. Validation should exist in its own set of classes that are externally configurable (properties files, xml config files, etc), are extensible (they can be customized to what the application needs), and be generic enough to be used across multiple applications. If you are looking for a word to sum up all of these characteristics, it is framework. In my opinion, a framework is the only way to go and there are some good ones out there already.
One of my personal favorites is the Struts Validator Framework. More information on Struts can be found here. Another great framework that has validation as one of its primary tenets is the OWASP ESAPI. This framework provides a complete set of functionality that any developer would need to implement to fully secure their application. The ESAPI not only provides great input validation, but also offers secure session management, robust access control solutions, as well as security logging features just to name a few. For applications that are already built and deployed and are just looking to beef up on input validation, Stinger is another solution also offered by the OWASP Project. Stinger is part of the OWASP Validation Project. Lastly, and always an option, is for developers to write their own custom validation engine, though this is not recommended due to the time and effort required and the fact that so many proven systems already exist.
So, what is the overall point to all of this: Input Validation is the first line of defense when protecting your application from attacks. It must be done, and it must be done right.
This brings me to my first issue with the way most input validation is implemented today. The problem is that all of this input validation is not centralized in the application. On the contrary, it is tightly coupled with the business logic, oftentimes located in the same class as the business logic implementation. So, I hear you asking, "Why is this bad?" and "That is just good OOP principles to have the validation logic in the same object that controls and manipulates the data. Its called Object Relevance". Well, I let me offer a slightly different perspective on that. Tightly coupling the validation logic with the business logic and/or data also violates a key principle of OOP: Single Responsibility.
The problem with this tight integration is that you now have duplicate logic throughout your application, which inevitably will become a nightmare to maintain when the time arises. Secondly and also attributed to the distribution of validation logic, multiple endpoints in the application are trapping and reporting back errors to the user. With all the endpoints, this reporting can become very difficult and many times impossible to keep consistent throughout the application. This becomes highly apparent in large scale enterprise applications when user testing starts. Lastly, these same endpoints are also most likely logging potential security related exceptions such as failed login attempts and database exceptions to the application's audit logs. (You do have audit logs don't you?)
So, where should all of this validation occur? The answer is surprisingly simple and draws on those OOP principles you so tightly clung to earlier. Validation should exist in its own set of classes that are externally configurable (properties files, xml config files, etc), are extensible (they can be customized to what the application needs), and be generic enough to be used across multiple applications. If you are looking for a word to sum up all of these characteristics, it is framework. In my opinion, a framework is the only way to go and there are some good ones out there already.
One of my personal favorites is the Struts Validator Framework. More information on Struts can be found here. Another great framework that has validation as one of its primary tenets is the OWASP ESAPI. This framework provides a complete set of functionality that any developer would need to implement to fully secure their application. The ESAPI not only provides great input validation, but also offers secure session management, robust access control solutions, as well as security logging features just to name a few. For applications that are already built and deployed and are just looking to beef up on input validation, Stinger is another solution also offered by the OWASP Project. Stinger is part of the OWASP Validation Project. Lastly, and always an option, is for developers to write their own custom validation engine, though this is not recommended due to the time and effort required and the fact that so many proven systems already exist.
So, what is the overall point to all of this: Input Validation is the first line of defense when protecting your application from attacks. It must be done, and it must be done right.
Whitelist input validation, where it becomes hairy
Everyone in the security field knows that the best way to protect your site from cross-site scripting (XSS) vulnerabilities is to implement proper whitelist input validation for all input fields, including hidden fields. This is not an easy task by any means, and requires significant planning on the part of the developers and architects to really determine what characters are acceptable for a given input. Some sets are easier than others, but I digress. One problem that I forsee, and sometimes have to address is when internationalized sites are not only internationalizing the display of text to the user, but are also required to accept various text encodings from the user. In this case, the input is also internationalized and your english whitelist just went out the window, at least for non-english countries.
Fortunately, websites are not completey out of luck. Although code samples such as
Fortunately for many, the Java Virtual Machine has supported POSIX style input validation for some time. Here is a code snippet that you can use that is functionally equivalent to "^[a-zA-Z]*$".
I hope this helps you in your development. I know it helped me when I found out about it.
Fortunately, websites are not completey out of luck. Although code samples such as
if (inputString.matches("\\w*")) { //do something } and Pattern strings = "^[a-zA-Z0-9]*$"; ... abound they really only apply to US-ASCII character sets. So, how does one validate against a larger character set, or better yet create validation routines that are character set agnostic? Enter POSIX validation.Fortunately for many, the Java Virtual Machine has supported POSIX style input validation for some time. Here is a code snippet that you can use that is functionally equivalent to "^[a-zA-Z]*$".
String posixAlphaCharacters = "\\p{Alpha}*";
if (inputString.matches(posixAlphaCharacters)) {
// do something cool
}
else {
// bomb horribly
}The problem with the above code is that it does not really give us anything. Many words that are spelled in their native way, such as München or España, will still fail this validation. So, we need to slightly tweak our code to broaden the character set. Take a look below.String posixLatinCharacters = "[\\p{InBasic Latin}\\p{InLatin-1 Supplement}]*";
if (inputString.matches(posixLatinCharacters)) {
// do something cool
}
else {
// bomb a little less horribly
}For the complete set of possibilities, review the Unicode Regular Expressions Definitions here.I hope this helps you in your development. I know it helped me when I found out about it.