Gdy liczba commitów rośnie wykładniczo, a zależności żyją własnym życiem, ręczny code review nie zatrzyma w porę wstrzyknięć SQL, wycieków danych czy błędów pamięci. Zespół potrzebuje czegoś, co nie tylko wykryje oczywiste błędy, ale zrozumie kontekst i przepływ danych w aplikacji. Sztuczna inteligencja potrafi przeczytać kod jak tekst, ale analizować go jak program – od tokenów, przez drzewa składni, po wzorce zachowań wykonania. Poniżej konkretny, techniczny przewodnik, jak AI analizuje kod w różnych językach, aby wykrywać luki, błędy i zagrożenia dla prywatności oraz jak to wdrożyć bez paraliżowania developera lawiną fałszywych alarmów.
- Jak AI rozpoznaje podatność bez uruchamiania programu?
- Czy modele rozumieją różnice między C++, Pythonem, a TypeScriptem?
- Jak połączyć SAST, DAST, IAST i SCA, by zredukować szum i czas napraw?
- Jak śledzić PII/PHI w mikroserwisach i logach?
- Kiedy ufać propozycjom poprawek generowanych przez model?
- Jak zorganizować pipeline w CI/CD, by wyniki były akceptowalne przez zespół?
Dlaczego klasyczne podejście nie wystarcza i gdzie AI wnosi przewagę
Skala, zmienność i presja czasu
Statyczne skanery oparte na prostych regułach działają szybko, ale gubią kontekst. Wystarczy, że walidacja danych wejściowych została przeniesiona do middleware, by reguła „użyto eval” przestała być użyteczna – nie wiadomo, czy to niebezpieczne. AI radzi sobie lepiej, bo łączy wiele źródeł sygnału: strukturę kodu, przepływ danych, typy i historię zmian. Dzięki temu zamiast 50 ostrzeżeń „XSS możliwy”, dostajesz 3, w których model pokazuje konkretną ścieżkę danych z użytkownika do DOM bez sanityzacji.
Tempo zmian frameworków jest kolejną przeszkodą. Nowe API potrafią narzucać wyższy poziom bezpieczeństwa (np. automatyczne escapowanie), ale też otwierać luki przy niewłaściwym użyciu. Modele uczone na szerokich korpusach kodu szybciej wyłapują te wzorce niż ręcznie aktualizowane zestawy reguł.
Od reguł do rozumowania probabilistycznego
Reguły działają zero-jedynkowo. AI ocenia ryzyko: „na 82% to deserializacja niebezpiecznego typu, bo widzę brak białej listy klas oraz ścieżkę z danych użytkownika”. Ten probabilistyczny charakter pozwala lepiej porządkować priorytety i planować sprinty naprawcze, zamiast gasić pożary według alfabetu plików.
Kontekst domenowy i styl projektu
W projektach finansowych „błąd w logu” może oznaczać poważne naruszenie prywatności. AI uczy się, że identyfikator klienta, nawet zahaszowany, w połączeniu z timestampem i ID transakcji tworzy wrażliwy zestaw. Modele mogą uwzględnić wytyczne organizacji i klasyfikować ryzyko inaczej dla tej samej konstrukcji w sklepie internetowym i w aplikacji medycznej.
Co sprawdzić w tej sekcji
- Czy obecne narzędzia przekładają się na realne naprawy, czy generują szum?
- Czy polityki bezpieczeństwa uwzględniają kontekst domenowy (np. finansowy, zdrowotny)?
- Czy masz metryki skuteczności (ile alertów zakończyło się poprawką)?
Jak AI analizuje kod: fundamenty techniczne
Reprezentacje kodu: od tokenów do grafów
Krok 1: Parsowanie. Kod zamienia się w AST (abstrakcyjne drzewo składni), które pokazuje strukturę wyrażeń i instrukcji niezależnie od formatowania. To baza do wykrycia np. wstrzyknięć zależnych od sposobu składania stringów.
Krok 2: Grafy przepływu sterowania (CFG) i zależności (PDG). Dzięki nim model rozumie, które gałęzie mogą się wykonać i jak wartości przechodzą między instrukcjami. To klucz przy złożonych if-ach, wyjątkach i asynchroniczności.
Krok 3: Reprezentacja wektorowa (embeddings) i cechy semantyczne. Tokeny, typy, nazwy funkcji i komentarze tworzą „sygnaturę” fragmentu kodu. Sieci grafowe (GNN) i transformery umieją odzwierciedlić podobieństwa między podatnymi fragmentami nawet wtedy, gdy różnią się detalami składniowymi.
Śledzenie przepływu danych (taint analysis)
AI oznacza źródła niezaufanych danych (np. request.body, parametry zapytań, websocket) jako „skażone” i sprawdza, czy dotrą do niebezpiecznych funkcji (tzw. sink), takich jak wykonanie polecenia systemowego, zapytanie SQL, tworzenie HTML w DOM lub deserializacja. Krytyczne jest wykrycie brakujących „sanitizerów” po drodze. Modele uczą się także niestandardowych sanitizers specyficznych dla twojej bazy narzędzi.
Wnioskowanie i ranking ryzyka
Kiedy ścieżka danych wygląda podejrzanie, model oblicza prawdopodobieństwo luki na podstawie wielu cech: złożoności ścieżki, odległości źródło–ujście, typów danych, wzorców w nazwach funkcji oraz kontekstu frameworka. Następnie przypisuje kategorię (np. CWE-79 XSS, CWE-89 SQLi), łączy ją z wpływem na poufność/integralność/dostępność i nadaje priorytet. To umożliwia automatyczne budowanie backlogu bezpieczeństwa z sensowną kolejnością zadań.
Co sprawdzić w tej sekcji
- Czy narzędzie potrafi pokazać pełną ścieżkę źródło–sanitizer–ujście?
- Czy wspiera embeddings i grafy, czy tylko dopasowuje reguły?
- Jak definiowane są customowe sanitizery w waszym kodzie?

Przegląd metod: SAST, DAST, IAST i SCA w wersji z AI
SAST z uczeniem maszynowym
Statyczna analiza z AI to więcej niż regexy. Modele szkolone na przykładach podatności uczą się wariantów tego samego ataku w różnych językach. Przykład: sklejanie SQL w Pythonie (f-string), w Javie (String.format) i w JS (template literals) wygląda inaczej, ale prowadzi do tej samej luki. SAST z AI potrafi też rozpoznać wzorce obiektowe (np. repozytoria w DDD), śledząc taint między warstwami.
DAST wspomagany generatywnie
Dynamiczne testy z AI generują scenariusze wejść dopasowane do logiki aplikacji. Model „rozumie” interfejs API, wnioskuje typy parametrów i tworzy testy fuzzujące, które omijają walidacje. Jeśli endpoint przyjmuje JSON, AI potrafi konstruktywnie zmieniać typy pól, długości i strukturę zagnieżdżeń, szukając wyjątków i wycieków informacji przez komunikaty błędów.
IAST i telemetry wykonania
Instrumentacja aplikacji rejestruje realne ścieżki wykonania w testach integracyjnych i środowiskach staging. Modele łączą te dane z analizą statyczną, żeby wyeliminować fałszywe pozytywy: jeśli podejrzany sink nigdy nie został wywołany kontrolowanym inputem, ryzyko spada. IAST wykrywa też luki wynikające z konfiguracji środowiska, których SAST nie zobaczy (np. brak nagłówków bezpieczeństwa).
Analiza zależności (SCA) sterowana kontekstem aplikacji
Klasyczne SCA melduje „podatna wersja X”, ale nie sprawdza, czy aplikacja w ogóle dotyka wadliwego symbolu. Wersja z AI łączy SBOM z analizą osiągalności i ryzykiem domenowym. Krok 1: budowa pełnej SBOM (CycloneDX/SPDX) z lockfile’i i obrazu kontenera. Krok 2: odtworzenie grafu wywołań do symboli z podatnością i dopasowanie do twojego kodu (importy, reflection, dynamiczne require). Krok 3: ocena, czy ścieżka jest osiągalna w twojej konfiguracji i na twojej platformie (różnice w backend/SSR/edge). Krok 4: propozycja aktualizacji z oceną ryzyka kompatybilności na bazie changelogów i testów regresyjnych uruchomionych w sandboxie.
Modele wykrywają także złośliwe pakiety (typosquatting, dependency confusion) przez podobieństwo nazw, anomalie w metadanych (nagły wzrost wersji, brak historii maintainerów) oraz sygnały z kodu (kopiowanie plików SSH, dynamiczny DNS). W licencjonowaniu LLM-y klasyfikują złożone licencje mieszaną metodą: ekstrakcja klauzul i mapowanie do polityk organizacji (np. „copyleft+linking” vs „permissive”).
Najczęstszy błąd to ślepe podnoszenie wersji „na najnowszą stabilną”. AI potrafi zaproponować „bezpieczną minimalną” (np. 2.4.3→2.4.7), dołączyć diff ryzyka z changeloga i wskazać, które testy muszą przejść, żeby uniknąć ukrytych zmian zachowania.
Co sprawdzić w tej sekcji
- Czy zgłaszane podatności są „osiągalne” w waszym kodzie, czy tylko w grafie zależności?
- Czy SBOM uwzględnia warstwę obrazu (systemowe biblioteki, glibc, openssl)?
- Czy narzędzie proponuje minimalny bezpieczny upgrade i pokazuje testy ryzyka?
Różnice językowe: jak modele adaptują się do semantyki i runtime
W C/C++ modele polują na klasyki pamięci (use-after-free, integer overflow, double-free) oraz ryzyko UB wynikające z optymalizacji kompilatora. Wskazują pary alokacja–zwolnienie, aliasing i ścieżki wyjątków porzucające zasoby. W Rust priorytetem są granice między „safe” i „unsafe”; AI ocenia, czy kontrakty z unsafe są realnie egzekwowane testami lub typami.
Python i Ruby to dynamika: deserializacja (pickle, yaml.load z default loaderem), improwizowane eval/exec, ORM-y składane z f-stringów. Model śledzi schematy input→ORM i sprawdza, czy użyto parametryzacji zamiast stringów. W Node/TS liczy się kontekst XSS (HTML, URL, JS, CSS). AI uczy się, kiedy escapowanie „nie to” zwiększa ryzyko (np. encodeURI vs escapowanie HTML) i wykrywa połączenia SSR/CSR, gdzie dane z serwera trafiają do klienta bez oczyszczania.
W Javie/Kotlinie priorytetem bywa deserializacja (Java Serialization, Jackson bez whitelist), SpEL, misconfig Spring Security i filtry CORS. W Go modele patrzą na wywołania systemowe, templating (html/template vs text/template), propagację context i timeouts w kodzie sieciowym. Na granicach FFI (JNI, Cgo, Wasm) AI weryfikuje, czy zasady bezpieczeństwa „przenikają” przez interfejs (walidacja długości, lifetime’y).
Przykład z praktyki: frontend TS korzysta z „bezpiecznego” sanitizer’a, ale AI wykrywa, że w jednym miejscu użyto go przed złożeniem HTML-a, a nie przed wstrzyknięciem do atrybutu href. To różnica kontekstu, której reguła nie złapie — model tak.
Co sprawdzić w tej sekcji
- Czy skaner zna konteksty escapowania specyficzne dla frameworka (Angular, React, Next SSR)?
- Czy w C/C++ raport pokazuje pary alloc/free i ścieżki wyjątków?
- Czy na styku FFI istnieją testy kontraktów (granice buforów, NUL-termination)?
Śledzenie PII/PHI w kodzie, mikroserwisach i logach
Klucz to nie sam regex na „email”, lecz nieprzerwany łańcuch klasyfikacji. Krok 1: taksonomia danych (PII, SPI, PHI) z mapą pól w schematach (Protobuf/Avro/JSON Schema) i słownikiem aliasów nazw (user_id, uid, subject, sub). Krok 2: etykietowanie źródeł w kodzie i kontraktach API (OpenAPI z rozszerzeniami), aby AI mogła rozszerzać etykiety w całym przepływie — także przez kolejki i ETL. Krok 3: polityki maskowania i redakcji na wejściu do logów/metriców/trace’ów; biblioteki loggingu z domyślną redakcją pól wrażliwych. Krok 4: testy z danymi syntetycznymi, które zasiewają PII w stagingu i weryfikują, że nigdzie nie wypłyną do SIEM, APM ani konsoli.
Modele wykrywają wrażliwość nie tylko po wzorcu, ale po kontekście: jeśli hash klienta + timestamp + ID zamówienia tworzą quasi-identyfikator, reguła prywatności może go traktować jak PII w danej jurysdykcji. AI wyłapuje też „promieniowanie” PII — np. dopisywanie fragmentu numeru telefonu w wiadomościach o błędzie 422.
Typowy błąd: maskowanie tylko w sinku (log), a nie w źródle formatowania komunikatu. Wystarczy alternatywna ścieżka wyjątków albo biblioteka, która wypisuje cały obiekt, i redakcja przepada. Lepiej wymusić redakcję na typach domenowych (np. typ Email z metodą .redact()) i w policy middleware.
Co sprawdzić w tej sekcji
- Czy OpenAPI/IDL zawiera adnotacje wrażliwości i są one sprawdzane w CI?
- Czy loggery domyślnie maskują pola, a niemaskowane użycia łapią testy snapshot?
- Czy istnieje test end-to-end, który wstrzykuje PII i szuka go w każdym miejscu telemetry?
Automatyczne poprawki z modeli: kryteria zaufania i bezpieczne wdrożenie
Generatywne propozycje są przydatne, gdy spełnią obiektywne kryteria. Krok 1: patch minimalny w sensie AST (zmień tylko to, co konieczne: parametryzacja SQL, dołożenie sanitizer’a, wymiana funkcji RNG). Krok 2: walidacja kompilacji/typów i testów jednostkowych w odizolowanym środowisku. Krok 3: odtworzenie PoC w teście bezpieczeństwa, który przechodzi po poprawce i zawodzi przed nią. Krok 4: ocena skutków ubocznych (logika, wydajność) z krótkim benchmarkiem lub property-based tests.
Dobry patch zawiera uzasadnienie: powiązanie z CWE, wskazanie ścieżki dataflow i link do dokumentacji frameworka. Zły patch „zamyka” alert, ale zmienia semantykę (np. escapuje zbyt wcześnie i psuje encode/decode), albo dodaje sanitizer, który nie działa w danym kontekście (HTML vs URL). Modele potrafią również mitygować ryzyko migracji bibliotek (np. z request do fetch), generując adapter i testy zgodności.
Co sprawdzić w tej sekcji
- Czy patch jest minimalny i udowadnia skuteczność testem reprodukcyjnym?
- Czy narzędzie blokuje merge, jeśli poprawka obniża pokrycie krytycznego kodu?
- Czy opis commita zawiera kontekst (CWE, ścieżka, link do docs) potrzebny do code review?
CI/CD bez tarcia: gdzie uruchamiać analizy i jak filtrować wyniki
Zbyt agresywne bramki zniechęcają zespół, zbyt łagodne nie chronią. Spójny układ działa etapami:
Etapy i bramki decyzyjne
Krok 1: pre-commit i lokalny feedback. Lekkie reguły (sekrety, format, podstawowe SAST) działają lokalnie lub w pre-push i nie blokują pracy bez potrzeby. Modele uruchamiane w „trybie różnicy” analizują tylko zmienione pliki i ich sąsiedztwo w grafie wywołań. Błąd częsty: wymuszanie pełnej analizy repo w pre-commit — kończy się wyłączeniem hooków przez zespół.
Krok 2: analiza w PR. W CI uruchom SAST/SCA i testy generatywne na środowisku tymczasowym. Bramki opieraj na zasadzie „no new high+reachable”: alerty krytyczne osiągalne danymi użytkownika blokują merge, średnie wymagają akceptacji właściciela domeny z datą wygaśnięcia wyjątku. DAST odtwarza PR-owy podgląd aplikacji (ephemeral) i generuje fuzz testy ograniczone budżetem czasu.
Krok 3: skany pełne po merge do main. Nocą lub na tagu release uruchamiaj pełne SAST, IAST z testami integracyjnymi i skan obrazu kontenera. Modele agregują wyniki i otwierają bilety tylko dla nowych przyczyn źródłowych, a nie dla duplikatów w wielu miejscach.
Krok 4: przedprodukcyjne potwierdzenie ryzyka. Na stagingu modele odtwarzają udane PoC z PR oraz testują nagłówki, polityki CORS, CSP i konfiguracje WAF. Tu wychwytuje się luki konfiguracyjne, których nie widać w jednostkowych buildach.

Przykład praktyczny: pipeline PR (limit 8 minut) używa inkrementalnego indeksu AST i cache kompilacji. Gdy model oznacza XSS jako „reachable-high”, bramka żąda testu reprodukcyjnego i minimalnej poprawki; w przeciwnym razie alert trafia jako „warn” z przypisaniem do właściciela modułu.
Co sprawdzić w tej sekcji
- Jaki jest budżet czasu na analizę PR i czy narzędzie wspiera skan różnicowy z cache?
- Czy bramki opierają się na „osiągalności” i ekspozycji, a nie wyłącznie na surowej wadze?
- Czy wyjątki mają właściciela i TTL, a akceptacja ryzyka wymaga PoC lub uzasadnienia?
- Czy DAST uruchamia się w ephemeral env, a wyniki trafiają do jednej osi czasu w SARIF/JUnit?
Filtrowanie szumu i priorytetyzacja
Modele łączą cechy techniczne (sink, sanitization, kontrola wejścia) z kontekstem biznesowym (krytyczność usługi, ekspozycja na Internet), żeby przeliczyć alert na ryzyko. Grupowanie przyczyny źródłowej ogranicza lawinę powtórek: jedna niebezpieczna funkcja-helper budująca HTML generuje dziesiątki XSS — AI wskazuje jedno miejsce do naprawy i automatycznie zamyka pochodne alerty po wdrożeniu patcha. Deduplikacja używa ścieżek stosu i podobieństwa AST, a „drift detektor” podnosi priorytet, gdy zmienia się konfiguracja (np. wyłączono CSP).
Typowy błąd: sortować tylko po CVSS. W praktyce wyższy priorytet ma „średnie” RCE osiągalne publicznie z gotowym wektorem ataku niż „wysokie” w martwym kodzie panelu admina za VPN.
Co sprawdzić w tej sekcji
- Czy narzędzie grupuje alerty do wspólnej przyczyny i zamyka wtórne po naprawie?
- Czy scoring ryzyka bierze pod uwagę ekspozycję, właściciela domeny i dane produkcyjne (traces, ruch)?
- Czy sekret w kodzie natychmiast blokuje merge niezależnie od innych metryk?
Przepływ naprawy i ślad audytowy
Krok 1: przypisanie do właściciela modułu (CODEOWNERS, mikroserwis). Krok 2: wygenerowana poprawka z towarzyszącym testem reprodukcyjnym trafia do branch’a serwisowego. Krok 3: code review sprawdza minimalność zmiany i kontekst (CWE, dokumentacja). Krok 4: po merge model weryfikuje zanik alertu oraz brak regresji w metrykach wydajności.
Audyt wymaga pełnego łańcucha: od alertu, przez decyzję (zaakceptowano/naprawiono), po wynik testu. Wyjątki kadencjonowane (np. 30 dni) wymuszają powrót tematu — AI przypomina i proponuje alternatywne mitigacje (WAF, feature flag).
Co sprawdzić w tej sekcji
- Czy każdy alert ma właściciela i artefakt testowy dowodzący podatności?
- Czy „accepted risk” ma uzasadnienie, datę wygaśnięcia i jest widoczny w przeglądach bezpieczeństwa?
- Czy repozytorium przechowuje SARIF i logi IAST jako artefakty release’u?
Prywatność i zgodność w pracy modeli: architektura i procedury
Krok 1: wybór trybu uruchomienia. Wrażliwe repozytoria wymagają inferencji on-prem lub w strefie prywatnej chmury z wyłączonym treningiem na danych klientów. Jeśli korzystasz z SaaS, podpisz DPA z klauzulą no-train/no-retain oraz gwarancją lokalizacji danych.
Krok 2: sanitarna warstwa wejścia. Preflight skanuje i redaguje tajemnice oraz PII zanim trafią do modelu. Dołącz listy dozwolonych plików i rozszerzeń, a dla logów stosuj maskowanie w źródle. Modele otrzymują fragmenty kodu w segmentach kontrolowanych przez politykę (chunking z kontekstem, ale bez wylewania całego repo).
Krok 3: twarde prompty i ochrona przed wstrzyknięciami. Systemowe reguły blokują żądania „zapisz fragment pliku X” czy „wyślij dane do URL”. Komentarze w kodzie bywają nośnikiem prompt injection — warto je odfiltrować lub sprowadzić do białej listy tagów TODO/FIXME.
Krok 4: poufność wyników. Artefakty skanów, logi i przykładowe payloady PoC traktuj jako dane wrażliwe: szyfrowanie, ograniczenie dostępu, retencja w dniach, a nie w latach. W środowiskach o podwyższonej ochronie użyj TEE (np. SGX/SEV) lub separacji inferencji na dedykowanych węzłach.
Krok 5: zgodność i ślad decyzji. Dla GDPR/PHI prowadź rejestr czynności przetwarzania (ROPA), DPIA dla komponentów AI oraz mechanizm „prawo do bycia zapomnianym” dla repo w indeksach. Import danych produkcyjnych do analizy zawsze przez warstwę anonimizującą.
Antywzorzec: kopiowanie logów ze środowiska produkcyjnego z realnymi identyfikatorami do zewnętrznej konsoli LLM „na szybko”. Skutki widać dopiero przy audycie lub incydencie.
Reprezentacje semantyczne między językami: od AST do grafów przepływu
Krok 1: normalizacja kodu do wspólnego IR. Parser tworzy AST, dołącza tablicę symboli i rozwiązuje importy/moduły. W C/C++ włącza makra i flagi kompilatora, w JVM/Kotlin łączy typy z adnotacjami i generikami, a w JS/TS bierze pod uwagę transformacje bundlera. IR zawiera punkty wejścia, definicje typów i możliwe ścieżki wywołań.
Krok 2: budowa grafu właściwości kodu (Code Property Graph). Połączenie grafu składni (AST), grafu przepływu kontroli (CFG) i przepływu danych (DFG) pozwala modelowi śledzić dane od źródeł (request, pliki, deserializacja, kolejki) do zlewów (SQL, render, exec, sieć). Wersja SSA upraszcza rozumowanie o przypisaniach i mutacjach.
Krok 3: iniekcja wiedzy o frameworku i konfiguracji. Routery (Django/Spring/Express/FastAPI), middleware, rejestry beanów, kontenery DI, a także pliki konfiguracyjne (YAML/ENV) trafiają do grafu jako węzły sterujące i adnotacje bezpieczeństwa (np. @Validated, CSP, CORS). Model widzi realną ścieżkę: „parametr id → walidator → mapper → zapytanie”.
Przykład: w TypeScript routerze pole „search” przechodzi przez sanitizer HTML, ale inna gałąź dla „sort” już nie — DFG wskaże XSS tylko w tej ścieżce. W C++ customowy alokator z pulą pamięci zmienia semantykę free; bez włączenia flag kompilacji model pominie realny błąd podwójnego zwolnienia.
Co sprawdzić w tej sekcji
- Czy narzędzie rozumie build system i makra (Bazel/CMake/Gradle/Cargo) oraz dołącza flagi kompilatora?
- Czy graf obejmuje routing, DI, konfigurację i generowany kod (np. Lombok, codegen OpenAPI)?
- Czy analiza przepływu używa SSA/alias analysis dla języków z intensywną mutacją (C/C++/Rust unsafe)?
Różnice językowe: gdzie modele popełniają błędy, a gdzie zyskują przewagę
Pamięć i bezpieczeństwo niskopoziomowe
Krok 1: C/C++ — instrumentacja ASan/UBSan i model aliasów. Bez tego AI przeszacuje lub niedoszacowuje UAF i OOB. Krok 2: Rust — skupienie na granicach unsafe i FFI; modele traktują każdy blok unsafe jak „strefę wysokiego ryzyka” i proszą o dowody niezmienników. Krok 3: Go — błędy rzadziej dotyczą pamięci, częściej wyścigów i niejawnych konwersji bajtów/łańcuchów (UTF-8 vs ASCII) prowadzących do logicznych luk.
Typowy błąd: wnioskowanie o bezpieczeństwie Rust na podstawie „braku błędów kompilatora”, bez przejścia przez unsafe i połączenia C ABI.
Co sprawdzić
- Czy skany C/C++ uruchamiają się z sanitizers i pełnym zestawem flag docelowej platformy?
- Czy raport Rust wskazuje konkretne granice unsafe/FFI i dołącza testy właściwości?
Refleksja, metaprogramowanie i dynamiczne typy
Krok 1: JVM/.NET — mapowanie refleksji i deserializacji. Modele szukają łańcuchów gadżetów (Java deserialization, ObjectInputStream, Jackson default typing) i sprawdzają, czy klasy są faktycznie osiągalne z danych użytkownika. Krok 2: Python/PHP/Node — analiza trakcji łańcuchów formatowania, eval/exec, pickle/unserialize, prototypów i rozszerzeń obiektów. Krok 3: TypeScript — uwzględnianie wymazania typów w runtime; zabezpieczenia muszą być w kodzie, nie tylko w typach.
Przykład: w Node atak polega na zanieczyszczeniu prototypu przez merge z req.body; AI zaznacza, że pozorne „sprawdzenie hasOwnProperty” bez odcięcia __proto__ nie wystarcza. W Javie niebezpieczny enableDefaultTyping sygnalizuje RCE, ale tylko wtedy, gdy dane płyną z zewnątrz do ObjectMapper bez białej listy typów.
Co sprawdzić
- Czy skan refleksji obejmuje ścieżki ładowania klas i konfigurację serializacji (Jackson/Gson/XmlSerializer)?
- Czy w JS/TS narzędzie wykrywa prototyp pollution i automatycznie sugeruje bezpieczne merge’y/klonowanie?
Warstwa prezentacji i szablony
Krok 1: mapowanie kontekstu escapingu. Inny sanitizer dla HTML, a inny dla atrybutu, URL i JavaScript. Krok 2: rozpoznanie silników szablonów (Twig, Handlebars, Thymeleaf, Go templates) i ich domyślnych reguł. Krok 3: sprawdzenie ręcznego konkatenowania HTML/JS w helperach — to zwykle źródło lawiny XSS.
Antywzorzec: globalne „escape wszystko” łata objawy, psuje logikę encode/decode i generuje regresje UI.
Co sprawdzić
- Czy analiza rozróżnia konteksty (HTML/attr/URL/JS) i mapuje je na właściwe encodery?
- Czy helpery HTML mają testy snapshot i zakaz wstrzyknięć surowych fragmentów?
Śledzenie danych w architekturze polyglot: kontrakty, kolejki i magazyny
Krok 1: indeks kontraktów. OpenAPI/GraphQL/Protobuf/Avro trafiają do jednego rejestru ze stanem wersji. AI oznacza pola wrażliwe (PII/PHI/sekrety) oraz propaguje etykiety do struktur pochodnych (DTO, eventy). Krok 2: mapowanie mostków. Kolejki (Kafka/SQS), ETL i CDC są jawnie modelowane, a schematy z registry są obowiązujące — brak schematu traktowany jako ryzyko.
Krok 3: korelacja z transakcjami i śladem runtime. Traces i logi z identyfikatorami żądań łączą przepływ „frontend → gateway → mikroserwis A → kolejka → mikroserwis B → magazyn”. Model weryfikuje, czy maskowanie/haszowanie dzieje się przed zapisem i czy nie ma bocznych kanałów w logach.
Przykład z praktyki: adres e‑mail trafia z frontu (TS) do bramki (Go), a dalej do Javy zapisującej do magazynu analitycznego. Etykieta PII jest poprawnie zhashowana przed zapisem, lecz inny strumień zdarzeń debugujących zawiera surowe e‑maile — AI łączy oba przepływy i oznacza wyciek.
Co sprawdzić w tej sekcji
- Czy wszystkie kontrakty mają wersjonowanie i reguły kompatybilności (schema registry z walidacją w CI)?
- Czy PII-tagging propaguje się przez kolejki i ETL, a testy E2E wstrzykują dane kontrolne i szukają ich w downstream?
- Czy brak schematu lub fallback do „string any” blokuje merge do usług na styku z Internetem?
Fuzzing i testy właściwości wspierane modelami
Krok 1: generowanie korpusu wejść ze specyfikacji. OpenAPI, przykłady w README i logi z maskowaniem tworzą ziarna. Model dokańcza przypadki narożne (puste, Unicode, oversize, nietypowe kolejności pól). Krok 2: sterowanie pokryciem. Dla C/C++ — libFuzzer/AFL z ASan; JVM/.NET — Jazzer/SharpFuzz; Python/JS — Hypothesis/fast-check z hookami do pomiaru pokrycia.
Krok 3: minimalizacja i stabilizacja. Po znalezieniu krakera AI redukuje wejście do minimalnego i zapisuje test reprodukcyjny. Krok 4: sandbox i limity. Testy uruchamiane w izolacji z budżetem czasu na PR i pełnym fuzzingiem nocnym.
Przykład: dla parsera YAML w Pythonie model wygenerował ładunek, który wymusił ścieżkę przez yaml.load zamiast safe_load, wykazując niezamierzony import tagów — patch ograniczył dopuszczalne tagi i dodał test właściwości.
Co sprawdzić w tej sekcji
- Czy fuzzing jest zasilany realnymi kontraktami i ma budżet czasu per PR oraz tryb pełny nocny?
- Czy każdy krakujący przypadek trafia do repo jako test z minimalnym ładunkiem i etykietą ryzyka?
- Czy C/C++ mają włączone ASan/UBSan, a JVM/.NET — integrację z runnerami fuzz (Jazzer/SharpFuzz)?
Integracja z CI/CD i egzekwowanie polityk
Krok 1: pre-commit i pre-push. Krótkie skany lokalne (inkrementalne, na zmienionych plikach) wykrywają oczywiste luki, wycieki sekretów i błędy stylu bezpieczeństwa, zanim trafią do CI. Model pracuje na cache’owanych indeksach projektu i respektuje .gitignore oraz reguły wykluczania danych wrażliwych. Po stronie dewelopera liczy się szybkość i niska liczba fałszywych alarmów.
Krok 2: bramka w CI na PR. Pełna analiza na zreprodukowanym buildzie (te same flagi, generatory kodu, bundlery). Wyniki w formacie SARIF trafiają do narzędzi code review, a polityka „policy-as-code” (np. OPA/Rego) decyduje: informacja, ostrzeżenie czy blokada. W monorepo skan uruchamia się selektywnie na dotkniętych modułach i ich zależnościach, z wykrywaniem wpływu konfiguracji (ENV, YAML).
Krok 3: zarządzanie wyjątkami i automatyczne poprawki. Każde odstępstwo ma zakres, okres ważności i właściciela. Modele mogą tworzyć PR-y z poprawkami (np. usunięcie niebezpiecznego deserializera, dodanie walidatora), ale merge przechodzi dopiero po kompilacji, testach i reprodukcji ostrzeżenia. Reguły bezpiecznego „auto-merge” ogranicz do niskiego ryzyka i modułów o dobrym pokryciu testami.
Przykład z praktyki: w PR do usługi Go model wykrył niechroniony dostęp do pliku konfiguracyjnego przez ścieżkę względną. Bot zaproponował patch z whitelistem katalogu i testem właściwości. Blokada zdjęta po potwierdzeniu przez właściciela modułu i przejściu fuzzingu ścieżek.
Typowy błąd: włączanie blokad bez kalibracji bazowej. Efekt to lawina fałszywych alarmów i wyłączanie skanów po tygodniu. Najpierw tryb „shadow”, potem progi i dopiero twarde bramki.
Co sprawdzić
- Czy wyniki skanów są publikowane jako SARIF i komentowane bezpośrednio w diffie?
- Czy analiza w CI używa dokładnie tych samych flag kompilacji/bundlingu co produkcja?
- Czy wyjątki mają TTL i są przeglądane w sprintach bezpieczeństwa?
- Czy auto-fix przechodzi kompilację, testy jednostkowe i reprodukcję alertu przed merge?
Modele detekcji i ocena jakości: od promptów do weak supervision
Krok 1: źródła etykiet. Połącz CVE/CWE, historyczne błędy w repo (commity „fix”, PR-y z referencją do incydentów), sygnały z SAST/DAST oraz adnotacje z przeglądów kodu. To daje słabe etykiety (weak supervision), które model czyści przez deduplikację klonów i filtrację fałszywych korelacji. Podział train/test wykonuj po repozytoriach i w czasie (split temporalny), żeby uniknąć przecieku informacji.
Krok 2: reprezentacja i kontekst. Wejściem dla modelu nie jest sam tekst, lecz wycinek CPG/IR z oknem kontekstu obejmującym wywołania, konfigurację i kontrakty API. Detekcja może łączyć klasyfikator grafowy (znajduje przepływy ryzyka) z generatywnym modelem wyjaśniającym i sugerującym poprawkę. Dla projektów wielojęzycznych używaj wspólnego IR i adapterów językowych, zamiast trenować osobne modele bez wymiany wiedzy.

Krok 3: ewaluacja zorientowana na zespół. Precyzja/czułość to za mało. Liczą się: akceptacja PR-ów z poprawką, czas do naprawy, współczynnik regresji po deployu i odsetek alertów zamykanych jako „noise”. Wdrażaj model w trybie „shadow” w CI, porównuj z bazą (SAST + reguły), a dopiero potem podnoś progi blokad.
Przykład: po dodaniu kontekstu konfiguracji Jacksona (pliki YAML) wzrosła trafność detekcji niebezpiecznej deserializacji; wcześniej model oznaczał RCE nawet tam, gdzie obowiązywała biała lista typów.
Typowy błąd: trenowanie i test na tych samych rodzinach projektów (np. forkach), co zawyża wyniki. Drugi błąd to brak negatywnych przykładów „podobnych, ale bezpiecznych”, co prowadzi do sygnałów zbyt ogólnych.
Co sprawdzić
- Czy zestaw danych ma split po repo i czasie oraz deduplikację klonów?
- Czy model widzi CPG/IR i konfigurację, a nie tylko surowy tekst plików?
- Czy metryki obejmują akceptację poprawek i czas do naprawy, nie tylko precision/recall?
- Czy jest tryb „shadow” w CI do kalibracji progów?
Automatyczne poprawki i weryfikacja: od sugestii do bezpiecznego merge’a
Krok 1: minimalny patch i dowód bezpieczeństwa. Model generuje poprawkę ograniczoną do jednej odpowiedzialności: zamiana konkatenacji SQL na zapytanie parametryzowane, dodanie walidatora do DTO, wymiana niebezpiecznego parsera na bezpieczny odpowiednik. Do PR dołącza krótkie uzasadnienie, ścieżkę danych (źródło → zlew) oraz test reprodukcyjny.
Krok 2: walidacja wielowarstwowa. Kompilacja/lint, testy jednostkowe i właściwościowe, reprodukcja alertu (przed/po), a dla C/C++ — uruchomienie z ASan/UBSan. Dla usług sieciowych — testy kontraktowe (OpenAPI/GraphQL) i szybki fuzz z ziaren. Jeśli poprawka dotyka konfiguracji lub szablonów, generuj snapshoty UI i porównuj konteksty escapingu.
Krok 3: bezpieczne wdrożenie. Feature flag/canary, monitoring regresji (błędy, latencja, wskaźniki biznesowe), automatyczne wycofanie po przekroczeniu progów. Dla poprawek dotykających polityk CORS/CSP — walidacja nagłówków w środowisku staging i smoke test przeglądarkowy.
Przykład: w Node.js model zamienił ręczny escape HTML na sanitarz oparty o DOMPurify z właściwą konfiguracją dla atrybutów. Do PR dodał testy snapshot i przypadek XSS z atrybutem onerror, co zapobiegło cichej regresji w innej gałęzi renderowania.
Antywzorzec: „globalne search&replace” bez uwzględnienia kontekstu. Ten sam sanitizer nie zadziała identycznie w HTML, atrybucie i URL; poprawka musi respektować kontekst wykryty w analizie.
Co sprawdzić
- Czy każdy auto-patch ma test reprodukcyjny i opis ścieżki danych?
- Czy pipeline waliduje poprawkę pod kątem wydajności i semantyki (brak niezamierzonych zmian)?
- Czy rollout używa canary/feature flag i ma progi automatycznego wycofania?






