PA193 - Secure coding principles and practices Static analysis of source code Petr Švenda svenda@fi.muni.cz Overview • Lecture: problems (demo), prevention – example of problems – types of static analysis – common types of errors, problem of false positives – design for testability – static analysis tools • Labs – run and fix results from static checker – write own additional rule to checker 2 | PA193 - Static and dynamic checkers PA193 - exams • 11.12. 18:00 A319 • 16.12. 18:00 B411 • 19.12. 10:00 A319 3 | PA193 - Static and dynamic checkers PROBLEM 4 | PA193 - Static and dynamic checkers Cost of insecure software • Increased risk and failures due to generally increased usage of computers • Fixing bug in released version is more expensive – testing, announcements, • Liability laws – need to notify, settlement... • Reputation loss • Cost of defense is decreasing – better training (like this course ☺), automated tools, development methods 5 | PA193 - Static and dynamic checkers What is wrong with this code? 6 | PA193 - Static and dynamic checkers year = ORIGINYEAR; /* = 1980 */ while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } Microsoft’s Zune bug • December 31st 2008 • Simultaneous fail of thousands music players • http://techcrunch.com/2008/12/31/zune-bug- explained-in-detail/ • Highly embarrassing (blogs) • Contributed to discontinuation 7 | PA193 - Static and dynamic checkers year = ORIGINYEAR; /* = 1980 */ while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } What is wrong with this code? 8 | PA193 - Static and dynamic checkers network_receive(in_packet, &in_packet_len); // TLV packet in = in_packet + 3; out_packet = malloc(1 + 2 + length); out = out_packet + 3; memcpy(out, in, length); network_transmit(out_packet); network_receive(in_packet, &in_packet_len); // TLV packet in = in_packet + 3; out_packet = malloc(1 + 2 + length); out = out_packet + 3; memcpy(out, in, length); network_transmit(out_packet); OpenSSL Heartbeat – “packet repeater” | PA193 - Static and dynamic checkers Payload [length B]length [2B]Type [1B] unsigned char* in Payload (length B)length [2B]Type [1B] unsigned char* out Payload [length B] 9 network_receive(in_packet, &in_packet_len); // TLV packet in = in_packet + 3; out_packet = malloc(1 + 2 + length); out = out_packet + 3; memcpy(out, in, length); network_transmit(out_packet); Problem? | PA193 - Static and dynamic checkers Payload [1B]Type [1B] unsigned char* in Payload (65535B)0xFFFF [2B]Type [1B] unsigned char* out … Heap memory … Payload [1B] Heap memory (keys, passwords…) 0x0001 [2B]0xFFFF [2B] Problem! in_packet_len != length + 3 10 How serious the bug was? • \ • http://news.netcraft.com/archives/2014/04/08/half-a-million-widely- trusted-websites-vulnerable-to-heartbleed-bug.html | PA193 - Static and dynamic checkers 17% SSL web servers (OpenSSL 1.0.1) Twitter, GitHub, Yahoo, Tumblr, Steam, DropBox, DuckDuckGo… https://seznam.cz, https://fi.muni.cz … 11 Defensive programming • Term coined by Kernighan and Plauger, 1981 – “writing the program so it can cope with small disasters” – talked about in introductory programming courses • Practice of coding with the mind-set that errors are inevitable and something will always go wrong – prepare program for unexpected behavior – prepare program for easier bug diagnostics • Defensive programming targets mainly unintentional errors (not intentional attacks) • Increasingly given security connotation 12 | PA193 - Static and dynamic checkers “Security features != Secure features” • “Security features != Secure features” – Howard and LeBlanc, 2002 • “Writing security features, although important, is only 10% of the workload of creating secure code. The other 90% of the coding work is meant to ensure that all non-security codebase is secure.” – Sullivan, Balinsky, 2012 • “Reliable software does what it is supposed to do. Secure software does what it is supposed to do, and nothing else.” – Ivan Arce 13 | PA193 - Static and dynamic checkers STATIC AND DYNAMIC ANALYSIS 14 | PA193 - Static and dynamic checkers How to find bugs in code? • Manual dynamic testing – running program, observe expected output • Manual analysis of code – code review • Automated analysis of code without compilation – static analysis (pattern matching, symbolic execution) • Automated analysis of code with execution – dynamic analysis (running code) • Automated testing of inputs (fuzzing) 15 | PA193 - Static and dynamic checkers Approaches for automated code review • Formal methods (mathematical verification) – requires mathematical model and assertions – often requires modeling the system as finite state machine • verification of every state and transition • Code metrics – help to identify potential hotspots (complex code) – e.g., Cyclomatic complexity (number of linearly indep. paths) • Review and inspection – tries to find suspicious patterns – automated version of human code review 16 | PA193 - Static and dynamic checkers Microsoft’s Secure Development Lifecycle 17 | PA193 - Static and dynamic checkers Taken from http://www.microsoft.com/security/sdl/process/implementation.aspx Cigital Touchpoints methodology 18 | PA193 - Static and dynamic checkers Static vs. dynamic analysis • Static analysis – examine program’s code without executing it – can examine both source code and compiled code • source code is easier to understand (more metadata) – can be applied on unfinished code – manual code audit is kind of static analysis • Dynamic analysis – code is executed (compiled or interpreted) – input values are supplied, internal memory is examined 19 | PA193 - Static and dynamic checkers Example of output produced by analyzer 20 | PA193 - Static and dynamic checkers Types of static analysis • Type checking – performed by compiler • Style checking – performed by automated tools • Program formal verification – annotations & verification of specified properties • Bug finding / hunting – between style checking and verification – more advanced static analysis – aim to infer real problem, not only pattern match • Security Review – previous possibilities with additional support for review 21 | PA193 - Static and dynamic checkers Static analysis - techniques • Structural rules (unwanted functions / patterns) – deprecated functions (e.g., gets) – fixed size arrays (e.g., char buff[100]) • Trace of interesting data throw program – propagation of tainted data (user input → exec(data)) – match of possible lengths for input / output data 22 | PA193 - Static and dynamic checkers Type checking • Type checking – performed by compiler – errors against language rules prevents compilation – warnings usually issued when problematic type manipulation occur – false positives (short = int = short;) • Security problems due to wrong types – string format vulnerabilities – type overflow → buffer overflow – data loss (bigger type to smaller type) • More on type checking later with compiler warnings 23 | PA193 - Static and dynamic checkers Style checking • Style checking – performed by automated tools – set of required code rules • Separate tools – MS style checker – Unix: lint tool (http://www.unix.com/man-page/FreeBSD/1/lint) – Checkstyle – PMD (http://pmd.sourceforge.net/) – Google C++ style checker: C++lint • http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml • http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py • Compiler warnings gcc –Wall gcc -Wextra 24 | PA193 - Static and dynamic checkers Program verification • Prove particular program property – e.g., all dynamically allocated memory is always freed • Requires mathematical model and assertions • Often requires modeling the system as finite state machine – verification of every state and transition • (Outside the scope of this presentation) 25 | PA193 - Static and dynamic checkers Bug finding • No language errors != secure program – finding bugs, even when language permits it • Examples: – Buffer overflow possible? – User input formated into system() call? – Hard-code secrets? • Must keep false positives low – do not report as a bug something which isn’t – there is simply too many potential problems • Tools: FindBugs, PREfast, Coverity... 26 | PA193 - Static and dynamic checkers Security analysis and review • Usage of analysis tool to perform security review – usually multiple tools are used during the process • (Will be covered in later lecture(s)) 27 | PA193 - Static and dynamic checkers Static analysis limitations • Overall program architecture is not understand – sensitivity of program path – impact of errors on other parts • Application semantics is not understand – Is string returned to the user? Can string also contain passwords? • Social context is not understand – Who is using the system? High entropy keys encrypted under short guessable password? 28 | PA193 - Static and dynamic checkers Problem of false positives/negatives • False positives – errors reported by a tool that are not errors in fact – too conservative analysis – inaccurate model used for analysis – annoying, more code needs to be checked, less readable output, developers tend to have as an excuse • False negatives – real errors NOT reported by a tool – missed problems, missing rules for detection 29 | PA193 - Static and dynamic checkers False positives – limits of static analysis • When foo() is called, always writes outside buffer 30 | PA193 - Static and dynamic checkers void foo() { char a[10]; a[20] = 0; } d:\StaticAnalysis>cppcheck example.cpp Checking example.cpp... [example.cpp:4]: (error) Array 'a[10]' accessed at index 20, which is out of bounds. False positives – limits of static analysis • For x + y != 2 false positive • But analyzer cannot be sure about x & y values 31 | PA193 - Static and dynamic checkers int x = 0; int y = 3; void foo() { char a[10]; if (x + y == 2) { a[20] = 0; } } d:\StaticAnalysis>cppcheck example.cpp Checking example.cpp... [example.cpp:7]: (error) Array 'a[10]' accessed at index 20, which is out of bounds. problematic assignment put inside condition False positives – limits of static analysis • No problem detected – constants are evaluated and condition completely removed 32 | PA193 - Static and dynamic checkers const int x = 0; const int y = 3; void foo() { char a[10]; if (x + y == 2) { a[20] = 0; } } const added (same for #define) d:\StaticAnalysis>cppcheck --debug example.cpp Checking example.cpp... ##file example.cpp 1: 2: 3: 4: void foo ( ) 5: { 6: char a@3 [ 10 ] ; 7: 8: 9: 10: } d:\StaticAnalysis>cppcheck example.cpp Checking example.cpp... False positives – limits of static analysis • Whole program is not compiled and evaluated 33 | PA193 - Static and dynamic checkers void foo2(int x, int y) { char a[10]; if (x + y == 2) { a[20] = 0; } } int main() { foo2(0, 3); return 0; } d:\StaticAnalysis>cppcheck --debug example.cpp Checking example.cpp... ##file example.cpp 1: void foo2 ( int x@1 , int y@2 ) { 2: char a@3 [ 10 ] ; 3: if ( x@1 + y@2 == 2 ) { 4: a@3 [ 20 ] = 0 ; 5: } 6: } 7: int main ( ) { 8: foo2 ( 0 , 3 ) ; 9: return 0 ; 10:} [example.cpp:4]: (error) Array 'a[10]' accessed at index 20, which is out of bounds. Always design for testability • “Code that isn't tested doesn't work - this seems to be the safe assumption.” Kent Beck • Code written in a way that is easier to test – proper decomposition, unit tests, mock objects – source code annotations (with subsequent analysis) • References – https://en.wikipedia.org/wiki/Design_For_Test – http://www.agiledata.org/essays/tdd.html 34 | PA193 - Static and dynamic checkers BUILD-IN COMPILER ANALYSIS 35 | PA193 - Static and dynamic checkers MSVC flags • warning C4018: '>=' : signed/unsigned mismatch 36 | PA193 - Static and dynamic checkers #include using namespace std; int main(void) { int low_limit = 0; for (unsigned int i = 10; i >= low_limit; i--) { cout << "."; } return 0; } Warnings – how compiler signals troubles • MSVC /W n – /W 0 disables all warnings – /W 1 & /W 2 basic warning – /W 3 recommended production purposes (default) – /W 4 recommended for all compilations, ensure the fewest possible hard-to-find code defects – /Wall == /W4 + extra • GCC -Wall, -Wextra • Treat warnings as errors – GCC –Werror, MSVC /WX – forces you to fix all warnings, but slightly obscure nature of problem 37 | PA193 - Static and dynamic checkers Recommendations for MSVC CL • Compile with higher warnings /W4 • Control and fix especially integer-related warnings – warning C4018: '>=' : signed/unsigned mismatch • comparing signed and unsigned values, signed value must be converted to unsigned – C4244, C4389 – possible loss of data because of truncation or signed&unsigned variables operation • If existing code is inspected, look for – #pragma warning (disable, Cxxxx) where xxxx is above • Use compiler /RTC flag 38 | PA193 - Static and dynamic checkers warning C4018: '>=' : signed/unsigned mismatch • What will be the output of following code? – string "x > y“ – but also compiler warning C4018 39 | PA193 - Static and dynamic checkers #include using namespace std; int main(void) { int x = -100; unsigned int y = 100; if (x > y) { cout << "x > y"; } else { cout << "y >= x"; } return 0; } Recommendations for GCC • GCC –Wconversion – warn about potentially problematic conversions – fixed → floating point, signed → unsigned, ... • GCC –Wsign-compare – signed → unsigned producing incorrect result – warning: comparison between signed and unsigned integer expressions [-Wsign-compare] – see http://stackoverflow.com/questions/16834588/wsign-compare-warningin-g for example of real problem • Runtime integer error checks using –ftrapv – trap function called when signed overflow in addition, subs, mult. occur – but significant performance penalty (continuous overflow checking) 40 | PA193 - Static and dynamic checkers GCC -ftrapv 41 | PA193 - Static and dynamic checkers /* compile with gcc -ftrapv */ #include #include #include void signalHandler(int sig) { printf("Overflow detected\n"); } int main() { signal(SIGABRT, &signalHandler); int largeInt = INT_MAX; int normalInt = 42; int overflowInt = largeInt + normalInt; /* should cause overflow */ /* if compiling with -ftrapv, we shouldn't get here */ return 0; } http://stackoverflow.com/questions/5005379/c-avoiding-overflows-when-working-with-big-numbers STATIC ANALYSIS TOOLS 42 | PA193 - Static and dynamic checkers Static analysis tools • List of static checkers – http://spinroot.com/static/ – http://en.wikipedia.org/wiki/List_of_tools_for_static_code_a nalysis – https://security.web.cern.ch/security/recommendations/en/ code_tools.shtml • We will be interested in C/C++ checkers – but tools exists for almost any language | PA193 - Static and dynamic checkers43 Both free and commercial tools • Commercial tools – PC-Lint (Gimpel Software) – Klocwork Insight (Klocwork) – Coverity Prevent (now under HP) – Microsoft PREfast (included in Visual Studio) • Free tools – Rough Auditing Tool for Security (RATS) http://code.google.com/p/rough- auditing-tool-for-security/ – CppCheck http://cppcheck.sourceforge.net/ – Flawfinder http://www.dwheeler.com/flawfinder/ – Splint http://www.splint.org/ – FindBugs http://findbugs.sourceforge.net (for Java programs) – Doxygen’s call graphs from source http://www.stack.nl/~dimitri/doxygen/ – ... 44 | PA193 - Static and dynamic checkers | PA193 - Static and dynamic checkers Flawfinder • Last version 1.27 (2007-01-16) • Download at http://www.dwheeler.com/flawfinder/ • Build by setup.py build • Install by setup.py install • /build/scripts***/flawfinder.py • flawfinder.py --context --html source_dir 45 | PA193 - Static and dynamic checkers Flawfinder - example 46 Splint • Secure Programming Lint • Annotation-Assisted Lightweight Static Checking • http://www.splint.org/ – standard static analyzer – possibility to add annotations • Last version 3.1.2 (2007) • Splint overview – http://www.slideshare.net/UlissesCosta/splint-the-c-code- static-checker 47 | PA193 - Static and dynamic checkers RATS • Rough Auditing Tool for Security (RATS) – http://code.google.com/p/rough-auditing-tool-for-security/ • Windows and Linux support • Previous version 2.3 (2009) • Last version 2.4 (December 2013) 48 | PA193 - Static and dynamic checkers Cppcheck • A tool for static C/C++ code analysis – Open-source freeware, http://cppcheck.sourceforge.net/ – Online demo http://cppcheck.sourceforge.net/demo/ • Last version 1.66 (2014-08-02 ) • Used to find bugs in open-source projects (Linux kernel... ) • Command line & GUI version • Standalone version, plugin into IDEs, version control... – Code::Blocks, Codelite, Eclipse, Jenkins... – Tortoise SVN – not Visual Studio • Cross platform (Windows, Linux) – sudo apt-get install cppcheck 49 | PA193 - Static and dynamic checkers Cppcheck – what is checked? • Bound checking for array overruns • Suspicious patterns for class • Exceptions safety • Memory leaks • Obsolete functions • sizeof() related problems • String format problems... • See full list http://sourceforge.net/apps/mediawiki/cppcheck/ind ex.php?title=Main_Page#Checks 50 | PA193 - Static and dynamic checkers Cppcheck – categories of problems • error – when bugs are found • warning - suggestions about defensive programming to prevent bugs • style - stylistic issues related to code cleanup (unused functions, redundant code, constness...) • performance - suggestions for making the code faster. • portability - portability warnings. 64-bit portability. code might work different on different compilers. etc. • information - Informational messages about checking problems 51 | PA193 - Static and dynamic checkers Cppcheck | PA193 - Static and dynamic checkers52 Cppcheck – simple custom rules • User can write own regular expression-based rules – Perl Compatible Regular Expressions www.pcre.org – limited only to simpler analysis – executed over simplified code (code after preprocessing) • http://sourceforge.net/projects/cppcheck/files/Articles/writing- rules-2.pdf • Regular expression can be supplied on command line – cppcheck.exe --rule=".+" file.cpp • match any code, use to obtain simplified code – cppcheck.exe --rule="pass[word]*" file.cpp • match any occurrence of pass or password or passwordword... • Or via XML file (for stable repeatedly used rules) 53 | PA193 - Static and dynamic checkers cppcheck.exe --rule="pass[word]*" file.cpp • cppcheck.exe --rule="if \( p \) { free \( p \) ; }" file.cpp – will match only pointer with name ‘p’ 54 | PA193 - Static and dynamic checkers Cppcheck – simple custom rules (XML) • XML file with regular expression and information – pattern to search for – information displayed on match 55 | PA193 - Static and dynamic checkers LIST PATTERN ID SEVERITY SUMMARY if \( p \) { free \( p \) ; } redundantCondition style Redundant condition. It is valid to free a NULL pointer. Example taken from http://sourceforge.net/projects/cppcheck/files/Articles/writing-rules-1.pdf/download Cppcheck – complex custom rules • Based on execution of user-supplied C++ code – possible more complex analysis 1. Use cppcheck.exe --debug file.cpp – outputs simplified code including Cppcheck’s internal variable unique ID 2. Write C++ code fragment performing analysis 3. Recompile Cppcheck with new rule and execute • Read more details (writing-rules-2 & writing-rules-3) – http://sourceforge.net/projects/cppcheck/files/Articles/ 56 | PA193 - Static and dynamic checkers Custom rules – obtaining variable ID 57 | PA193 - Static and dynamic checkers d:\StaticAnalysis>cppcheck.exe --debug dealloc.cpp Checking dealloc.cpp... ##file dealloc.cpp 1: void f ( ) { 2: if ( p ) { free ( p ) ; } 3: 4: char pass@1 [ 7 ] = "Secret" ; 5: char password@2 [ 8 ] = "Secret2" ; 6: } variable pass has ID @1 58 | PA193 - Static and dynamic checkers void CheckOther::dealloc() { // Loop through all tokens for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { // Is there a condition and a deallocation? if (Token::Match(tok, "if ( %var% ) { free ( %var% ) ; }")) { // Get variable name used in condition: const std::string varname1 = tok->strAt(2); // Get variable name used in deallocation: const std::string varname2 = tok->strAt(7); // Is the same variable used? if (varname1 == varname2) { // report warning deallocWarning(tok); } } } } // Report warning void CheckOther::deallocWarning() { reportError(tok, // location Severity::warning, // severity "dealloc", // id "Redundant condition"); // message } pattern to match %var% will match any variable reporting error in standard format PREfast - Microsoft static analysis tool 59 | PA193 - Static and dynamic checkers PREfast - Microsoft static analysis tool • Visual Studio Ultimate and Premium Editions • Documentation for PREfast – http://msdn.microsoft.com/en-us/library/windows/hardware/gg487351.aspx • PREfast tutorial – http://www.codeproject.com/Articles/167588/Using-PREfast-for-Static- Code-Analysis • Can be enabled on every build – not enabled by default, time consuming • Can be extended by source code annotation (SAL) – (next lecture) 60 | PA193 - Static and dynamic checkers PREfast – example bufferOverflow 61 | PA193 - Static and dynamic checkers PREfast – what can be detected • Potential buffer overflows • Memory leaks, uninitialized variables • Excessive stack usage • Resources – release of locks... • Incorrect usage of selected functions • List of all code analysis warnings http://msdn.microsoft.com/en-us/library/a5b9aa09.aspx 62 | PA193 - Static and dynamic checkers PREfast settings (VS 2012) • http://msdn.microsoft.com/en-us/library/ms182025.aspx | PA193 - Static and dynamic checkers63 PREfast & MSVC /analyze • Enables code analysis and control options – http://msdn.microsoft.com/en-us/library/ms173498.aspx • Some analysis rules work only for managed code (C#, VB...) • Available rule sets – http://msdn.microsoft.com/en-us/library/dd264925%28v=vs.120%29.aspx • Writing custom rules – http://msdn.microsoft.com/en-us/library/dd380660%28v=vs.120%29.aspx 64 | PA193 - Static and dynamic checkers Coverity (free for open-source) • Commercial static & dynamic analyzer • Free for C/C++ & Java open-source projects • https://scan.coverity.com/ • Process – Register at scan.coverity.com (GitHub account possible) – Download Coverity build tool for your platform • Quality and Security Advisor – Build your project with cov-build • cov-build --dir cov-int – Zip and submit build for analysis • Can be integrated with Travis CI (continuous integration) – https://scan.coverity.com/travis_ci 65 | PA193 - Static and dynamic checkers 66 | PA193 - Static and dynamic checkers ++ FindBugs • http://findbugs.sourceforge.net/ • Static analysis of Java programs • Current version 2.0.2 (2012-12-02) • Command-line, GUI, plugins into variety of tools • Support for custom rules • FindSecurityBugs – Additional detection rules for FindBugs – https://h3xstream.github.io/find-sec-bugs/bugs.htm 67 | PA193 - Static and dynamic checkers STATIC ANALYSIS IS NOT PANACEA 68 | PA193 - Static and dynamic checkers 69 | PA193 - Static and dynamic checkers // Note: GCC and MSVC uses different memory alignment // Try "12345678DevilEvecosia" as a password for gcc build // Try "1234567812345678Devil I am. Ha Ha" as a password for MSVC debug build void demoBufferOverflowData() { int unused_variable = 30; #define NORMAL_USER 'n' #define ADMIN_USER 'a' int userRights = NORMAL_USER; #define USER_INPUT_MAX_LENGTH 8 char userName[USER_INPUT_MAX_LENGTH]; char passwd[USER_INPUT_MAX_LENGTH]; // print some info about variables printf("%-20s: %p\n", "userName", userName); printf("%-20s: %p\n", "passwd", passwd); printf("%-20s: %p\n", "unused_variable", &unused_variable); printf("%-20s: %p\n", "userRights", &userRights); printf("\n"); // Get user name memset(userName, 1, USER_INPUT_MAX_LENGTH); memset(passwd, 2, USER_INPUT_MAX_LENGTH); printf("login as: "); fflush(stdout); gets(userName); // Get password printf("%s@vulnerable.machine.com: ", userName); fflush(stdout); gets(passwd); // Check user rights (set to NORMAL_USER and not changed in code) if (userRights == NORMAL_USER) { printf("\nWelcome, normal user '%s', your rights are limited.\n\n", userName); fflush(stdout); } if (userRights == ADMIN_USER) { printf("\nWelcome, all mighty admin user '%s'!\n", userName); fflush(stdout); } // How to FIX: //memset(userName, 0, USER_INPUT_MAX_LENGTH); //fgets(userName, USER_INPUT_MAX_LENGTH - 1, stdin); //memset(passwd, 0, USER_INPUT_MAX_LENGTH); //fgets(passwd, USER_INPUT_MAX_LENGTH - 1, stdin); } Cppcheck --enable=all d:\StaticAnalysis>cppcheck --enable=all bufferOverflow.cpp Checking bufferOverflow.cpp... [bufferOverflow.cpp:26]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. [bufferOverflow.cpp:31]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. MSVC /W4 1> BufferOverflow.cpp 1>bufferoverflow.cpp(32): warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(261) : see declaration of 'gets' 1>bufferoverflow.cpp(37): warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(261) : see declaration of 'gets' 1>bufferoverflow.cpp(78): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\string.h(191) : see declaration of 'strncpy' 1>bufferoverflow.cpp(81): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(357) : see declaration of 'sprintf' MSVC /analyze (PREfast) 1> BufferOverflow.cpp bufferoverflow.cpp(32): warning : C6386: Buffer overrun while writing to 'userName': the writable size is '8' bytes, but '4294967295' bytes might be written. bufferoverflow.cpp(37): warning : C6386: Buffer overrun while writing to 'passwd': the writable size is '8' bytes, but '4294967295' bytes might be written. Type overflow – example with dynalloc 70 | PA193 - Static and dynamic checkers typedef struct _some_structure { float someData[1000]; } some_structure; void demoDataTypeOverflow(int totalItemsCount, some_structure* pItem, int itemPosition) { // See http://blogs.msdn.com/oldnewthing/archive/2004/01/29/64389.aspx some_structure* data_copy = NULL; int bytesToAllocation = totalItemsCount * sizeof(some_structure); printf("Bytes to allocation: %d\n", bytesToAllocation); data_copy = (some_structure*) malloc(bytesToAllocation); if (itemPosition >= 0 && itemPosition < totalItemsCount) { memcpy(&(data_copy[itemPosition]), pItem, sizeof(some_structure)); } else { printf("Out of bound assignment"); return; } free(data_copy); } Cppcheck --enable=all d:\StaticAnalysis>cppcheck --enable=all typeOverflow.cpp Checking typeOverflow.cpp... [typeOverflow.cpp:17]: (error) Memory leak: data_copy MSVC /W4 1> typeOverflow.cpp nothing ☺ MSVC /analyze (PREfast) 1> typeOverflow.cpp bufferoverflow.cpp(13): warning : C6011: Dereferencing NULL pointer 'data_copy'. Test suites – vulnerable code, benchmark • SAMATE Juliet Test Suite – huge test suite which contains at least 45000 C/C++ test cases – http://samate.nist.gov/SRD/testsuite.php • Static analysis test suite for C programs – http://mathind.csd.auth.gr/static_analysis_test_suite/ 71 | PA193 - Static and dynamic checkers Microsoft Zuno’s bug • No luck with Cppcheck • No luck with PREfast • Coverity? • Will be solved in next lecture – fuzzing 72 | PA193 - Static and dynamic checkers year = ORIGINYEAR; /* = 1980 */ while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } SUMMARY 73 | PA193 - Static and dynamic checkers Summary • Static analysis is VERY important tool for writing secure software – significant portion of analysis done already by compiler (errors, warning) • Multiple tools exists (both free and commercial) – Flawfinder, Cppcheck, PREfast... – custom rules can be written • Static analysis cannot find all problems – problem of false positives/negatives – no substitution for extensive testing and defense programming 74 | PA193 - Static and dynamic checkers Questions References • Fortify’s presentation, overview of static checking – http://secwg.noc.harvard.edu/archives/talks_files/chess_se cure_programming.pdf • Cppcheck presentation – http://www.slideshare.net/zblair/cppcheck-10316379 • Secure Programming: the Seven Pernicious Kingdoms – http://www.datamation.com/secu/print.php/3686291 75 | PA193 - Static and dynamic checkers | PA193 - Static and dynamic checkers Recommended reading • Process of security code review – http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=01668009 • Why cryptosystems fail, R. Anderson – http://www.cl.cam.ac.uk/~rja14/Papers/wcf.pdf • Software Security Code Review – http://www.softwaremag.com/l.cfm?doc=2005-07/2005-07code • Static code analysis tools – http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis • Security in web applications (OWASP) – http://www.owasp.org/index.php/Code_Review_Introduction 76