Testing to find vulnerabilities in the application which could allow accidental or malicious access, misuse, modification, destruction, or disclosure of the application or data.
Definition
Security testing is to find vulnerabilities of your application. A vulnerability usually allows an attacker to trick the application into injecting data into its back end, execute commands on the system hosting the application, or use a flaw which allows for unintended access of memory to execute code with the privileges of the program. Some vulnerabilities arise from un-sanitized user input, often allowing the direct execution of commands or SQL statements (known as SQL injection), while others arise from more complex problems, such as unchecked buffers which can be overflowed so that code may be executed on the stack.
Successfully testing an application for security vulnerabilities requires thinking "outside of the box". Good security testing requires going beyond what is expected and thinking like an attacker who is trying to break the application. Creative thinking can help to determine what unexpected data may cause an application to fail in an insecure manner. It can also help find what assumptions made by web developers are not always true and how can they be subverted. This is one of the reasons why automated tools are actually bad at automatically testing for vulnerabilities, this creative thinking must be done in a case by case basis and most of the web applications are being developed in a unique way
It's impossible to build a perfect system that's immune to attack, remember security is a process, not a product. But security testing could help make such attack too time consuming that attackers would decide it's not worth the effort in doing so. Several tools exist that can aid in the discovery of vulnerabilities in a application but none can substitute the human element in vulnerability assessment.
When To Test
One of the best methods to prevent security bugs from appearing in production applications is to improve the Software Development Life Cycle by including security.
An effective testing program should have components that test;
- People - to ensure that there is adequate education and awareness
- Process - to ensure that there are adequate policies and standards and that people know how to follow these policies
- Technology - to ensure that the process has been effective in its implementation
Security testing should start alone with the application. By starting security testing early, it allows fixing the problem more quickly and at a lower cost. A key step in making this possible is to educate the development and QA organizations about common security issues and the ways to detect & prevent them. It is important to know how much security a given project will require. The information and assets that are to be protected should be given a classification that states how they are to be handled (e.g. confidential, secret, top secret).
Before Development Begins
- Test to ensure that there is an adequate software development life cycle where security is inherent.
- Test to ensure that the appropriate policy and standards are in place for the development team.
- Develop the metrics and measurement criteria.
*During Definition and Design*
- Security requirement review.
- Design Architecture review.
- Create a review UML model.
- Create a review thread model
During the Development
- Code walk-through and review
During the Deployment
- Application penetration testing
- Configuration management testing
After the Deployment
- Conduct Operational Management Reviews.
- Conduct Periodic Health Checks.
- Ensure Change Verification.
Test Techniques
Manual inspections and review
Manual inspections are human-driven reviews that typically test the security implications of the people, policies, and processes, but can include inspection of technology decisions such as architectural designs. They are usually conducted by analyzing documentation or using interviews with the designers or system owners.
Advantages
- Requires no supporting technology
- Can be applied to a variety of situations
- Flexible
- Promotes team work
- Early in the software development life cycle
Disadvantages
- Can be time consuming
- Supporting material not always available
- Requires significant human thought and skill to be effective!
Threat Modeling
Threat modeling helps people focus their inevitably limited resources and attention on the parts of the system that most require it. Threat models should be created as early as possible in the software development life cycle, and should be revisited as the application evolves and development progresses. Threat modeling is essentially risk assessment for applications. It is recommended that all applications have a threat model developed and documented. One of the treading modeling is STRIDE: Spoofing identity, Tampering with data, Repudiation, Information disclosure, Denial of service, Elevation of privilege.
Advantages
- Practical attackers view of the system
- Flexible
- Early in the software development life cycle
Disadvantage
- Relatively new technique
- Good threat models don't automatically mean good software
Source Code Review
Source code review is the process of manually checking a web applications source code for security issues. Many serious security vulnerabilities cannot be detected with any other form of analysis or testing. Many unintentional but significant security problems are also extremely difficult to discover with other forms of analysis or testing such as penetration testing making source code analysis the technique of choice for technical testing. Security source code review is different from normal code review in that reviewer is looking for security vulnerabilities instead of functionalities. My experience is that it's more efficient to do security code review after normal code review when the reviewer is more familiar with the code.
Advantages
- Completeness and effectiveness
- Accuracy
- Fast (for competent reviewers)
Disadvantages
- Requires highly skilled security developers
- Can miss calls to issues in compiled libraries
- Can not detect run-time errors easily
- The source code actually deployed might differ from the one being analyzed.
Penetration Testing
Penetration testing has become a common technique used to test network security for many years. It is also commonly known as black box testing or ethical hacking. While penetration testing has proven to be effective in network security, the technique does not naturally translate to applications. As web applications are almost exclusively bespoke, penetration testing in the web application arena is more akin to pure research. Penetration testing tools have been developed that automated the process but again with the nature of web applications their effectiveness is usually poor.
Advantages
- Can be fast (and therefore cheap)
- Requires a relatively lower skill-set than source code review
- Lots of web application pen testers available
- Familiar
- Tests the code that is actually being exposed
Disadvantages
- Inefficient
- Too late in the software development life cycle
- Front impact testing only!
Security Principles
Minimize Attack Surface Area
Principle of Least Privilege
Principle of Defense in Depth
Fail Securely
External System are Insecure
Separate of Duties
Do Not Trust Security Through Obscurity
Simplicity
Security Testing Areas
Because the big scope of the security areas, it's impossible for this document to cover all the security risks. Here are a list of the common security holes.
Input Validation
Input validation is the process of ensuring that a program operates on clean, correct and useful data. The most common vulnerabilities in this catalog includes SQL injection and cross-site scripting.
SQL injection is the act of passing malicious SQL code into an application. You should pay particular attention of the potential for SQL injection attacks when you process user input that forms part of a SQL command.
Example:
A web form returns employee title based on user input employee name. The application runs following statement after user input and the output is send back to the web page.
Select * From Employee where empl_name = 'user input'
When a malicious code "blah ' drop table Employee; --" is processed, the whole Employee table is dropped from the database.
When a malicious code "blah or 1=1;--" is processed, all data are returned to the user.
It's worth pointing out that two other potential vulnerabilities exists in this example:
1. The credential that the application run under must has permission to have SELECT permission on the database.
2. The error message generated from database server should be handled carefully. Most of the time, the error message contains two many valuable information.
Solution:
The real solution is to carefully validate all user inputs before using them, don't assume anything.
- Make sure user input values are with expected data type. Use numbers where possible.
- Check parameter data length for string type columns.
- Eliminate special characters if possible.
- Input should only contains value, not logic.
- Avoid concatenate SQL queries. In the rare case that dynamic SQL is needed, extra care is needed to make sure
- Escaping single quote of user input is not the whole solution. There are many attacks possible without using single quote and there are many ways to inject a single quote.
- Move the string concatenation into stored procedure doesn't solve the problem. It just makes finding the risk more difficult.
- Malicious user may not use standard input form, therefore server side validation is must.
Another type of input attack is cross site scripting. Cross site scripting attack occurs when the application gathers malicious data from user input.
Example:
One web site has an input box for user comment, then display the comment back to the page. If the web application doesn't check user input, it's easy for malicious user to input comments like "<script>do_sth_maclious</script>". When the comment is display back to the page, the java script code is executed automatically.
.NET disabled character "<" and ">" as valid user input by default. If you need to accept these characters and turn the feature off, the application needs to Escape them as "<" and ">".
Sensitive Data
Most web applications have a need to store sensitive information, either in a database or on a file system somewhere. The information might be passwords, credit card numbers, account records, or proprietary information. Frequently, encryption techniques are used to protect this sensitive information. While encryption has become relatively easy to implement and use, developers still frequently make mistakes while integrating it into a web application. Developers may overestimate the protection gained by using encryption and not be as careful in securing other aspects of the site.
Discovering cryptographic flaws without access to the source code can be extremely time consuming. However, it is possible to examine tokens, session IDs, cookies and other credentials to see if they are obviously not random. All the traditional cryptanalysis approaches can be used to attempt to uncover how a web site is using cryptographic functions.
By far the easiest approach is to review the code to see how the cryptographic functions are implemented. A careful review of the structure, quality, and implementation of the cryptographic modules should be performed. The reviewer should have a strong background in the use of cryptography and common flaws. The review should also cover how keys, passwords, and other secrets are stored, protected, loaded, processed, and cleared from memory.
The easiest way to protect against cryptographic flaws is to minimize the use of encryption and only keep information that is absolutely necessary. For example, rather than encrypting credit card numbers and storing them, simply require users to re-enter the numbers. Also, instead of storing encrypted passwords, use a one-way function, such as SHA-1, to hash the passwords.
If cryptography must be used, choose a library that has been exposed to public scrutiny and make sure that there are no open vulnerabilities. Encapsulate the cryptographic functions that are used and review the code carefully. Be sure that secrets, such as keys, certificates, and passwords, are stored securely. To make it difficult for an attacker, the master secret should be split into at least two locations and assembled at runtime. Such locations might include a configuration file, an external server, or within the code itself.
Authentication and Authorization
Authentication/Authorization includes deciding how many tiers the application should have, what authentication and authorization each tier should setup. This test should run at the architecture and design stage.
Authentication:
- Web Server: Which authentication should the web server use, Anonymous/Integrated? Kerberos/NTLM?
- ASP.NET: Windows authentication or form based? If form based, where and how are the username/password stored?
- Web Service: How is web service setup? How does credential pass from web application to web service?
- Database Server: Dedicated user vs. login user?
Authorization:
- What kind of authorization should be used?
- How many roles are needed, what privilege each role has?
- What role has permission or each URL?
- What role has permission on the File System?
- Database roles and permissions.
- Are all files under protection? can hacker uses relative path to access files without protection?
Best Practice:
- The authorization code should be modular, well structured, well documented and centralized
- Penetration testing should be used to determine if there is problem
- Components should authenticate itself to other components it's interacting.
Denial of Service
A denial-of-service attack is an attack on a computer system that causes a loss of service to users, typically the loss of network connectivity and services by consuming the bandwidth of the victim network or overloading the computational resources of the victim system. Defending against denial of service attacks is difficult, as there is no way to protect against these attacks perfectly.As a general rule, you should limit the resources allocated to any user to a bare minimum, avoid un-necessary access for unauthorized user, considering caching content for un-authorized user instead of retrieve from the system, check error handling routines to ensure an error doesn't affect the overall system.
E-Commerce Payments
Best Practice:
- Process transaction immediately.
- Do not store credit card numbers
- Do not display credit card numbers, even the last 4 digits.
- Do not use email to send sensitive information.
- Use strong type for money amount: "unsigned short" or "unsigned int".
- Set and check money amount limit.