310 likes | 490 Views
FIT3056 Secure and trusted software. Lecture 11 & 12 Testing and verification. Outline. Traditional software testing Traditional software verification and validation Secure software testing issues Secure software verification Verification of design Verification of implementation
E N D
FIT3056 Secure and trusted software Lecture 11 & 12 Testing and verification
Outline • Traditional software testing • Traditional software verification and validation • Secure software testing issues • Secure software verification • Verification of design • Verification of implementation • Verification of security policy • Secure software testing rules • Design a test plan • Set up test • Test the software and write report
Software testing • Software testing is an integral part in software development. Normally we need to test the correctness of our software, its performance, and reliability. • A testable design is a design that can be easily validated and maintained. Because testing is a rigorous effort and requires significant time and cost. Designing software which allows testability is also an important design principle for software development.
Software testing • Positive tests are called clean tests and they can only validate that the software works for the specified test cases. • Normally a finite number of tests can not validate that the software works for all situations. • Only one failed test is sufficient enough to show that the software does not work. • negative tests refer to the tests aiming at breaking the software or showing that it does not work. “Every method you use to prevent or find bugs leaves a residue of subtler bugs against which those methods are ineffectual” (old saying by many authors)
Software verification and validation • Verification: is the process of determining if we are building the product right. • The software should conform to its specification. • Validation: is the process of determiningifwe are building the right product. • The software should do what the users really require.
Secure software: design, implementation and testing • There are subtle security implications made during the design phase • Even if the design is secure, choices made during the implementation can impact security of the software. Eg. You may choose to implement your network application using socket or RPC and each software platform has different security issues. • Testing secure software is not testing the functionality of the software but its behaviours under different (known and unknown) circumstances. So how do we test if a program is secure? • How can we test the API? • How can we test if the software exposes un-encrypted data in the memory? Eg. A thread may fail to return and leave un-encrypted data in the memory. • How can we test if the software is exposed to denial of service attacks? Eg. Your server may run a bad script when a client sends a request included with code injection. • How can we test if the communication using the software will be hijacked? E.g; your client’s session may be hijacked after the authentication.
Secure software testing • Secure software testing is different from traditional software testing: • Software can be correct without being secure. • Security bugs are different from traditional bugs. • A security bug can allow code injection while a traditional bug which looks alike can just allow bad input without validation. • Security testing addresses software failures that have security implications. • Security testing requires different mind set, skills and knowledge. • Testing vulnerabilities requires security knowledge and experience rather than traditional software testing techniques.
Testing secure software • Traditional non-security bugs are often defined as a violation of a specification. • Security bugs are additional damaging behaviours. • Traditional testing techniques are not good at finding dangerous behaviours. They also overlook undesirable side-effects and cannot foresee possible future attacks. • Test data are often generated for normally secure environments. • You would likely generate test data like “ 12hjaja%5ada” or “12345678123z” to test if the input as a credit card number is accepted. • But you would not generate test data like “;/bin/chmod go=w /bin/*”
Traditional software general errors (non-security errors) • Incorrect • Supposed to do A but did B instead. • Missing • Supposed to do A and B but did only A. • Uncertain • Most the times it does A as it is supposed to do but sometimes it does not do exactly A.
Security errors • Errors causing side effects, damages, or inconvenience • Supposed to do A, and it did but in the course of doing A, it also did B (causing damages to the system or inconvenience to users). • Finding and removing errors which cause side effects and impact on security can be challenging • Side effects can be subtle and hidden (e.g: file writing, registry entry insertion, extra network packet insertion, etc.). • A script is designed to access database server to get information on requests of clients however, it can be exploited to allow attackers to gain the control of the server. How can we find all such possible errors?
Secure software testing: considerations • Information in memory: any data that an application uses will be in the memory eventually. • Encryption keys, passwords and other sensitive information are eventually used in an unencrypted form. We must protect their exposure in memory. It is extremely difficult to test if such information can be leaked when it is in the memory during the execution of the software.
Secure software testing: considerations • Stress testing: it is for low memory and other faulty operating conditions that may cause an application to crash leading to denial of service • an application may crash and can cause denial of service (most servers are subject to denial of service attacks). • an application may crash before completing an important task like encrypting passwords, keys or sensitive information. • Once it crashes the state of data is likely unknown.
Secure software testing: considerations • System dependencies: applications rely heavily on their environment to work properly can create security risks. • human input is not the only source but there are lots of other sources of input such as input generated by other programs or systems. if your software receives a value outside of its expected range, it can fail. • environment failures lead to calls on error-handling functions and error handling functions can be vulnerable. • Traditional software testing often makes the following assumptions: • Servers do not run out of disk space • File permissions are set properly • However, the above assumptions can be the cause of security problems when the server crashes.
Verification of the design • Before any security test is carried out, verification of the design must be done. • Secure software engineer team have to make sure all design principles for secure software have been used during the design phrase. • This can be done by checking if the final design describes the reason for a design principle not to be relevant/or relevant to the design and if there is a detailed analysis and application of the principle in the design. Eg: a user interface of a package was designed with minimum privilege and separated from code which accesses data.
Verification of the implementation • When the verification of the design has been done, the implementation of the software must be verified. • To verify the implementation of the software one has to check if the choice for the implementation is the best one to minimise security bugs. Eg: • strncp() should be used rather strcp() • higher level functions should be used where possible rather than lower ones. • dynamic memory allocation for un-encrypted sensitive information should be overwritten before it is returned to the system. • Tools should be used to detect security bugs resulted from poor security implementation.
Verification of the security policy • A security policy for secure software must be in place before the software is designed, implemented and tested. • To verify a security policy before you go to the test phrase is a must. Fail to do so can result in serious damages to the system because many security tests can temporary or permanently create security holes to your system. • The security policy should include what you can and cannot do during the test phrase.
Design a security test plan • A plan to test the security of your software must be carefully done and you need to be able to at least answer the following questions (pre-test questions): • Under what circumstances a denial of service attack can happen? • Do you need to test if your software is vulnerable to denial of service attack? • How can communication hijacking happen? • Do you need to test if your software is vulnerable to communication hijacking? • Can you generate mixed (data & commands) input to test all functions in your program? • Can code injection attacks happen to your code?
Design a security test plan • A plan to test the security of your software must be carefully done and you need to be able to at least answer the following questions: • Does your program invoke sever system calls? • Which API is in use? • Does your system allow object migration? • Is your code invoked by any other programs? • What other programming languages are used in your code? • Eg; database applications are programmed with C/C++ and SQL; shell scripts can call C code; etc. • Is your code system-dependent or portable? • If it is portable code then you will have to test the security of the code on all platforms because security mechanisms on one platform is different from another.
Write a real test plan for secure software • After you have verified the security of the design and implementation, and can answer the pre-test questions, you can write a real test plan for secure software which should include the following steps: • Scan the code for known static security bugs. • Tools can be used to statically scan buggy code. Eg: http://www.acsac.org/2000/papers/78.pdf
Write a real test plan for secure software 2. check system-related security problems • compiler optimisation (use different compilers to find if optimisation can cause security concerns), • old software library (check the version of library functions your program calls and test the library source code if you can), • new API (check if you program uses new API, if it does then check API functions in use carefully for vulnerabilities), • Communication software platform (if you are working with sockets, or RPC, or CORBA (Common Object Request Broker Architecture) , or .NET, then you need to check the security of the platform). • Check the OS vulnerabilities (see the documents for listed vulnerabilities such as things may cause kernel panic, stack overwrite, sticky-bit access, etc. Your program may facilitate the attacks which exploit those vulnerabilities.)
Write a real test plan for secure software 3. Write all possible ways of mixed input that you can generate (data and commands) • (data + commands) in text • Hex values of (data + commands) • Binary of (data + commands)
Write a real test plan for secure software 4. Write all possible ways for a code that can travel up in privilege when the code is owned by high privileged users and has world executable right.
Write a real test plan for secure software • Write a real test plan for secure software 5. Write all possible cases in which your code is invoked. For example, a C function can be written for use by a Java program may be later used by other programs written in other programming languages. E.g: (check syntax errors – I just type the code) char username[80], char password[20]; int hash_val ; int hash(char *str_of_chars); #include <sqlca.h> printf("Username? \n"); gets(username); printf(“Password? \n"); gets(password); hash_val = hash(password); EXEC SQL WHENEVER SQLERROR GOTO sql_error; EXEC SQL CONNECT :username IDENTIFIED BY :hash_val;
Write a test report • Testing software security is not always complete. The testing team must finally write a report in detail to describe: • what have been done to set up tests, • what tests have been carried out, • complete tests and incomplete tests, • limitations, • recommendation for incomplete tests, • your suggestions for future work.
Add things to the security policy • Before you start doing the security test (design the security test, write the test plan and carry out the real security tests), you need to know the security policy written during the design and implementation phases. • After you have completed the test, you must submit your report for changes to the security policy. • The server security has to be retested if it is going to be run on a different platform.
Software security policy • As a general guide, there must be a security policy available before any phase of secure software development. • The security policy can be enhanced or altered after each phase depending on many factors such as discovery of new threats, new release of related software that your software depends on, un-testable cases, etc.
Example of a secure software policy An example of secure software policy for developing code used by many employees of different roles in a large retail company: • Code injection must be considered as the main threat of your software. • Code separation principle must be strictly followed due to different users of different privileges. • Do not invoke any untested functions in your software including the code written by the same author(s). • Open source code is strictly prohibited.
Example of a secure software policy (con’t) An example of secure software policy for developing code used by many employees of different roles in a large retail company: • Any request for modification to the design, implementation, or test plan must be approved by the security team. • Modified software must be verified again and retested. • Integrity of the software must be checked when the implementation completed and after approved modified version.
Testing the software and writing a report • The real security tests must be carefully done. Some tests can be done in the test environment ad you may have done some tests in the production environment. • code injection tests can be done in the test environment, however they should be done carefully because powerful tests may cause unexpected side effects. • Running the application client remotely is normally through some real servers such as proxy, firewalls, VPN, or authentication servers.
Testing the software and writing a report • Wring a report after security tests are very important. • Some tests can leave real security holes in the system. The security team can prevent attacks by completely plug those holes. • Some tests may required some special setup and configuration which need to be reversed after the tests. This must be done to avoid any side effects.
Testing the software and writing a report Example of the report after security tests. The report should look like: • The test team had to create a temporary account (username, group, privilege, etc) to test remote clients and the account has been removed (date, time, etc). • A full system scan for applications of root privilege which will work with this software was done and the log file has been removed. • The test team sent its requests for the software to be fixed due to vulnerabilities (vulnerabilities, state, date, time, corresponding, etc).