Upss… Coś nie tak z Twoją przeglądarką
Do poprawnego wyświetlania formularza zalecana jest przeglądarka Chrome lub Safari.

Monitorowanie nowych wersji zależności projektowych i automatyzacja ich aktualizacji

Automatyzacja to temat, który obecnie odmieniany jest przez wszystkie przypadki. I ciężko się temu dziwić. Liczba procesów zachodzących w różnych projektach stale rośnie, dlatego dzisiaj, na przykładzie firmy Comarch postaram się przybliżyć podejście stosowane dla ciągłego monitorowania nowych wersji zależności projektowych i automatyzacji ich aktualizacji.

Problematyka

Każdy produkt, który wykorzystuje starsze wersje bibliotek, czy komponentów jest narażony na zjawisko potocznie zwane „długiem technologicznym”. Jego pojawienie się może skutkować nie tylko dużą refaktoryzacją kodu i zwiększeniem kosztów wprowadzenia nowych funkcjonalności do produktu, ale także występowaniem podatności w tych bibliotekach.

Część z Was na pewno wie, do czego mogą doprowadzić podatne biblioteki, chociażby na przykładzie tej samej podatności CVE-2021-44832 w log4j.

Śledzenie wersji bibliotek i komponentów

W rzeczywistości, kiedy pracujemy nad rozwojem małego pet-project, czy też małej aplikacji, zarządzanie wersjami bibliotek nie wygląda na skomplikowaną sprawę. Wystarczy spojrzeć w plik z zależnościami naszego projektu np. package.json dla projektów na stosie technologicznym JS, czy requirments.txt dla projektów napisanych w Python. Warto też zauważyć, że podatności mogą pojawić się nie tylko w bezpośrednich zależnościach projektowych, ale też w zależnościach naszych paczek - prawie każda takie ma.

W przypadku pracy przy większym projekcie, który ma sporo zależności takich jak biblioteki frontendowe, third party componenty typu ElasticSearch, Kafka, Postgres itd. sprawa mocno się komplikuje. Czas sprawdzania, które musi być wykonywane dość często, jest duży, a na samym sprawdzeniu sprawa niestety się nie kończy. Na koniec bowiem musimy jeszcze wykonać samo podniesienie wersji.

Nie pomaga nam również fakt, że często programiści zaangażowani są w wiele projektów, w których wykonują te same, lub zbliżone działania – różnice zależą od wykorzystywanego stosu technologicznego. Oczywiście na rynku dostępne są narzędzia takie jak npm list, czy też mvn dependency:tree, których zdaniem jest ułatwienie nam codziennej pracy. Nie zwalniają nas one jednak od stworzenia i utrzymywania tzw. listy zależności (czy też dependency graph). Jak widać, podejście manualne do rozwiązania tego typu problemu wcale nie jest proste i mocno obciąża programistów, czasochłonnym i często powtarzającym się procesem.

Dlatego nie tak dawno temu postanowiliśmy ułatwić prace naszym programistom, tym samym polepszając jakość naszego oprogramowania i całkiem zautomatyzować tego typu działania. Nie tylko od strony ciągłego śledzenia nowych wersji, ale też i od strony podnoszenia ich.

I tutaj w wielu głowach pojawia się pytanie. Czy utrzymywanie oprogramowania w najnowszych wersjach wyeliminowuje ryzyko związane z podatnościami w produkcie?

Same w sobie aktualizacje bibliotek nie eliminują całościowo wszystkich możliwych podatności, chociażby z powodów błędów programisty czy też ew. pojawienia się podatności typu 0-day, nad którymi niestety nikt nie ma władzy. Poza tym utrzymanie oprogramowania up-to-date pozwala maksymalnie wyeliminować - na ile jest to możliwe - sytuacje, w których produkt jest zagrożony ze strony bezpieczeństwa z powodów twórców bibliotek, czy komponentów, użytych w naszym projekcie.

Jak rozwiązaliśmy ten problem w Comarch?

Jakiś czas temu w naszym sektorze (Telekomunikacja) wdrożyliśmy narzędzie, które rozwiązuje wszystkie ww. problemy.

Zaletą tego narzędzia jest to, że oprócz ciągłego śledzenia dostępnych nowych wersji, ma także potężne API, które dodatkowo pozwala na zaaplikowanie wykrytych wersji (czytaj podniesienie wersji) w sposób w pełni automatyczny, gdzie developerowi zostaje jedynie zaakceptować stworzony przez narzędzie PR/MR request.

Ogólnym celem tego narzędzia jest ułatwienie czasochłonnego procesu podniesienia wersji w naszych produktach, a co za tym idzie znaczna redukcja wektora ew. ataku na oprogramowania za pośrednictwem podatnych bibliotek. Dodatkowo, co jest z naszej perspektywy bardzo istotne, możemy wyeliminować powstanie tzw. długu technologicznego, ponieważ system informuje nas o konieczności podniesienia wersji. Tym samym narzędzie wymusza na nas sprawdzenie zmian API w nowych wersjach biblioteki/komponentu i ewentualne zareagowanie w sposób dostosowania kodu naszych aplikacji do zmian typu breaking changes.

Sposób działania narzędzia

W naszym rozwiązaniu zastosowaliśmy tzw. managery, które odpowiadają za znalezienie i wyciągnięcie informacji na temat tego, co ma być zaktualizowane. Narzędzie działa w postaci bot-a, który czy to w określonym czasie, czy też na bieżąco, śledzi pojawienie się nowych wersji i triger-uje stworzenie MR, kiedy znajdzie nowszą wersję.

Stworzony przez narzędzie Merge request, oprócz samych zmian w plikach z zależnościami zawiera też streszczoną informacje o zaaplikowanych zmianach w postaci tzw. Dashbord-u. Znajdą się tam informacje takie jak:

  • Release Notes do zaktualizowanego oprogramowania
  • Data wydania nowej wersji
  • Confidence level:
    • Adoption – ile osób zaaplikowało tę zmianę wersji
    • Passing – wynik ich testów funkcjonalnych po podniesieniu wersji
    • Confidence rate, który jest obliczany z powyższych dwóch metryk i przedstawia, na ile „bezpieczna jest ta zmiana”

Oczywistym pytaniem będzie: skąd narzędzie posiada informacje wyświetlone w Confidence level? Już wyjaśniam. Narzędzie w sposób anonimowy zbiera dane od innych użytkowników o wynikach ich testów. Nie ma informacji, jakie to były testy. Interesuje jego jedynie fakt, jaki procent testów przeszedł.

Czy takie narzędzie można wdrożyć do każdego projekt?

I tak i nie. Automatyzacja procesu podniesienia wersji sama w sobie jest sporym ułatwieniem, oraz pozwala developerom zaoszczędzić sporo czasu. Jednak z drugiej strony, automatyzacja wymaga od projektu pewnej dojrzałości w postaci obecności różnego rodzaju testów (jednostkowych, E2E i innych). Ma to na celu uniknięcie sytuacji, w której takie podniesienie zepsuje działanie aplikacji z powodu np. zmian na funkcjonalnościach, z których korzysta aplikacja (breaking changes).

Patrząc przez pryzmat faktu, że produkty Comarch mają dość zróżnicowany stos technologiczny, dla nas kluczowe było wsparcie różnego rodzaju języków programowania i framework-ów. W obecnej chwili narzędzie świetnie sobie radzi z większością popularnych technologii i języków programowania np.: Java, Dotnet, JS, Python, Rust, Elixir, i wiele innych. Oprócz pielęgnacji wersji bibliotek użytych w projekcie, narzędzie pozwala też na obsługę dużych komponentów third-party np.: ElasticSearch, Kafka, Postgres czy też innych, które są zależnościami, na których opierają się główne funkcjonalności aplikacji. Dodatkowo mamy możliwość obsługi podniesienia wersji obrazów docker-owych, jak i gotowych.

Ogromną zaletą jest także wsparcie helm chart oraz Infrastructure as Code. Przy odpowiednim stosowaniu podejścia GitOps jesteśmy w stanie zautomatyzować nie tylko zarządzanie infrastrukturą, ale też za pomocą tego narzędzia możemy usprawnić aktualizacje infrastruktury/dużych komponentów, których wersje znajdują się w naszych chartach.

Podsumowanie

Na koniec chciałbym podkreślić, że automatyzacja zarządzania wersjami oprogramowania użytego w produkcie znacznie oszczędza czas, zarówno programistów, jak i DevOps-ów. Pozwala skupić się nad bieżącymi pracami, ogranicza stres związany z koniecznością aktualizacji z ich strony, oraz znacznie polepsza jakość wytwarzanego produktu.

Jeżeli ktoś z Was chciałbym pracować z tego typu narzędziami, zachęcam do dołączenia do naszego zespołu. Realizujemy zagadnienia związane z bezpieczeństwem IT oraz automatyzacją procesów. Obecnie poszukujemy analityków bezpieczeństwa/pentesterów oraz inżynierów systemowych/DevOps/DevSecOps. Obsługujemy wiele projektów i mamy różnorodny stos technologiczny, więc na pewno znajdziecie coś, co wam się spodoba.

Dodaj komentarz

      adres e-mail nie zostanie opublikowany

            Najczęściej czytane w tej kategorii