~~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 automatycznej 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]]
* **metryki kodu źródłowego** - ocena jakości kodu źródłowego na podstawie danych statystycznych.
===== Zalety =====
* Szybkość działania - szybkie wykrywanie błędów, których naprawa jest prosta i mało kosztowna
* nie wymagają uruchamiania programu
* łatwe do zrównoleglenia
* Łatwość użycia - proste we wdrożeniu w cykl wytwarzania oprogramowania
* Automatyzacja - integracja z narzędziami //continius integrations//
* Możliwości rozszerzania: własne reguły, wtyczki, ...
* Integracja z innymi narzędziami: serwery automatyzacji, IDE, kontrola wersji
* Dużo darmowych narzędzi
===== Wady =====
* Wymagany dostęp do źródeł
* Reguły wykrywają zazwyczaj proste błędy i nie są w stanie wyeliminować ręcznego sprawdzenia kodu
* Dużo szumu, zbyt czułe - duże prawdopodobieństwo zaklasyfikowanie poprawnego fragmentu jako błędu (//false positive//)
* Każde narzędzie zazwyczaj pokrywa pewien zakres testów (do 14% błędów?!). Dlatego warto korzystać z kilku różnych skanerów kodu. 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 testowania
* analizując sygnalizowane błędy można się sporo nauczyć na temat dobrych praktyk bezpiecznego programowania
===== Dlaczego analizować kod? =====
Koszt naprawy błędu w zależności od momentu wykrycia
{{zajecia:npr:benefits.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 Static Analyzer]] (składowa kompilatora //clang//), [[http://frama-c.com/|frama-c]], [[https://wiki.eclipse.org/CDT/designs/StaticAnalysis|CODAN]] wbudowany w CDT (wtyczka Eclipse)
* 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]], [[https://pmd.github.io/|PMD]], [[http://checkstyle.sourceforge.net/|Checkstyle]]
* Python: [[http://pylint.org/|pylint]]
* dotNet: [[https://msdn.microsoft.com/en-us/library/bb429476(v=vs.80).aspx|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 =====
Kompilatory oprócz sprawdzania składni również potrafią sygnalizować możliwość występowania błędu w kodzie.
[[http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html|GCC warning options]]
* ''-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 =====
* analiza kodu c/C%%++%%
* CLI, GUI, biblioteka (API)
* Raporty: txt, XML, HTML
* Cel:
* wykrywanie błędów, które nie są wykrywane przez kompilatory
* 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]]
* możliwość dodawania własnych reguł opartych na wyrażeniach regularnych
[[http://cppcheck.sourceforge.net/|Cppcheck]] \\
[[http://cppcheck.sourceforge.net/demo/|Online Demo]] \\
===== Wykrywane błedu =====
* wykroczenia poza zakres tablicy
* wycieki pamięci
* odwołania do adresu NULL
* niezainicjowane zmienne
* używanie przestarzałych lub niebezpiecznych funkcji
* wykrywanie niedostępnych fragmentów kodu oraz powtórzeń kodu
* wiele innych ...
* [[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ć, np błędy związane są z konfiguracją lub logiką biznesową
* Problemem są zależności, dodatkowe moduły, biblioteki, konteksty dodawane przez frameworki
* Skomplikowane algorytmy i architektury bardzo ciężko jest analizować
// 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]]