1 / 48

Lesson 18-Software Development

Lesson 18-Software Development. Background. Software engineering is the systematic development of software. There is a universal requirement that the software works properly and performs the desired functions. Background.

Download Presentation

Lesson 18-Software Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lesson 18-Software Development

  2. Background • Software engineering is the systematic development of software. • There is a universal requirement that the software works properly and performs the desired functions.

  3. Background • Software engineering fits as many requirements as possible into a project management schedule timeline. • Analysts and developers work hard to get the functional elements correct. However, the issue of non-functional requirements gets neglected entirely.

  4. Background • Security has been described as a non-functional requirement. • It is usually placed into a category of secondary importance. • Trust is built upon an expectation that the software will work and continue to meet the requirements, and not change its behavior or functionality because of outside influences.

  5. Objectives • Upon completion of this lesson, students will be able to: • Describe how security should be incorporated into the software development process. • List the types of coding errors. • Describe the root causes of coding errors. • Describe good software development practices. • Explain good software development practices that impact application security. • Describe how using a software development process enforces security inclusion in a project.

  6. Software Engineering Process • Traditionally, security is an add-on item incorporated after the functional requirements have been met. • It is not viewed as an integral part of the software development lifecycle process. • The challenge lies in how to achieve this goal. • There are two elements to achieve this objective. • First, the inclusion of security requirements and measures into the specific process model being used. • Second, the use of secure coding methods to prevent any possibility of security failures in the software being designed.

  7. Process Models • The waterfall model. • The spiral model.

  8. Process Models • All process models have similar components. • The waterfall software engineering process model is characterized by a multistep process where the steps follow each other in a linear, one-way fashion, like water over a waterfall. • The spiral model has steps in phases that execute in a spiral fashion, repeating at different levels with each revolution of the model. • From requirements to system architecture to coding to testing, security is an imbedded property in all aspects of the process.

  9. Process Models • Requirements should define specific security requirements if there is any expectation of them being designed into the project.

  10. Process Models • There are four primary areas of interest, independent of the model or method employed: • System architecture acts to design a system that will meet the requirements that are identified at the requirements process. • The division of the overall requirements of the software into systems and subsystems also maps the requirements to these systems and subsystems. • The coding process for each component can have a significant impact on the security response of a system. • The testing phase of the project is the opportunity to determine compliance with requirements and, even, discover unexpected behavior that may result in security issues.

  11. Process Models • Independent of the method used, the process is about completing the requirements. • Opportunities exist independent of the model used to include security in the requirements process and security awareness during architectural design, coding, and testing.

  12. Process Models • The requirements process is key to including security in software development. • Security-related items enumerated during the requirements process are visible throughout the rest of the software development process.

  13. ROI and Error Correction • Developing a set of security requirements has a secondary result in the overall process – improved total cost of development. • Correcting errors results in additional work and expense and the level of rework and extent of extra work are direct functions of how late in the development process the errors are detected.

  14. ROI and Error Correction • Developing a software engineering process that detects errors as early as possible is critical. • This detection implies a level of testing that is distributed throughout the development process. • This distributed testing is guided by specific requirements to test against at each step of the development process. • From a cost point of view, it does not matter what the source or the classification of an error is, but the cost to rework is critical.

  15. Secure Code Techniques • Implementation of designs leads to the coding step in the software development process. • Instantiation of an idea in code is where errors enter the process. These errors are of two types: • The failure to include the desired function. • Testing for the first type of error is easy if the requirements are enumerated. • The inclusion of undesired behavior in the code. • Testing for the undesired behavior is more difficult since testing for an unknown – unknown is an impossible task.

  16. Buffer Overflows • The CERT/CC at Carnegie Mellon University estimates that nearly half of all software exploits stem from buffer overflow. • Buffer overflow classes include: • Static buffer overruns • Indexing errors • Format string bugs • Unicode and ANSI buffer size mismatches • Heap overruns

  17. Buffer Overflows • These vulnerabilities are relatively simple. The buffer used to hold program input is overwritten with data larger than the buffer. • The root cause of this vulnerability is a mixture of two things: • Poor programming practice • Programming language weaknesses

  18. Buffer Overflows • The first step to counter buffer overflow is to write solid code. • Regardless of the language used or source of input, treat all input from outside a function as hostile. • Validate all inputs as if they were hostile or were an attempt to force a buffer overflow.

  19. Buffer Overflows • The second step is proper string handling. • String handling is common in programs and is the source of a large number of known buffer overflow vulnerabilities.

  20. Buffer Overflow Sample Code • Replace the following code: { char buf[512]; gets( buf ); /* ... The rest of your code ... */ }

  21. Buffer Overflow Sample Code • With the following code: { char buf[512]; fgets( buf, sizeof(buf), stdin ); /* ... the rest of your code ... */ }

  22. Code Injection • Code injection is a technique where rather than the input being appropriate for the function, a piece of code is input that causes the function to act in an unintended way. • The primary defense for this vulnerability is similar to that for buffer overflows: validate all inputs. • Rather than validating just the length, the inputs also need to be validated for content.

  23. Code Injection Sample • In this example, the function takes the user-provided inputs for username and password and substitutes them into a where clause of a SQL statement. • Assume the desired SQL statement is: • select count(*) from users_table where username = ‘JDoe’ and password = ‘newpass’

  24. Code Injection Sample • The values JDoe and newpass are provided by the user and simply inserted into the string sequence. Though this seems functionally safe, it can be easily corrupted by using the sequence: • ‘ or 1=1 -- • Since this changes the where clause to one that returns all records: • select count(*) from users_table where username = ‘JDoe’ and password = ‘’ or 1=1 --‘

  25. Code Injection Attack (Java) • Imagine that the user puts the text for a JavaScript function in the middle of an input sequence with a call to the script. • Now, the generated Web page has an added JavaScript that is called when displayed. • Passing the user input through an HTML encode function before use can prevent such attacks.

  26. Code Injection • Good programming practice prevents these types of vulnerabilities. • This places the burden not just on the programmers but on: • The process of training programmers. • The software engineering process that reviews code. • The testing process to catch programming errors.

  27. Code Injection • The software development process accounts for the types and causes of these errors and have safeguards in place to prevent their propagation.

  28. Least Privilege • A central paradigm of security is the notion of processes running with the least required privilege. • Least privilege requires the developer to understand what privileges are required specifically for an application to execute and access its required resources.

  29. Least Privilege • As developers move from developing in an environment where there is no security to an operating system with built-in security, the natural tendency is to code around ‘new’ security requirement and programmers develop in the same way as before. • This is manifested as a program that runs only under an administrative level account, or runs as a service utilizing the SYSTEM account for permissions in Windows.

  30. Least Privilege • Designing and coding software with respect to access level controls is to plan and understand the nature of the software’s interaction with the operating system and system resources. • Whenever the software accesses a file, a system component, or other program, access control must be addressed.

  31. Least Privilege • Determine what needs to be accessed and what is the appropriate level of permission. • Use that level in design and implementation. • Repeat this for every item accessed. • When the application is designed, the process needs to be repeated with the installation procedure. • Frequently installing software needs a higher level of access than executing the software.

  32. Least Privilege • The cost of least privilege failure is two-fold. • First, there are expensive, time-consuming access violation errors that take a lot of time and effort to trace and correct. • Second is when an exploit is found that allows some other program to use portions of the code in an unauthorized fashion.

  33. Least Privilege Exploitation • The Sendmail exploit in the UNIX environment. • Sendmail requires root-level access for some functions. • This exploit inserts foreign code into the process stream and executes its code at root-level access.

  34. Cryptographic Failures • Proper use of cryptography can provide various functionalities such as: • Authentication • Confidentiality • Integrity • Non-repudiation

  35. Cryptographic Failures • A common mistake is the decision to develop your owncryptographic algorithm. • Cryptographic algorithms become trustworthy after years of scrutiny and attacks. • New algorithms take years to join the trusted set. • Deciding to use a trusted algorithm is a proper start, but there still are several major errors that can occur. • The first is an error in instantiating the algorithm. • An easy way to avoid this type of error is to use a library function that has been properly tested.

  36. Cryptographic Failures • Randomness: • Once you have an algorithm, and have chosen a particular instantiation, you need a random number to generate a random key since cryptographic functions use an algorithm and a key, the later being a digital number. • There are random functions built into the libraries of most programming languages. • These are pseudorandom number generators. • Although the distribution of output numbers appears random, it produces a reproducible sequence. • Using a cryptographic random number generator resolves this problem.

  37. Cryptographic Failures • Storing keys: • Storing private keys in areas where they can be recovered by an unauthorized person is the next source of potential failure. • Tools have been developed that can search code for ‘random’ keys and extract the key from the code or running process. • The bottom line is simple – do not hard code secret keys in the code, as then they can be discovered. • Keys should be generated, and then passed by reference, minimizing the transfer of copies across a network or application.

  38. Cryptographic Failures • Storing keys: • Storing them in memory in a non-contiguous fashion is also important to prevent external detection and, again, trusted cryptographic library functions come to the rescue.

  39. Additional Failure Modes • Making a security decision based on the name of a resource is dangerous. • There is more than one way to represent the name of an object. • A rose may always be a rose, but the same can be said of r%6fse, where one or more characters of the flower’s name are represented by hexadecimal escape code representations. • One defense is Canonicalization • Canonicalization is the conversion of a name to its simplest form. • Program errors from canonicalization errors can result in unexpected behaviors.

  40. Additional Failure Modes • Examples of this vulnerability include the IIS ::$DATA error, and a host of Unicode exploits to bypass checking based on URLs. • The best method to avoid these errors is not to trust filenames when making decisions. • If a filename needs to be used, the resource should be run through a canonicalization routine first.

  41. Additional Failure Modes • The failure mode may not cause a program to operate differently. It may tie it up so inspite of running, it may not be functioning – this is known as a Denial-of-Service (DOS) attack. • Denial-of-Service attacks come in many types and each has its own mode of operation. • Defending against Denial-of-Service attacks is complex. • It requires determining how the code is vulnerable and what safeguards will prevent the code from running forever. • One major rule is not to trust input – validate all input before using in a module.

  42. Good Practices • A software development process that has security planning built-in will make a difference in the end result. • The process begins with requirements and ends with testing. • Enumerating and defining the specific security requirements and how they are tested is a key element in building security into code.

  43. Requirements • Security requirements are often included at the end in a project. • Putting the security requirements in an overhead role and having the corporate backing to maintain an acceptable level of security functionality as a baseline solves many problems.

  44. Requirements • For example, making system requirements such as “Never trust input” to a function, and “validate all buffer lengths” can be built into a template for all modules that are developed.

  45. Requirements • Making a ‘code review’ requirement, where a second programmer is walked through the functionality of code before release to testing can catch many errors.

  46. Requirements • The requirements phase is the first step in a software development process model. • The details for all endproduct requirements are documented. • Since it occurs at the beginning of the model, it ensures all future steps are aware of the specific requirements.

  47. Testing • The testing phase is the last opportunity to determine that software performs properly before the end user experiences problems. • Testing can occur at each level of development, module, subsystem, system, and complete application. • The sooner errors are discovered and corrected, the lower the cost and the impact to project schedules.

  48. Testing • The use of use cases to compare program responses to known inputs and comparison of the output to the desired output is a time-proven method of testing software. • The design of use cases to test specific functional requirements occurs based on the requirements determined in the requirements phase. • Providing additional security related to use cases is the process-driven way to ensure that the security specifics are also tested.

More Related