Je čas vyvíjet a čas udržovat, a tak i v životním cyklu našich projektů přichází moment, kdy jejich vývoj aktivně neprobíhá a kdy se naše pozornost zaměří jiným směrem („Nový projekt, hurá!“)... A my skoro až zapomeneme, že nějaký projekt kdy existoval.

Pokud jde o nějaký interní tooling, nemusí to být špatně. Jde-li ale o veřejnou stránku, veřejné API či jinde používanou knihovnu, je naše zapomenutí problém.

Proč? Každý projekt je vybudován na ramenou obrů, ve světě software jsou těmito rameny používané knihovny. Můžeme psát jakkoliv bezpečné aplikace, ale když někdo najde slabé místo obra, naše akrobatická konstrukce hrozí nejen metaforickým zřícením.

Jak takový problém řešit? Pravidelným auditem všech závislostí. Slovo audit vás možná odrazuje, ale ve skutečnosti to není tak hrozivé, jak to zní, protože používáte-li composer (jako my), máte z poloviny vyhráno. Zkuste si v takovém projektu pustit následující:

composer outdated --strict --minor-only

Výstupem může být něco takového:

roave/security-advisories   dev-master         dev-master 74a42b8 Prevents installation of composer packages with known security vulnerabilities: no API, simply require it
symfony/console             v3.4.17            v3.4.18            Symfony Console Component
symfony/debug               v3.4.17            v3.4.18            Symfony Debug Component
symfony/polyfill-ctype      v1.9.0             v1.10.0            Symfony polyfill for ctype functions
symfony/polyfill-mbstring   v1.9.0             v1.10.0            Symfony polyfill for the Mbstring extension
symfony/yaml                v3.4.17            v3.4.18            Symfony Yaml Component
tracy/tracy                 v2.5.3             v2.5.5             😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will...

To nám ukazuje, že naše závislosti nejsou tak úplně aktuální, a chtělo by to pustit composer update (což provede aktualizace dle vašich omezení).

Dělat toto ručně by ale byla otrava, a jak praví programátorská moudrost, automatizujte. U nás pro tyto účely používáme GitLab CI, takže stačí přidat do .gitlab-ci.yml následující kód a nastavit spouštění v GitLab -> Projekt -> CI/CD -> Schedules.

dependencies_monitoring:
  only:
    - schedules
  image: phpdocker/phpdocker:7.1
  stage: test
  script:
    - composer install --no-progress
    - composer outdated --minor-only --strict
  tags:
    - docker

Pár vysvětlení:

  • GitLab CI spouští postupně všechny skripty, pokud nějaký selže, dojde k selhání úkolu, další skripty nejsou prováděny.
  • Příznak --minor-only používáme, protože nás zajímají jen bezpečné aktualizace a setinkové verze (opravy chyb).
  • Příznak --strict způsobí, že příkaz vrací návratovou hodnotu úspěch (nic k aktualizaci), nebo neúspěch (něco k aktualizaci existuje).

Že nemáte GitLab? Špatná výmluva, CRON máte určitě ;-)

Jak často kontrolu spouštět? To je otázka, která se čas od času vynoří... Správnou odpověď nemáme, ale důvody, které nás dovedly k týdenní periodě, jsou následující:

  • Když se to bude odkládat, bude tam víc změn a míň se nám do toho bude chtít... A také zde bude větší šance, že se něco přeci jen pokazí. Sémantické verzování je fajn, ale občas prostě někdo udělá chybu.
  • Když to bude příliš často, bude nás to otravovat a je možné, že to začneme ignorovat.
  • Když to zapojíme před merge (namísto periodické úlohy), tak nás to bude štvát a potenciálně to zbytečně bude dávat do repozitáře nesouvisející změny.

Co jde dělat víc?

PHP závislosti přes Composer nejsou jediné závislosti, na kterých naše projekty stojí (resp. mohou stát):

  • npm: zde se věnujte npm audit příkazu dostupnému od verze 6.
  • bower: je postupně opouštěn, nástroje existují (například bower-outdated, ten se nám ale nepodařilo nakonfigurovat podle našich představ).
  • yarn: zde též yarn outdated (viz dokumentace), nemáme s nimi však zkušenost, protože yarn zatím nepoužíváme.

Jde kontrolovat knihovny na nahlášené zranitelnosti (CVE...) pomocí nástroje Security-checker. Ideálně ho zapojte hned po composer install, ať se o případných zranitelnostech dozvíte, i když máte něco neaktuálního:

  script:
    - php external/backend/bin/security-checker security:check composer.lock

A pak tu je Roave\SecurityAdvisories composer závislost, která nastavuje nebezpečné balíčky jako konfliktní (instalaci nepovolí), přičemž zdrojem je stejná databáze jako výše zmíněný Security-checker.

Tímto monitoringem přidáváme další kousek skládačky do celkového boje za aktualizované a bezpečné aplikace. Je toho spousta k vylepšení, ale o tom zase někdy příště.