12.16.2009

Implementing Trust Between Systems

When designing or reviewing a system, it is common to ensure that trust is established between end-users and the applications. Trust in this context means that the users are trusted because they have proven their identity, and their authority to access the application has been verified. Many times, trust between system components is overlooked. This can be a deadly sin for software design that can lead to security vulnerabilities.

When trust is not established between system components, it means that any application that has access to the network can connect to the subsystem's exposed ports. For example, consider an application that exposes port 443 for receiving XML using HTTP over SSL. You might think that this is secure, since it uses encryption; however, encryption does not guarantee trust. Any web browser or system that supports HTTP over SSL can connect to that application and send malicious XML payloads.

You may say, "But my application uses a proprietary protocol that people would not understand." Unfortunately, security by obscurity is not security at all. With enough time or inside information, an application that does not require trust of the systems that connect to it may be easily compromised.

Trust generally comes with a certain amount of overhead. Here are two ways you can establish system trust in your application. First, you can require that all clients that connect to an open port present a user name and password or a shared secret key. This approach has the lowest overhead. When using web services, this can be accomplished using WS-Security. Second, you can use asymmetric encryption for non-repudiation to ensure that only the client could have connected because only it has a public key that can decrypt the message. This approach has high overhead, since encryption requires time and system resources, but it also ensures that the credentials are not exposed in clear text.

Many companies allow so many other companies into their networks, and insiders are frequently as much of a threat as external attackers. With this in mind, firewalls have limited value and are not very good at establishing trust. They are good for building a layer of security around your applications, but this does not compensate for a listening port that does not require trust.

How are your applications doing at establishing trust?

Labels: ,

1.25.2008

Secure Coding Practices, Part 11: The Checklist

This post wraps up the series on secure coding practices. Remember that secure coding begins with having coding standards that are communicated to software engineers. Awareness of the secure coding practices alone will help improve the security of your software applications.

Next, remember that source code must be reviewed. This practice may be performed by software engineers, by a security analyst, or both. Any violation of secure coding practices should be noted and tracked for follow up. Consider tracking these vulnerabilities in your defect tracking system to ensure they are addressed.

Please feel free to use the Red Light Security secure code checklist, "Fifty Questions to Improve Software Security", as a guide to get started. It summarizes all of the questions found in the posts of this series.

Labels:

1.24.2008

Secure Coding Practices, Part 10: Code Quality

Overall code quality is important for secure applications. Software bugs may create opportunities for attackers to exploit the application or gain information they should not have about system internals or even user credentials.

Security professionals may not know enough about the code they review to understand what is a defect and potential vulnerability. Some developers also overlook coding problems. This is why automated static analysis of source code is so important. Although it does not replace manual review, it is an excellent supplement to help find problems.

Keep in mind that these automated tools generally find a lot of defects that are not actually defects. Each warning created by these tools needs to be looked at and qualified before raising them as issues.

Below is a brief summary of some code review tools that are specifically geared for security. Try using different tools for the same code. It may help you find more defects.

SoftwareJavaC/C++PerlPythonComments
Commercial
Fortify SCA








  • Lots of other languages
    Ounce






  • Also .Net, C#, ASP
    Free Software
    FindBugs





  • Excellent choice
    Lint4J





  • Good choice
    RATS








  • Do you have other tools that work well for you to find security vulnerabilities in source code? Please share them in the comments section.

    Labels:

    1.23.2008

    Secure Coding Practices, Part 9: Performance

    One of the security professional's concerns is the availability of systems. Although this may seem like the sole responsibility of the IT operations department, security assesses the risk to the availability of critical information assets. This is because attackers may not care about retrieving information or gaining access to your systems. They may simply want to attack your system to make it unavailable for normal use.

    The most common term for this type of attack is Denial of Service (DoS). A DoS attack may be intentional or be caused by misconfiguration of another system. As a result, applications must be able to perform well under stressful operation.

    Performance factors vary widely depending on the server, operating system, third party software, and software languages.

    When reviewing source code, ask these questions to help uncover potential performance problems:

    • Is the application thread-safe?
    • Are variables encapsulated to limit their scope and prevent sharing between processes?
    • Are efficient algorithms used?
    • Are database transactions clearly defined and not subject to deadlocks?
    • Are database tables indexed appropriately?
    • Are file handles and connections to external systems explicitly closed?
    • Are all variables that are initialized actually used?
    It is better to find potential performance problems before there is a production outage, so that you can look at the source code thoroughly and objectively.

    Labels:

    1.22.2008

    Secure Coding Practices, Part 8: Cryptography

    Several volumes can be written on encryption. With the various protocols and and approaches to encryption, it can leave software developers uncertain about how it applies to them.

    Sensitive data must be encrypted. This may be to support compliance requirements, such as PCI and HIPAA, or it may be because your own organization has standards that require certain data to be encrypted. At a minimum, user credentials, like passwords, must be encrypted.

    Data can exist in three different states: 1) at rest, meaning it's stored in a file system, database, or archive media; 2) in transit, meaning it is moving from one system to another system or subsystem (usually over a network); and 3) in process, meaning it is being processed by an application and may be resident in memory or the CPU's registers. It is data at rest and data in transit that should be considered for encryption.

    In some cases, the transport layer may be used to allow encryption over a network The applications that receive this data will not need to decrypt the message. This means that data that is being stored will not be encrypted, unless the application storing the data or the storage layer itself performs the encryption. Examples of transport layer encryption are SSL, TLS, and IPSec.

    In other cases, encryption may be performed by the application, which means that the data can be sent across an unencrypted network, because it leaves the application encrypted. It also means that data can be stored directly on the file system or in a database, because the data is already encrypted.

    When looking at encryption, make sure your encryption protocol is sufficiently strong. The increasing performance of computers makes decrypting much easier for attackers. Consider protocols such as AES, 3DES, and TLS for starters.

    When writing or reviewing secure code, the following questions are important:

    • What is the sensitivity of the data being processed by the application?
    • Is encryption required for the data? If so, in transit, at rest, or both?
    • Does the application comply with your organization's standards regarding encryption?
    • Are standard, accepted encryption protocols being used, rather than home-grown algorithms?
    • Are passwords encrypted in transit and at rest?
    • Are keys used with encryption protocols managed securely in the application?
    Encryption is essential for certain information, but performance is also important. Make sure your application encrypts only what is needed to ensure optimal performance.

    Labels: ,

    1.21.2008

    Secure Coding Practices, Part 7: Error Handling

    Error handling is important in software applications. For developers, it may be a necessary evil, but for security professionals, it is a vital part of maintaining confidentiality, integrity, and availability. Error handling, tied with appropriate logging, is also important for investigation of incidents.

    One of the most important functions of error handling is that it must allow the application to fail securely. Errors or exceptions must not compromise the application by exposing confidential information or allowing the user to do what is unauthorized for their profile. Just like a firewall should fail closed, an application should fail securely.

    Errors and exceptions may mean that the information processed by the application has been processed incompletely. This may compromise the integrity of data or leave the application unavailable.

    When writing secure code or reviewing the code of others, be sure to ask the following questions:

    • Are exception handling mechanisms used consistently?
    • Does the application fail securely? If so, how?
    • Are open transactions processed appropriately if an error is encountered during processing?
    • Are error messages displayed to the users informative without revealing information about system internals or other sensitive data?
    • For function-based error handling, are return values of functions tested?
    • For exception-based error handling, are specific exceptions caught, rather than broad exception handlers (i.e. Throwable in Java)?
    • Are exceptions that are caught managed and logged (i.e. no empty catch{} blocks)?
    Remember that software testing may not reveal how an application will handle errors, since it is often unplanned combinations of events and data that expose them. This makes finding them in source code review essential.

    Labels:

    1.18.2008

    Secure Coding Practices, Part 6: Logging

    Logging is not always thought of as a security consideration, but it is important for on-going security monitoring. By logging events that help detect a security breach or attack, applications can provide early warning to security staff.

    Although security monitoring may be out of scope for developing your application, the capability to log security events is important. Choose a commonly accepted logging framework to make your work easier and to simplify integration with monitoring software.

    What should be logged? Typical audit events include authentication successes and failures, startup and shutdown of services, password changes, account lockouts, authorization decisions, job starts and completions, file transfers, and any other events that may be helpful in investigating security incidents.

    Questions to ask when creating or reviewing application logging functionality:

    • Are security-related events logged consistently?
    • Is sensitive information, such as passwords, kept from logs?
    • Are security events stored in a secure location and not mixed with common application logging?
    • Are events logged in a format and location that is compatible with security monitoring/event correlation software?

    Labels:

    1.17.2008

    Secure Coding Practices, Part 5: Session Management

    Session management security is especially important in web applications. A user can view and modify all information that is passed to and from a web browser. Popular browsers have plug-ins to make viewing and modification of HTTP traffic easy. As a result, the means of establishing, maintaining, and ending a session are in full view of the end user.

    To make session management secure, it is important to encapsulate sensitive information in a way that the user does not see the data, but the server-side application can still identify the user and session properties.

    Here are a few questions to consider when creating or reviewing web application software:

    • Is session data excluded from the URL using the GET method?
    • Does data in the browser cookie contain only the session ID and exclude other session information?
    • Are session IDs hashed to prevent attackers from guessing valid session IDs?
    • Are session IDs guaranteed to be unique?
    • Are sessions validated on each page request?
    • Do sessions expire after a period of inactivity?
    • Are expired sessions deleted on the server?

    Labels:

    1.16.2008

    Secure Coding Practices, Part 4: Data Validation

    Data validation is one of the most important secure coding practices, since it is the most exploited function of applications. Whether your organization creates web applications, desktop applications, or client server systems, data validation is crucial to protecting the applications, data, and servers on which they reside.

    The most important data to validate is data that has come from user input or is received from another system or outside source. It is at this interface of information that information cannot be trusted until it is validated.

    Validation of data is important to prevent:

    • Injection attacks caused by characters that change the functioning of the program
    • Buffer overflows caused by entering too much data in a fixed length buffer
    • Cross-site scripting, which allows attackers to change the presentation of a web interface to redirect user input
    • Data type validation, which may cause exceptions in programs that threaten system availability
    • File corruption or tampering to validate the sender and contents of the file
    Many data validation considerations can be found with automated static analysis tools, such as Fortify, Ounce Labs, Coverity, FindBugs, and Rough Auditing Tool for Security (RATS). These tools will alert you of many potential data validation issues. You will still need to review and validate the results, since these tools may produce false positives.

    File corruption or tampering will need to be caught through manual review. Look for system-to-system file exchange points. Using asymmetric keys to provide non-repudiation of the sender, using encryption, or simply creating a hash of the file for validation will go a long way to prevent problems caused by tampering with the files.

    Here are some review questions to add to your secure coding practices and your review checklist:
    • Are all user inputs validated?
    • Does validation check data length?
    • Does validation filter or escape special characters?
    • Does validation of web input remove tags before displaying it back to the user?
    • Does the application validate the data type of user input before operating on it?
    • Is XML received from outside of the application validated?
    • Is the integrity of files sent and received by the application validated?

    Labels:

    1.15.2008

    Secure Coding Practices, Part 3: Authorization

    Reviewing application authorization is an important consideration when reviewing code security. Authorization determines what users are allowed to do in the application after the they have successfully authenticated.

    Proper authorization supports separation of duties. Information is better protected by giving users the least privilege needed to perform their jobs. Applications must support fine-grained roles in order to implement separation of duties when assigning users to roles.

    When evaluating authorization in an application, here are a few questions to consider:

    • Are permissions defined to create fine-grained user access?
    • Are permissions defined for fine-grained administrator access?
    • Are permissions enforced consistently in the application?
    • Can permissions be grouped or organized to user roles for simplified access management?
    • Are roles and permissions consistent with standards or other applications in the enterprise?
    Make sure that your software developers understand the differences between authentication and authorization, as well as the importance of fine grained access to support separation of duties. Authorization controls are an important part of your secure coding guidelines and should be on your security code review checklist too.

    Labels:

    1.14.2008

    Secure Coding Practices, Part 2: Authentication

    When considering secure coding practices and security code reviews, one of the most important things to look for is effective authentication. Authentication in applications controls user and system access. Without a complete authentication solution, there will be opportunities for an attacker to find ways to obtain unauthorized system privileges.

    Here are some of the most important questions when evaluating authentication in applications:

    • Does each web request validate authentication?
    • Are credentials presented securely (i.e. using SSL, not using the GET method)?
    • Are passwords stored in an encrypted or hashed format?
    • Is password complexity enforced, including minimum length, non-guessable words, special characters, numbers?
    • Do user credentials expire after a period of time?
    • Are standards used for authentication and identity management (i.e. SAML, WS-Security, LDAP, NTLM, Kerberos)?
    • Are user accounts locked after a certain number of failed authentication attempts?
    If the answer to any of these questions is "no" then there is risk that authentication may be compromised. Risks in several of these areas may have been found in the requirements and design of the application. It is still important to verify that they have been implemented correctly when coded.

    Discuss these questions with software engineers. Document them as part of your secure coding practices, and verify them when you perform a security code review.

    Labels:

    1.11.2008

    Secure Coding Practices, Part 1

    When was the last time you did a security code review? If you are like most security professionals, this sounds foreign to you. For years, security has focused on the electronic perimeter, hardening of servers, patching third-party software, and access control. Today security is digging deeper into the nuts and bolts of the applications.

    This is the first article in a series on secure coding practices. The goal is to introduce the software engineering side of security to help you develop a more comprehensive skill set.

    One of the pillars of application security is secure coding practices. The security professional’s role in secure coding is first of all to help develop, communicate, and train software engineers in secure coding practices. To ensure that these practices are followed, security must be integrated into the software development process by performing on-going code reviews.

    Code review is not the starting point for security involvement in software development. Before beginning code review, it is important to review requirements to ensure that security controls are defined. It’s also important to review system designs to ensure that there are no design flaws that can be spotted at a high level.

    After security requirements are solid and the design looks good on paper, you are ready for code review. Code review for security is a combination of manual and automated processes. Your goal is to ensure that the security requirements and design artifacts are accomplished in the code and to uncover coding practices that expose application vulnerabilities.

    Begin with developing secure coding practices and train the software engineers in your organization to use them. These practices should provide guidelines for at least the following security functions:


    You will also need a code review checklist that covers these areas, along with sections for describing the system context, end users, confidentiality of information, and availability requirements. You will use this form to communicate to developers on risks and to make follow-up notes when risks have been closed. The completed template also serves as evidence of due diligence, if you ever experience a security breach.

    The articles that follow in this series will describe secure coding practices for each of the functions above to help you to develop secure coding practices, train your software engineering staff, and perform effective security code reviews.

    Labels: