Przejdź do głównej zawartości

Bezpieczeństwo i utrzymanie narzędzia do backportowania

Narzędzie do kompilacji — NIE zależność wykonawcza. Ta strona wyjaśnia, jak prowadzić proces kompilacji i na jakiej podstawie mu ufać. Stan bezpieczeństwa samego silnika formatu Portable Document Format (PDF) jest udokumentowany razem z silnikiem, a nie tutaj.

Narzędzie do kompilacji przekształca źródło, którego samo nie tworzy, i wytwarza dystrybucję, nad którą nie prowadzi prac rozwojowych. Jego model bezpieczeństwa wynika z tej granicy. Granicę zaufania wyznaczają pobrane źródło oraz łańcuch narzędzi. Wytworzony artefakt jest tylko do odczytu i powstaje maszynowo. Podział licencji między pakietem publicznym a pakietem Pro jest ustalony w kodzie.

Narzędzie do kompilacji przyjmuje jako dane wejściowe repozytoria źródłowe oraz przypięty łańcuch narzędzi. Wytwarza artefakt pochodny. Wynikają z tego trzy właściwości:

  • Wygenerowana dystrybucja jest tylko do odczytu i powstaje maszynowo. Jest publikowana pod tagami wersji, a nie jako gałęzie tego repozytorium. Prace rozwojowe, zgłoszenia błędów i prośby o funkcje trafiają do oryginalnych repozytoriów źródłowych nextpdf/*, nigdy do wygenerowanego drzewa. Zweryfikowano na podstawie bloku ostrzegawczego w pliku README.md projektu oraz .github/workflows/build.yml (wydanie zatwierdza i taguje wygenerowane drzewo od zera).
  • Zakres tokenu wydania jest wąski. secrets.BACKPORT_TRIGGER_TOKEN autoryzuje klonowanie repozytoriów źródłowych z tagu wydania. Jest używany wyłącznie w krokach pobierania źródła. Zweryfikowano na podstawie build.yml (użycie GH_TOKEN).
  • Podział runnerów ciągłej integracji (CI) jest zamierzony. Zaufane zdarzenia są uruchamiane na własnych runnerach PHP; pull requesty z forków i przebiegi Dependabota są wymuszane na runnerach hostowanych przez GitHub. Niezaufany kod nigdy nie wykonuje się w zaufanej puli runnerów. Zweryfikowano na podstawie .github/workflows/0-ci.yml (warunek runs-on).
  • Łańcuch narzędzi jest ograniczony w pliku composer.json. Wykorzystuje Rector ^2.0, PHPStan ^2.1, PHPUnit ^13.0 oraz zestaw symfony/polyfill-*. Narzędzie do kompilacji nie ma zależności wykonawczej od NextPDF, więc skompromitowany pakiet wykonawczy NextPDF nie może oddziaływać na narzędzie. Zweryfikowano na podstawie composer.json.
  • Aktualizacje zależności są sterowane botem i poddawane kontroli. Repozytorium zawiera konfigurację Dependabota oraz przepływ pracy automatycznego scalania. Przebiegi Dependabota są przypięte do runnerów hostowanych przez GitHub i przed scaleniem nadal przechodzą przez pełną bramkę CI (PHPStan, testy, próbny przebieg). Zweryfikowano na podstawie .github/dependabot.yml oraz .github/workflows/0-ci.yml, 9-dependabot-auto-merge.yml.
  • Wynik nie obejmuje stanu kompilacji. Archiwum wydania jest pakowane jako zip z wykluczeniem vendor/ i .git/. Opublikowany artefakt zawiera źródło i wygenerowany manifest, a nie własne drzewo zależności narzędzia do kompilacji. Zweryfikowano na podstawie build.yml (zip ... -x '*/vendor/*' '*/.git/*').
  • Analiza statyczna obejmuje kod kompilacji. composer analyse uruchamia PHPStan na poziomie 10 dla rector/rules i scripts przy każdym pushu i pull requeście do dowolnej z trwałych gałęzi. Uruchamia się przed jakimkolwiek próbnym przebiegiem. Zweryfikowano na podstawie composer.json oraz 0-ci.yml.

Skrypt kompilacji nie sprawdza składni wyniku lokalnie, ponieważ host kompilacji uruchamia nowsze PHP niż docelowe. Miarodajna bramka znajduje się w przepływie pracy wydania. Po kompilacji runner przełącza się na docelowe PHP i uruchamia php -l dla output/src, przerywając wydanie przy dowolnym błędzie parsowania lub błędzie krytycznym. Artefakt jest następnie instalowany i sprawdzany w macierzy walidacji — PHP od 8.1 do 8.4 dla toru PHP 8.1 oraz PHP 7.4 i 8.0 dla toru PHP 7.4. Dystrybucja, którą odrzuciłoby docelowe środowisko wykonawcze, nie trafia do wydania. Zweryfikowano na podstawie scripts/build.php (validateOutput()) oraz .github/workflows/build.yml (zadania sprawdzania składni i validate-*).

Jest to gwarancja oparta na zaobserwowanym zachowaniu, ograniczona do środowisk wykonawczych sprawdzanych przez proces. Nie jest to certyfikacja zgodności. Nie potwierdza poprawności przekształconego programu poza akceptacją składni i własnym zestawem testów projektu.

Dwa wytwarzane pakiety mają różne licencje, ustalane w pliku scripts/adjust-composer.php:

PakietPole licencjiUstawiane przez
nextpdf/backportApache-2.0generatePublicComposer()
nextpdf/backport-proproprietarygenerateProComposer()

Samo repozytorium narzędzia do kompilacji jest na licencji Apache-2.0 (composer.jsonlicense). Jego CHANGELOG.md odnotowuje wcześniejszą zmianę licencji z LGPL-3.0-or-later na Apache-2.0. Wersje opublikowane przed tą zmianą pozostają na starszej licencji i nadal są dostępne do pobrania, natomiast każda nowa wersja jest na licencji Apache-2.0. Dystrybucja Pro jest zastrzeżona, powstaje wyłącznie dla docelowego PHP 8.1 i wymaga phpseclib/phpseclib ^3.0. Zweryfikowano na podstawie CHANGELOG.md, composer.json oraz scripts/adjust-composer.php.

Co proces gwarantuje w zakresie wymuszanym przez kod:

  • Zatrzymanie przy pierwszym niepowodzeniu. Kompilacja jest przerywana na pierwszym nieudanym etapie ze wskazaniem błędu. Częściowa dystrybucja nigdy nie zostaje wydana, ponieważ zadania wydania zależą od pomyślnej kompilacji i walidacji. Zweryfikowano na podstawie scripts/build.php (step()) oraz pola needs zadania w build.yml.
  • Szeregowanie kompilacji. Grupa współbieżności backport-build z cancel-in-progress: false zapobiega wyścigowi dwóch wydań źródłowych o ten sam tag wydania. Zweryfikowano na podstawie build.yml.
  • Odtwarzalne dane wejściowe. Proces klonuje każde repozytorium źródłowe dokładnie przy tagu wydania przed kompilacją. Zweryfikowano na podstawie build.yml (--branch "${TAG}").

Czego proces nie deklaruje:

  • Nie certyfikuje zgodności ze standardami, pełnej kompatybilności z wersjami PHP ani poprawności przekształconego programu poza akceptacją składni i zestawem testów.
  • Obniżenie wersji usuwa niezmienność wymuszaną w czasie wykonania (usunięcie readonly). Kod, który polegał na tym, że środowisko wykonawcze odrzuci zapis do właściwości readonly, traci tę ochronę w wyniku obniżenia wersji. Jest to udokumentowany, celowy kompromis na rzecz bezpieczeństwa klonowania z modyfikacją — zob. /integrations/backport/troubleshooting/.

Problemy z bezpieczeństwem narzędzia do kompilacji rozwiązuje się zgodnie z plikiem SECURITY.md repozytorium: zgłaszaj je poprzez GitHub Security Advisory lub kontakt ds. bezpieczeństwa, a nie jako publiczne zgłoszenie. Problemy w wygenerowanym kodzie zgłaszaj w oryginalnych repozytoriach źródłowych, ponieważ wygenerowane drzewo powstaje maszynowo i nie prowadzi się nad nim prac rozwojowych. Zweryfikowano na podstawie SECURITY.md oraz README.md projektu.

  • /integrations/backport/overview/ — czym jest narzędzie do kompilacji i co wytwarza.
  • /integrations/backport/production-usage/ — jak prowadzić proces wydawania.