Fortify Source Code Analysis Suite Overview Section Objectives
Fortify Source Code Analysis Suite Overview: Section Objectives In this section, you will learn: • Major components of SCA • How SCA processes various source code into one representative model • How SCA Analyzers and Rules work together to find possible vulnerabilities in source code • How to use SCA results
Fortify Source Code Analysis Suite Overview Fortify SCA and its Components Fortify SCA Translation Fortify SCA Analysis Fortify SCA Audit 2
Fortify 360 • Threat Intelligence – Knowledge of Secure Software • Vulnerability Identification – Source Code Analyzer (SCA) – Program Trace Analyzer (PTA) – Real-Time Analyzer (RTA) • Remediation • Governance 3
Fortify SCA Suite Fortify SCA Audit Work. Bench (AWB) Secure Coding Plug-ins Fortify 360 Server • Static source code analysis. • Visual interface for analysis of software vulnerabilities. • Integrated vulnerability detection into Integrated Development Environments (IDEs). • Management for multiple audit projects from a single centralized console. 4
Fortify SCA Process Flow Translation Analysis Audit Source Code to Fortify Intermediate Model to List of Possible Vulnerabilities Vulnerability Verification, Triage and Remediation 5
Fortify Source Code Analysis Suite Overview Fortify SCA and its Components Fortify SCA Translation Fortify SCA Analysis Fortify SCA Audit 6
Fortify SCA – Translation Source Code to Fortify Intermediate Model Analysis Audit Fortify Intermediate Model to List of Possible Vulnerabilities Vulnerability Verification, Triage and Remediation 7
Fortify SCA – Translation (cont’d) Translate Source Code to Fortify Intermediate Model Scan Build Integration - Touch Fortify - Touchless Intermediate Model GUI (IDE & to AWB) FPR File Diagnose Vulnerability Triage and Remediation Translation Phase 8
Translation Phase = Compilation • Source code need to be in a compile-able state – C / C++: needs C/C++ compiler to run SCA translator – Java: Java code is translated directly by SCA translator • Partial results can be obtained if the project is not build-able –. NET: Solutions must be build-able and compiled in Debug configuration to create a program database (pdb) file • SCA translator expects. NET assemblies and the pdb files. – Other languages such as Java. Script, SQL, PHP are translated directly by SCA translator 9
Normalized Syntax Tree (NST Files) • All language translated into a single format – NST Files • Uniform representation of a full application – X-Tier™ Analysis • Static analysis across different tiers of an application 10
Fortify Source Code Analysis Suite Overview Fortify SCA and its Components Fortify SCA Translation Fortify SCA Analysis Fortify SCA Audit 11
Fortify SCA – Analysis Translation Source Code to Fortify Intermediate Model Analysis Fortify Intermediate Model to List of Possible Vulnerabilities Audit Vulnerability Verification, Triage and Remediation 12
Fortify SCA – Analysis (cont’d) Analysis Phase 13
Analysis Phase = Analyzers + Rules • Analyzers – Comprised of six distinct analyzers • Analyzers are static analysis algorithms – Each analyzer is associate with a rule type • Rules – Vulnerability definition (pattern) – There as many number of rule types as the number of analyzers • Each rule type works with one analyzer • Each rule type has its own syntax – Secure Coding Rulepacks • A set of files that contains rules 14
Fortify SCA Analyzer • Fortify SCA provides six primary analyzers – Data flow – Control flow – Structural – Semantic – Configuration – buffer 15
Understanding Data Flow – Sample import java. sql. *; public class SQLInjection { public static void main (String args[]) { Connection conn = null; try { String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); } catch (SQLException err) { err. print. Stack. Trace (); } } } 16
Data Flow • Find vulnerabilities where non-trusted input can potentially control application operation. – Vulnerabilities to injection attacks • Analyzer uses global taint propagation to trace the flow of nontrusted data – Source • Non-trusted (user controlled) input – Sink • Potentially dangerous function call or operation 17
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { Connection conn = null; try { String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); } catch (SQLException err) { err. print. Stack. Trace (); } } } 18
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { args[] is tainted Connection conn = null; try { String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); } catch (SQLException err) { err. print. Stack. Trace (); } } } 19
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { args[] is tainted Connection conn = null; try { Taint propagated to user. Name String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); } catch (SQLException err) { err. print. Stack. Trace (); } } } 20
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { args[] is tainted Connection conn = null; try { Taint propagated to user. Name String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); Tainted input } user. Name used catch (SQLException err) { in assignment err. print. Stack. Trace (); } } } 21
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { args[] is tainted Connection conn = null; try { Taint propagated to user. Name String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); Sink while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); Tainted input } user. Name used catch (SQLException err) { in assignment err. print. Stack. Trace (); } } } 22
Data Flow (cont’d) import java. sql. *; Source public class SQLInjection { public static void main (String args[]) { args[] is tainted Connection conn = null; try { Taint propagated to user. Name String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); Sink while ( rs. next() ) {. . . } rs. close (); stmnt. close (); conn. close (); Tainted input } user. Name used catch (SQLException err) { in assignment err. print. Stack. Trace (); } Vulnerability } Reported } 23
Understanding Control Flow – Sample private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } 24
Control Flow • Detects potentially dangerous sequences of operations/function calls – Control Flow analyzer simulates state machines using your source code (NST files) to determine the state transitions • Each state machines has an error state which represents the state where a vulnerability could be exploited – Control Flow rules are definition of the state machines 25
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } Variable initialized & assigned } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } 26
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); Connection } closed else { lbl. Msg. Text = "Login attempt failed. "; } Variable initialized & assigned } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } 27
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); Connection } closed else { lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Safe Sequence 28
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } Variable initialized & assigned } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } 29
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) Variable { initialized & Forms. Authentication. Redirect. From. Login. Page(txt. User, false); assigned cnx. Close(); } else Control Flow Observe all { possible paths lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } 30
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else Observes all { possible paths lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Analyze until cnx is out of scope 31
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); Vulnerability Reported if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else Observes all { possible paths lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Analyze until cnx is out of scope 32
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Observes all possible paths 33
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Observes all possible paths Analyze until cnx is out of scope 34
Control Flow (cont’d) private void cmd. Login_Click(object sender, System. Event. Args e) { Label lbl. Msg = null; try { string txt. User = Request. Form["txt. Username"]; string txt. Password = Request. Form["txt. Password"]; string str. Cnx = "server=localhost; database=northwind; uid=sa; pwd=; "; Sql. Connection cnx = new Sql. Connection(str. Cnx); cnx. Open(); string str. Qry = "SELECT Count(*) FROM Users WHERE User. Name='" + txt. User + "' AND Password='" + txt. Password + "'"; int. Recs; Sql. Command cmd = new Sql. Command(str. Qry, cnx); int. Recs = (int)cmd. Execute. Scalar(); Vulnerability Reported if (int. Recs > 0) { Forms. Authentication. Redirect. From. Login. Page(txt. User, false); cnx. Close(); } else { lbl. Msg. Text = "Login attempt failed. "; } } catch (Exception err) { Response. Write(err. Stack. Trace. To. String()); } Variable initialized & assigned Observes all possible paths Analyze until cnx is out of scope 35
Structural • Detects potentially dangerous flaws in the structure or definition of a program – Wide varieties of flaws related to source Structure: • Insecure declaration and use of variables • Overly broad catch blocks • Comments that contain sensitive information, such as password 36
Structural (cont’d) • Erroneous String comparison public static void add. Resource. Request( Wiki. Context ctx, String type, String resource ) {. . . if( type == RESOURCE_SCRIPT ) { resource. String = "<script type='text/javascript' src='"+resource+"'></script>"; } else if( type == RESOURCE_STYLESHEET ) { resource. String = "<link rel='stylesheet' type='text/css' href='" +resource+"' />"; } else if( type == RESOURCE_INLINECSS ) { resource. String = "<style type='text/css'>n"+resource+"n</style>n"; } else if( type == RESOURCE_JSFUNCTION ) { Using the == operator does not resource. String = resource; compare the values of the objects } but the objects themselves. . Always use the equals () method to compare the values of two strings. 37
Structural (cont’d) • Empty catch block try { page = m_engine. get. URLConstructor(). parse. Page( request. Context, request, m_engine. get. Content. Encoding() ); if ( page != null ) { try { String final. Page = get. Final. Page. Name( page ); if ( final. Page != null ) { page = final. Page; } Notice how the comment in the } empty catch block. catch( Provider. Exception e ) However the code has made it { into production now ! // FIXME: Should not ignore! } return page; } } catch( IOException e ) { log. error( "Unable to create context", e ); throw new Internal. Wiki. Exception( "Big internal booboo, please check logs. " ); }. . . 38
Structural (cont’d) • Password in Comment //DB password is admin //Set the connection string for the database Password written in a comment block string connectionstring = "Initial Catalog=Test. Catalog; Data Source=my. Data. Source; user id=admin; password=admin; "; string tainted_query = "Select name=" + args[1]. Clone() + " from Employees"; 39
Structural (cont’d) • Member variables are not thread safe – Unless a Servlet implements the Single. Thread. Model, it is a singleton import javax. servlet. http. *; import java. io. *; public class Credit. Card. Servlet extends Http. Servlet { private String credit. Card. Num; public void do. Post (Http. Servlet. Request request, Http. Servlet. Response response) throws IOException { credit. Card. Num = request. get. Parameter("CC_NUM"); if (credit. Card. Num != null) { The value of credit. Card. Num will keep Print. Writer out = response. get. Writer(); out. println (credit. Card. Num); } changing as the application serves } web requests. These requests are } potentially from different users, so it } may expose one user’s data to another 40
Semantic • Looks for unsafe function calls based on their signature – Signature consists of • Package / namespace • Return types of the method • Types passed to the method • Has similarity to a search function – More limited: Semantic look only at function calls – More powerful: Knows about object oriented concepts • Ability to specify object type that is expected in the function signature 41
Semantic (cont’d) import java. sql. *; public class SQLInjection { public static void main (String args[]) { Connection conn = null; try { String user. Name = args [0]; String passwd = args [1]; String query = "select uname, passwd from users where uname like "+user. Name+"%"; conn = Driver. Manager. get. Connection ("jdbc: odbc: logistics", "admin", "letmein"); Statement stmnt = conn. create. Statement (); Result. Set rs = stmnt. execute. Query (query); while ( rs. next() ) {. . . } rs. close (); stmnt. close (); Hardcoded conn. close (); Password } catch (SQLException err) { err. print. Stack. Trace (); } } } 42
Semantic (cont’d) char *cmd = new char[256]; const char *safe = "safe_command "; int return. Code; while (1) { Dangerous cout << "Enter command: "; Function/Operator cin >> cmd; if (strncmp(cmd, safe, strlen(safe)) != 0) { cout << "Unsafe command enteredn"; break; } return. Code = system(cmd); cout << "Command returned " << return. Code << 'n'; } 43
Configuration • Uses XPath queries and name-value matching to identify issues in application’s configuration files – web. xml - J 2 EE applications – web. config -. NET web applications – other. xml - any well-formed XML files – Properties files - name/value pairs • Primarily searches application configuration files for – Mistakes – Omissions – Weaknesses 44
Configuration (cont’d) • Incomplete Error Handling … </welcome-file-list> <error-page> <error-code>403</error-code> <location>/error/Forbidden. html</location> Missing java. lang. Throwable, error code 404, and 500 </error-page> <resource-ref> … 45
Configuration (cont’d) • Misconfiguration: Directory Listing <servlet>. . . <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> … Listings is set to true. Allow users to view files in the file system. 46
buffer • buffer analyzer detect access to buffer beyond its boundaries – Converts code to integer programs – Uses constraint solver to detect possible access beyond the buffer boundaries. • Trace the buffer size used in allocation and buf operations – Memory allocation: malloc(), static string, etc – Buffer operation: strcpy(), strncat(), etc 47
buffer (cont’d) • Buffer Overflow void foo() { char* str = "hello world"; char* buf = (char*)malloc(strlen(str)+5); Buffer size = 16 strcpy(buf, str); Written 12 bytes strcat(buf, "overflow"); Written 8 bytes return 0; } 48
Secure Coding Rules - Fortify • Fortify Rules cover commonly use API – Library that comes with the programming language – Common 3 rd party and extension library for the language • Developed by Fortify Security Research Group (SRG) – New rule update every quarter • End of February, May, August, and November – Distributed as encrypted files • Fortify’s intellectual property 49
Secure Coding Rules - Custom • Why develop custom rules? – Create precise validation rules to improve results accuracy – Enforce your organization security or coding practices – Need to cover your proprietary libraries • Fortify doesn’t know about your library – Need to cover libraries that Fortify Rules have not covered • Contact Fortify and request for rule coverage on the libraries • Custom rule development class is available from Fortify – Different classes for different programming languages 50
Summarizing Analysis Phase • Data flow – Trace taint from source to sink – Rules define sources and sinks • Control flow – Simulate state machine – Rules define the state machines • Structural – Match a structural pattern in source file – Rules define structures’ patterns 51
Summarizing Analysis Phase (cont’d) • Semantic – Flag function call with a specific signature – Rules define function signatures • Configuration – Lookup for attributes and their values in configuration and property files – Rules define XPath or name-value pair • buffer – Calculate buffer size and detect access beyond the bound of buffer – Rules define behavior of functions which manipulate buffers 52
Fortify Source Code Analysis Suite Overview Fortify SCA and its Components Fortify SCA Translation Fortify SCA Analysis Fortify SCA Audit 53
Fortify SCA – Audit Translation Analysis Source Code to Fortify Intermediate Model to List of Possible Vulnerabilities Audit Vulnerability Verification, Triage, and Remediation 54
Fortify SCA – Audit (cont’d) Audit Phase 55
Audit Phase = Fortify Utilities + You • Fortify Utilities – Audit Workbench (AWB) • A Fortify Graphical User Interface (GUI) utility • Rich features to review results from Fortify SCA analysis – Secure Coding Plug-ins • Very similar functionalities to AWB – 360 Server Collaboration Module • Very similar functionalities to AWB • You – Verify and remediate issues found by Fortify SCA 56
- Slides: 57