Build Security, Test Security or Both?
Generally
it is easier to build a secure software than to correct security flaws later,
let alone an eventuality of a security breach. Cost of a security breach can be
humongous and unbearable at times. Security attacks are gradually shifting base
to the application layer in the software ecosystem as shown by a study which reported
more than 60% of attacks on the internet are against web applications.
Software
security flaws can be introduced at any stage of software development life
cycle. Possible stages/ways of introduction of security flaws are as follows:
- Introduction of security flaws by design errors
- Introduction of security flaws by undefined security requirements
- Introduction of security flaws by bad coding practices
- Introduction of security flaws by incorrect deployment
- Introduction of security flaws in maintenance/fixes
- Introduction of security flaws in software updates
So What Do We Do?
Software security maturity models recommend various practices, processes, training to achieve a secure software development and delivery ecosystem. However eventually most essential base for developing secure software is to bring secure coding practices on the work floor and making it integral part of the entire echo system. Each and every developer should and must learn secure coding practices and make it a part of implementation while coding.
Explicitly State Security Requirements
Security requirements should be ‘a must have’ in requirements document. Just like any other requirement they need to be elaborated thoroughly before implementation. Focusing only on functional requirement has been the primary factor for slippage of vulnerabilities and hence the development of insecure software. Developers and related product teams should be aware that there are tools and proxies available to intercept, analyze and modify the application traffic/request /response. If vulnerabilities creep in these layers they are likely to be exploited and have consequences.
Essential Security Checklist for Coders
Every coder should have essential security checklist in his mind when coding. High level headers in this checklist should include the following:
- Data Protection
- Input Validation
- Output Encoding
- Access control
- Session Management
- Authentication and Password Management
- Database Security
- Memory Management
- File Management
- Cryptographic Techniques
- System Configuration
- Error Handling and Logging
Data Protection
Implement the system of least privilege and encrypt all sensitive information that is stored. Do not store passwords, connection strings, or other sensitive information in clear text. Protect backend code from download or comments revealing useful information. HTTP GET request parameters should not include sensitive information and disable/filter/encrypt client side caching. Application should also support removal of sensitive data when not required.
Input Validation
Canonicalize input data i.e. all inputs should be encoded in common character set, such as UTF-8 before being validated. Input validation should be uniform and central to the entire application using a uniform set of rules for validation of input data. Validate expected data type, range, length, and ensure that header values in request and response contain only ASCII chars. If commonly known potential hazardous characters, such as < > " ' % ( ) & + \ \' \" are to be allowed in application input then make sure to have additional sanitization measures such as output encoding. Also make sure you check for the following if it is not a part of the standard input validation routine:
Check for null bytes ()
Check for new line characters (%0d, %0a, \r, \n)
Check for “dot-dot-slash" (../ or ..\) path alterations characters.
Output Encoding
All characters must be encoded unless the intended interpreter is known to be safe. Encoding must be done on a trusted system which is typically the server. Contextually sanitize all output of untrusted data to queries for LDAP, SQL and XML. An example of HTML entity encoding is as follows:
Convert > to >
Convert < to <
Convert “ to "
Convert ‘ to '
Convert / to F;
Access Control
Enforce authorization control on every request that comes from both: server side scripts and client side scripts. Restrict the following only to authorized users:
- Access to protected URLs and functions
- Direct object references
- Access to services and application data
- Policy information used for access controls
Limit number of transactions a single user/device can perform and revalidate long authentication sessions. Ensure the application supports disabling of account and forced logouts.
Session Management
Every application requires a set of controls that help ensure web applications handle HTTP sessions in a secure manner. Set of common practices that help in secure session management are as follows:
- Session inactivity timeout should be as short as possible
- Always use frameworks session management controls on a trusted server
- All pages protected by authorization should have logout
- Logout should kill associated session or connection
- Session information should not be revealed in URL
- Re-authentication should always generate new session identifier
- Disallow concurrent logins with same user ID
- Cookies transported over TLS need to be set as ‘secure’
- Replace the per session paradigm to per request for highly sensitive transactions
- Always set cookies with HttpOnly attribute, until unavoidable
These essentials when kept in mind while coding and designing build a strong foundation for a secure application development and delivery. Will try putting up more points to the checklist in following posts.