~~SLIDESHOW~~ ====== Statyczna analiza kodu ====== **Analiza statyczna kodu** - analiza struktury kodu źródłowego lub kodu skompilowanego bez jego uruchomienia. Static Analysis Software Testing (SAST) - narzędzia do analizy statycznej Analiza statyczna a inspekcja kodu ("code review") ===== SDL for Agile ===== Agile Development Using Microsoft Security Development Lifecycle - analiza statyczna w każdym sprincie {{:zajecia:npr_2015_1:microsoft-static.png?500|}} Źródło: http://www.microsoft.com/security/sdl/discover/sdlagile.aspx ===== Metody analizy ===== * analiza leksykograficzna - wyszukiwanie niebezpiecznych konstrukcji w kodzie źródłowym, zazwyczaj na podstawie zestawu reguł, różnych heurystyk i dopasowania do wzorców błedów * metody formalne - oparte na matematycznej definicji zachowania programu * modele matematyczne * reguły logiczne [[wp>Hoare_logic]] * analiza przepływu [[wp>Data-flow_analysis]] * obliczanie metryk kodu źródłowego. Ocena jakości kodu źródłowego na podstawie danych statystycznych. ===== Cechy ===== * Łatwość użycia, prostota wdrożenia w cykl wytwarzania oprogramowania * Automatyzacja, integracja z narzędziami //continius integrations// * Szybkie wykrywanie błędów, których naprawa jest prosta i mało kosztowna * nie wymaga uruchomienia aplikacji * łatwe do zrównoleglenia * Możliwości rozszerzania: własne reguły, wtyczki, * Integracja z innymi narzędziami: serwery automatyzacji, IDE, kontrola wersji * Dużo darmowych narzędzi ===== Cechy ===== * Wymagany dostęp do źródeł * Reguły wykrywają zazwyczaj proste błędy (nie zastąpią ręcznego sprawdzenia) * Dużo szumu, zbyt czułe (duże prawdopodobieństwo //false positive//) * Każde narzędzie zazwyczaj pokrywa pewien zakres testów (do 14% błedów?!) dlatego warto korzystać z kilku. * Istnieją narzędzia integrujące wiele narzędzi SAST, np: [[http://codedx.com/|CodeEx]], Yast (open source) ===== Czego dotyczy analiza statyczna ===== * analiza poprawności składni * luki w bezpieczeństwie, także błędy które mogą pojawić się przy specyficznych danych wejściowych * detekcja backdoors, niebezpieczne i nieaktualne funkcje, wycieki pamięci, przepełnienie bufora, używanie niezainicjowanych zmiennych, SQL Injections, * jakość kodu, ocena stylu, powtórzenia kodu, nieużywane fragmenty kodu, ... * wydajność, wykrywanie wąskich gardeł, niewydajne konstrukcje, sugestie dotyczące poprawienia wydajności * zgodność z dobrymi praktykami, zachowanie standardów, norm nazewniczych, problemy z przenośnością kodu ===== Dlaczego analizować kod? ===== Statyczna analiza programu pozwala na: * zwiększenie wydajności i stabilności poprzez zasady oparte na dobrych praktykach, * unikniecie typowych błędów podczas programowania, * dostarczenie struktury do zarządzania standardami kodu. * wymuszenie zasad i standardów pisania kodu * zwiększanie bezpieczeństwa poprzez kolejny etap tetowania ===== Dlaczego analizować kod? ===== Koszt naprawy błędu w zależności od momentu wykrycia {{http://www.microsoft.com/global/security/sdl/PublishingImages/About/benefits_reducecost_01.jpg}} Źródło: http://www.microsoft.com/security/sdl/about/benefits.aspx ===== Narzędzia ===== [[http://www.unix.com/man-page/FreeBSD/1/lint|Lint]] - UNIX V7 1979, historyczny program od którego nazwy często określa się narzędzia do analizy i szukania błedów * C/C%%++%%: [[http://cppcheck.sourceforge.net/|cppcheck]], clint, [[http://www.splint.org/|splint]], [[http://clang-analyzer.llvm.org/|clang]], [[http://frama-c.com/|frama-c]] * PHP: [[https://github.com/oliverklee/pixy|pixy]], [[http://www.program-transformation.org/PHP/PhpSat|php-sat]] * Java: [[http://findbugs.sourceforge.net/|FindBugs]], [[http://sourceforge.net/projects/jlint/|jlint]], PMD, Checkstyle * Python: [[http://pylint.org/|pylint]] * dotNet: FxCop, CAT.NET * JavaScript: [[http://www.jslint.com/|jslint]] * HTML: [[http://tidy.sourceforge.net/|tidy]] ([[http://infohound.net/tidy/|wersja online]]) , [[http://validator.w3.org/|W3C Validator]] * CSS: [[http://jigsaw.w3.org/css-validator/|W3C CSS Validator]] , [[http://csslint.net/csslint]] ===== Wielojęzykowe ===== * [[http://code.google.com/p/rough-auditing-tool-for-security/|rats]] (rough auditing tool for security) C, C%%++%%, Perl, PHP, Python * [[http://pmd.sourceforge.net/|PMD]] Java, JavaScript, XML, XSL (zawiera CPD analiza powtórzeń: C, C%%++%%, C#, PHP, Ruby, Fortran) * [[http://www.scovetta.com/yasca.html|Yasca]] Java, C/C%%++%%, HTML, JavaScript, ASP, ColdFusion, PHP, COBOL, .NET, and other languages + integracja z innymi SAT * [[http://sourceforge.net/projects/visualcodegrepp/|VisualCodeGrepper]] C/C%%++%%, C#, VB, PHP, Java and PL/SQL Wiele innych: * [[wp>List_of_tools_for_static_code_analysis]] * [[http://samate.nist.gov/index.php/Source_Code_Security_Analyzers.html|Source Code Security Analyzers]] ===== Kompilatory ===== Analiza w [[http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html|GCC]] * ''-pedantic'' \\ tylko czyste ISO C i ISO C%%++%% * ''-Wall'' \\ wszystkie ostrzeżenia * ''-Werror'' \\ ostrzeżenia generują błąd kompilacji * ''-Wextra'' \\ dodatkowe ostrzeżenia wykraczające poza ''Wall'' Visual C++: warning level 4 ===== cppcheck ===== * CLI, GUI, biblioteka (API) * Raporty: txt, XML, HTML * Wykrywanie błędów, które nie są wykrywane przez kompilatory. Celem jest brak fałszywych alarmów (wykrywanie tylko prawdziwych błędów). * wielowątkowy * wsparcie: Code::Blocks (wbudowany), [[http://www.eclipse.org/hudson/|Hudson]], [[https://github.com/VioletGiraffe/cppcheck-vs-addin/releases/tag/1.2.1|wtyczka Visual Studio]] * dodawanie reguł opartych na wyrażeniach regularnych [[http://cppcheck.sourceforge.net/|Cppcheck]] \\ [[http://cppcheck.sourceforge.net/demo/|Online Demo]] \\ [[http://sourceforge.net/p/cppcheck/wiki/ListOfChecks/|Lista reguł i testów]] \\ cppcheck --doc cppcheck --errorlist'' ===== Ograniczenia ===== * Jest wiele typów błędów które ciężko jest wykryć * Trudno wykrywalne błędy związane są z konfiguracją lub logiką biznesową. * Dodatkowe moduły, biblioteki, konteksty dodawane przez frameworki * Skomplikowane algorytmy i architektury // calculate the number of days int days = hours / 23; ===== Przykład ===== int main() { char *x; int a[20]; *x = 5; a[20] = 5; return 0; } cppcheck --enable=all test1.c Checking test1.c... [test1.c:4]: (style) Variable 'x' is not assigned a value. [test1.c:8]: (style) Variable 'a' is assigned a value that is never used. [test1.c:8]: (error) Array 'a[20]' accessed at index 20, which is out of bounds. [test1.c:7]: (error) Uninitialized variable: x Checking usage of global functions.. ===== Przykład ===== #include int main() { char c; while (c != 'x'); { c = getchar(); if (c = 'x') return 0; switch (c) { case '\n': case '\r': printf("Newline\n"); default: printf("%c",c); } } return 0; } Źródło: [[http://en.wikipedia.org/wiki/Splint_%28programming_tool%29|wikipedia.org]] ===== Przykład: buffer overflow ===== Śledzenie wywołań funkcji: void f1(char *s) { s[20] = 0; } void f2() { char a[10]; if (x + y == 2) { f1(a); } } Array 'a[10]' index 20 out of bounds ===== ===== Prawie to samo ale ''cppcheck'' już nie wykrywa błędu void f3(char *s) { if (x + y == 2) { s[20] = 0; } } void f4() { char a[10]; f3(a); } ===== Wycieki pamięci ===== void f() { char *a = malloc(10); if (x + y == 2) { return; } free(a); } Wynik cppcheck [mem.c:5]: (error) Memory leak: a ===== ===== void f2(int x) { char *a = 0; if (x == 10) a = malloc(10); if (x == 20) free(a); } Brak błedu?! ===== Automatyzacja testów ===== * kiedy analizować: przed/po commicie, po każdym buildzie, po zapisaniu pliku * IDE i ich edytory sprawdzają składnię też (rozszerzenia Resharper) * testy po stronie developera lub po stronie repozytorium (serwera autoamtyzacji) * skrypty uruchamiane po zatwierdzeniu zmiany + + powiadomienia (email, inne alerty), w SVN ''hooks/post-commit'' * uniemożliwienie zatwierdzenia kodu z błędami, w SVN ''hooks/pre-commit'' * serwery automatyzacji, np. [[http://www.eclipse.org/hudson/|Hudson]] Przykłady: [[http://www.petefreitag.com/articles/findbugs-commit-email|FindBugs]], [[http://sourceforge.net/p/cppcheck/wiki/tortoisesvn/|Cppcheck+TortoiseSVN]] [[http://wordaligned.org/articles/a-subversion-pre-commit-hook|SVN pre-commit]] ===== Źródła ===== * [[http://sekurak.pl/statyczna-analiza-bezpieczenstwa-kodu-aplikacji-czesc-1-wprowadzenie/|Statyczna analiza bezpieczeństwa kodu aplikacji]] Adrian “Vizzdoom” Michalczy * [[http://security.psnc.pl/files/szkolenia/KDM_101116.pdf|Tomasz Nowak, Statyczna analiza kodu źródłowego]] * [[http://cppcheck.sourceforge.net/|Cppcheck]] * [[http://splint.org/pubs.html|Splint publications]] * [[https://msdn.microsoft.com/en-us/library/ms182066%28v=vs.140%29.aspx|Walkthrough: Analyzing Managed Code for Code Defects]] (MSDN) * [[https://msdn.microsoft.com/en-us/library/dd264897%28v=vs.140%29.aspx|Analyzing Application Quality by Using Code Analysis Tools]] (MSDN) * [[http://blogs.msdn.com/b/hkamel/archive/2013/10/24/visual-studio-2013-static-code-analysis-in-depth-what-when-and-how.aspx|Visual Studio 2013 Static Code Analysis in depth: What? When and How?]] Hosam Kamel * [[http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext|A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World]]