IAC 2024 - IA Fast Track to Search Focused AI Solutions
How to conduct a security code review
1. About Security Innovation
• Application and Data Security Experts Seattle
– 10+ years of research on security vulnerabilities
– Hundreds of assessments on world‟s most dominant
How to Conduct a software, applications and development environments
– Solutions for all phases of SDLC:
Security Code Review secure design, development, testing and deployment
Boston
• Products, Services & Training
– Training/eLearning on secure coding, security testing, etc.
– Application Security Assessment (black and white box)
– Encryption for secure data transfer and communications
Jason Taylor
CTO
Security Innovation
What is a Security Code Review? Why Security Code Review?
• Security Engineering Activity • It can find vulnerabilities that are very difficult to discover in testing
– Automated and manual inspection of code • It can be performed by your developers or your technical testers
– Can start as soon as you begin development
• It can be done early in the development process
– Can continue through testing and release
• It can be performed on every check-in, every build, or some other
interval that works for your development process
• Focused
– Focused on security vulnerabilities
• Security code review is one of the most impactful steps you can
– Uses a „question list‟ to drive the inspection take toward more secure code
– Only review for issues that are relevant to your application
Conducting the Code Review Goals of the Code Review
Methodology
1. Identify Code Review Iterative Process • Create/Update a list of inspection questions
Objectives
– What problems are possible in the technology
Inputs • e.g. should you be looking for buffer overflows?
• Design documentation
• Architecture diagram – What problems are possible due to the design?
• Data flows • are there threat mitigations already in place?
2. Perform • Usage scenarios
Preliminary
Scan
• Inspection questions • Identify vulnerabilities
Outputs – Where in the code
• Inspection questions – Under what conditions
4. Review for 3. Review for • Prioritized list of problems to fix in
Unique Issues Common Issues the code
• Document a fix
– How can the vulnerability be resolved
1
2. Tips for an Effective Review Tips for an Effective Review
• Set time limits • Set clear objectives
– It is easy to get stuck in a code review – Understand what issues you are looking for
– Too much time in any one area may diminish returns – Understand patterns of bad code
– Time-box your effort so you can move on • Review only for security
– Don‟t spread yourself thin, stay focused
• Break into manageable chunks – Security focus is proven to be more effective
– Would you be more effective reviewing 1MLOC or 1KLOC?
• Update your coding standards
– Stay focused, finish quickly, find high quality bugs
– Identify problems that occur repeatedly
• Review iteratively – Add coding standards to address these problems
– Continuous review is more effective than big-bang • Identify what‟s out of scope
– Review as often as possible and make it routine – Clarify what you will not be looking for, don‟t waste time
Conducting the Code Review 1. Identify Code Review Objectives
Overview
Code Review Steps: • Code review objectives are a set of bug types you‟ll be looking
for based upon the code‟s architecture and the identified threats.
1. Identify code review objectives – For instance, it is not important to look for SQL injection bugs if your
application has no interactions with a database.
2. Perform preliminary scan
• To determine the objectives, consider the following:
3. Review for common security issues
– Which threats identified in threat model apply to the code you‟re reviewing?
4. Review for security issues unique to – Which common coding errors apply to the code you are reviewing?
your application‟s design – What is the scope of your review?
• Examples of Code Review Objectives
– Ensure all un-trusted input to the component is passed to a validation
routine before being used.
– Check error handling to ensure exceptions are caught consistently and
close to source.
– Check cryptographic routines to ensure secrets are cleared quickly.
2. Perform Preliminary Scan Static Analysis Tools
Strengths and Weaknesses
• Use a static analysis tool to grab low hanging fruit • Strengths
– Find first set of potential vulnerabilities – Can find many common and KNOWN vulnerabilities fast
– Determine hotspots where more bugs may be hiding – Good at finding bugs that are caused by single lines of code and may
find bugs that span multiple lines of code in a single function
• Perform a preliminary manual scan to uncover hotspots
– Good at finding buffer overruns, format string problems, use of
– Input and data validation architecture dangerous win32 APIs, memory leaks, etc.
– Find code used for authentication and authorization – May find bugs that you miss in the manual scan
– Discover code that appears especially complex
– Discover code that uses cryptography • Weaknesses
– False-positives can lead you on a wild goose chase
– Find code that performs interop between managed and native code
– Can you give a false sense of security
• Goals – Limited in their ability to find bugs that span
– First set of bugs multiple functions or components
– Hotspots to review more closely
2
3. 3. Review for Common Issues Focus on Hotspots
Hotspots in your code
• Use code review objectives developed in step one • Hotspots are areas that were highlighted in your preliminary scan
– Checklist or question driven approach works best – Areas of code with many „hits‟ from static analysis
• Focus on hotspots – Code that mitigates a known threat
– Hotspots discovered in the preliminary scan – Complex code (cyclomatic complexity measures can help)
– Common security hotspots such as XSS and SQLi – Etc.
• Perform control flow analysis
– Review logical conditions • Use this list to focus your effort
• Perform data flow analysis
– Trace data from input to output
– Analyze trust boundaries
Focus on Hotspots Focus on Hotspots
Common Hotspots Common Hotspots
• SQL Injection • Authorization
– Look for un-trusted input that can modify the semantics of a SQL query – Look for permissive database access, privilege escalation, lack of separation
• Sensitive Data
• Cross-Site Scripting – Look for disclosure of information over the network,
in files, code, error messages, memory
– Look for user input echoed back as web content
• Unsafe Code
• Data Access – Look for code that runs at higher privileges, without interpreter protections
– Look for plain-text data base connection strings and authentication to the • Hard-coded Secrets
database – Look for hard-coded keys, passwords, hashes and salts
• Input and Data Validation • Poor Error Handling
– Look for poor exception handling, missing error code paths
– Look for client-side input validation, black-list techniques
• Authentication
– Look for weak passwords, credentials sent in clear-text, long or semi-
random sessions
Focus on Hotspots Conducting the Code Review
Common Hotspots Control Flow Analysis & Data Flow Analysis
• Configuration Files Manually inspect your code by tracing paths through the code that is
– Look for sensitive data, connection strings, poorly configured security most likely to contain vulnerabilities
features
• Dataflow analysis
• Cryptography – Trace data from the points of input to the
– Look for failure to clear secrets, custom cryptography or improper use of points of output
platform APIs
– Determine trust level for input
• Undocumented Public Interfaces – Look for input validation
– Look for test interfaces or other undocumented interfaces that haven‟t
received good documentation or test scrutiny • Control flow analysis
• Threading Problems – Step through logical conditions in the code
– Look for race conditions and deadlocks – Understand the conditions under which each block will execute
• Memory Problems
– Look for memory leaks and buffer overflows Optimized by the use of Hotspots and Code Review Objectives!
3
4. Data Flow Analysis Data Flow Analysis
Trust Boundaries
• Look for input sources • Trust boundary represents a layer between components or
– Public interfaces data sources that represent a transition from lower trust to
higher trust
– User interface
– Database • Use trust boundaries to determine how much you trust an
input source
– Sockets
– Files
– Pipes
• Look for input sinks • The less you trust the source, the more carefully you need to
validate
– Where does the data exit your application as output?
– Where does the data come to rest?
Data Flow Analysis Data Flow Analysis
Trust Boundaries Most Common Input Validation Bugs
• High Trust • Numeric underflows and overflows
– Known to be good, strongly named assemblies or signed/hashed native libraries
– A DB that is only used by your component and for which you can prove that all data has been • SQL injection
properly validated
– Network data that has been signed by a known good source (IPSec or SSL)
• Cross Site Scripting
• Canonicalization
• Medium Trust
– Libraries that have not been signed but are local to your server • Native code issues
– Public interface that should only be accessible to trusted users
– UI that should only be accessible to trusted users • Buffer overflows
– Network data that should only be accessible to trusted users
• Format strings
• Low Trust
– Libraries that have not signed and are located on the client
– Client code, a file, a public interface or UI that is accessible to any user
– Data from a network that is shared with other components or processes
– Data from a database that is shared with other components or processes
Data Flow Analysis Data Flow Analysis
Numeric Underflows and Overflows SQL injection
Look for: a calculation causes a data value to be larger or smaller than its data type Look for: User input can impact logic of a SQL query
allows Impact: Malicious user can access or modify data in your SQL database
Impact: The value wraps to become much larger larger or smaller than its data type allows - cag te
Caused when a calculation causes a data value to be
or smaller than expected
Example:
value to wrap-around and generally become much larger or smaller than expected
Example:
int[ ] filter(uint len, int[ ] numbers)
{ The SQL query in code looks like this.
uint newLen = len * 3/4; query = “SELECT * FROM USERS WHERE USER_ID = „” + userIdFromWebPage + “‟”;
int[] buf = new int[newLen]; Imagine userIdFromWebPage contains “‟ or 1=1 –“, or “‟ ;DROP TABLE users –“, or “‟ ;exec
int j = 0; xp_cmdshell(„format c:‟) –“.
for (int i = 0; i < len; i++)
{ The final query could look like this, which will result in a format of the c: drive on DB server
if (i % 4 != 0) “select * FROM USERS WHERE USER_ID = „‟ ;exec xp_cmdshell(„format c:‟) –”
buf[j++] = numbers[i];
}
return buf;
}
When calculating the value for len, the code first computes len * 3 and then divides by 4.
When len is large enough (~1.4 billion), len * 3 overflows and newLen gets assigned too
small of a value. The result in this code will be an unhandled IndexOutOfRange exception.
4
5. Data Flow Analysis Data Flow Analysis
Canonicalization Format String
Look for: There are multiple ways to represent a resource. Validation is performed on one
representation and processing is performed on another. Look for: Use of the printf family of functions on user input.
Impact: You may get a resource (e.g. URL or File) other than you expected Impact: The printf family of functions will pop the stack as many times as they see “%” in
the format string. Sufficient %‟s can traverse the stack, and reach any location in it. Use
of %n can allow arbitrary writing of data anywhere within the stack.
Example:
Examples:
void main (int argc,
– Use of partial paths may result in a file other than what you expect being loaded. char **argv)
– Alternate representation of an IP address such as dotless IP may result in a URL other {
than what you expected being loaded.
/* Whatever the user said, spit back! */
– Encoded characters such as %20 for space may result in a URL other than what you printf (argv[1]);
expected being loaded.
}
Control Flow Analysis Control Flow Analysis
Does the application rely on client side validation?
Look for: Application relies upon client-side validation alone
• Use Hotspots and Code Review Objectives: Impact: It is easy to modify or bypass client code, malicious input will reach the
– Does the application rely on client side validation? server
– Are there secrets or critical IP embedded in the code? Example:
<html><head>
– Is sensitive data being stored in predictable locations (such as temp files), or being
<script language=„javascript‟>
sent in clear text over the network?
function validateAndSubmit(form)
– Is cryptography being used? {
– Are there undocumented public interfaces? if(form.elments[“path”].value.length() > 0)
{
– Is the component giving dependencies too much trust?
form.submit();
– Is there proper and consistent error checking? }
– Do error messages give away too much information? }
</script>
– Does your application expose sensitive information via user session?
<form action=“mypage.asp” method=“post”>
– Can write operations be performed with a GET request? <input type=„text‟ id=„path‟/>
– Is the code multithreaded? <input type=„button‟ onclick=„validateAndSubmit(this.parent)‟>Submit</input>
</form>
…
Control Flow Analysis Control Flow Analysis
are there secrets or critical IP embedded in the code? is sensitive data stored in predictable locations or sent in clear text?
Look for: Secrets are hardcoded in the application Look for: Store sensitive information in configuration files or sent over the network
Impact: Code can be decompiled, sensitive IP or hard coded secrets can be unencrypted
stolen Impact: Attacker can steal sensitive information.
Example:
IntPtr tokenHandle = new IntPtr(0); Example:
IntPtr dupeTokenHandle = new IntPtr(0);
Server password stored in the ASP.NET web.config file:
string userName = "joe", domainName = "acmecorp", password="p@Ssw0rd"; <connectionStrings>
const int LOGON32_PROVIDER_DEFAULT = 0; <add name="Sales” providerName="System.Data.SqlClient"
connectionString= "server=myserver;database=Products;uid=dbUser;pwd=dbPwd" />
//This parameter causes LogonUser to create a primary token. </connectionStrings>
const int LOGON32_LOGON_INTERACTIVE = 2;
const int SecurityImpersonation = 2;
tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
5
6. 4. Review for Issues Unique to Your Application‟s
Subject Object Matrix
Design
• Is there a security architecture implemented in this application? • Are there unique roles in the application?
Great location to look for bugs for several reasons: – Look for problems in the code that could allow one role to assume the
– It has already been recognized that a security problem exists, that‟s why privileges of another.
the custom security code was written in the first place. – Understand what the set of roles and what each role should be allowed to do.
– Unlike other areas of the product, a functional bug is very likely to result
in a security vulnerability.
Once the matrix has been completed, review the code for contradictions to this matrix.
Even a well designed system with clearly defined roles can be broken by a bad
assumption or a logical mistake in the implementation.
Post Code Review Activities How Security Innovation can Help
• Prioritize the bugs found • Source Code Analysis Solutions
– prioritization should be based upon the impact the – Static analysis tooling
bug will have on your customers – Code review as a service
– Think through the maximum damage potential as
well as which of your customers will be impacted • TeamMentor Security Knowledge Base
• Fix the right set of bugs – Common vulnerabilities
– Each bug fixed can introduce a new unknown bug – Checklists
– Guidelines for writing secure code
– Sometimes the bug you know is less dangerous than the bug you don‟t
• Learn from your mistakes • TeamProfessor Security eLearning
– Keep a running dialog within your team discussing the mistakes made, – Courses cover secure process, design, development and testing
how they were found, how they were fixed.
– Strive to write code that comes up clean in a code review the first time!
eKnowledge Solutions for Secure Development &
Source Code Analysis Solutions
Code Review
CxDeveloper: Next Generation Static Analysis TeamMentor:
Secure Development Guidance System
– Accurate: Full analysis of all application paths and
variables with a near zero false positive rate – Out of the box secure development standards and
best practices (maps to several compliance reqt‟s)
– Scalable. 32 & 64 bit architecture for high demand
environments – How-to‟s, how not-to‟s, code snippets, attacks,
checklists
– Extensible. Built in CxQL query language, IDE
integrations, low process impact – Targeted, on-demand, context specific application
security training
– Affordable. Flexible licensing and great
price/performance ratio – Lots of content on conducting a code review
Code Review as a Service Software Security eLearning:
– Creating Secure Code
– Independent, expert eyes
– How to Break Software Security
– Can perform deep review or quick, baseline review
– Optional remediation assistance – Fundamentals of Application Security
– Introduction to Threat Modeling
– Buffer/Integer Overflows
6
7. Appendix
Try eLearning for free
http://elearning.securityinnovation.com
Free eLearning Course for Attending
“Introduction to Threat Modeling”
Contact Me
Jason Taylor
jtaylor@securityinnovation.com
Inputs - Minimum Inputs – Nice to Have
• Architecture diagram • Usage Scenarios
– Useful especially if you don‟t already know the architecture – How is the code used, what are the scenarios?
– Can be replaced by an architecture conversation, whiteboard, etc. • Use of native code
• Data flows – If you are reviewing managed code (Java/.NET) where does it call
into native code?
– Where are the inputs?
• Reference material
– How does the data flow between components?
– Data schemas
– Where is the data output?
– API documentation
– Where does it come to rest?
– User documentation
– Threat model
7