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

Ź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 Hoare_logic

analiza przepływu 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: 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

Źródło: http://www.microsoft.com/security/sdl/about/benefits.aspx

Narzędzia

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++: cppcheck, clint, splint, clang, frama-c

PHP: pixy, php-sat

Java: FindBugs, jlint, PMD, Checkstyle

Python: pylint

dotNet: FxCop, CAT.NET

JavaScript: jslint

HTML: tidy (wersja online) , W3C Validator

CSS: W3C CSS Validator , http://csslint.net/csslint

Wielojęzykowe

rats (rough auditing tool for security) C, C++, Perl, PHP, Python

PMD Java, JavaScript, XML, XSL (zawiera CPD analiza powtórzeń: C, C++, C#, PHP, Ruby, Fortran)

Yasca Java, C/C++, HTML, JavaScript, ASP, ColdFusion, PHP, COBOL, .NET, and other languages + integracja z innymi SAT

VisualCodeGrepper C/C++, C#, VB, PHP, Java and PL/SQL

Wiele innych:

List_of_tools_for_static_code_analysis

Source Code Security Analyzers

Kompilatory

Analiza w 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), Hudson, wtyczka Visual Studio

dodawanie reguł opartych na wyrażeniach regularnych

Cppcheck
Online Demo
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 <stdio.h> 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: 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. Hudson

Przykłady: FindBugs, Cppcheck+TortoiseSVN SVN pre-commit

Źródła

Statyczna analiza bezpieczeństwa kodu aplikacji Adrian “Vizzdoom” Michalczy

Tomasz Nowak, Statyczna analiza kodu źródłowego

Cppcheck

Splint publications

Walkthrough: Analyzing Managed Code for Code Defects (MSDN)

Analyzing Application Quality by Using Code Analysis Tools (MSDN)

Visual Studio 2013 Static Code Analysis in depth: What? When and How? Hosam Kamel

A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World