Composer. Небезопасно использовать packagist и приватный источник пакетов одновременно

    image
    Уже было нечто подобное. Хотя это поведение багом не было, но его исправили. Дело было в том, что composer мог установить не тот пакет, который указан в composer.json, а замещающий его: Composer: Replace, Conflict & Forks Explained, Composer: Downloading Random Code Is Not A Security Vulnerability?. Но осталось другое поведение. Оно очевидно, но, как мне кажется, обделено вниманием.

    Composer стремится установить более свежую версию пакета. И ему не важно где он найдёт этот пакет, в приватном источнике пакетов или на packagist.

    Таким образом, если используются packagist и приватный источник пакетов одновременно, то существует вероятность того, что приватный пакет будет заменен на другой из packagist (если у них совпадут имена и, например, версии). Таким образом существует вероятность того, что пакет может быть(если учесть закон Мерфи, то будет) преднамернно подменён злоумышленником.

    Вывод: Небезопасно использовать packagist и приватный источник пакетов одновременно.

    Если ничего не используется с packagist, то его можно просто отключить. Если нужны и те, и те пакеты, то желательно создать свою экосистему используя satis или что-нибудь подобное.

    А ещё можно на packagist создать пустой пакет, чтобы никто не смог заменить ваш, но это не согласуется с основной идей packagist.

    #3509

    P.S. Воспроизводится просто. Достаточно создать на github репозиторий с compser.json c одним коммитом и тэгом, который будет выше или равен версии вашего приватного пакета. Потом добавить его на packagist.org. После этого обновиться и получить пакет с packagist, а не с приватного репозитория. Пример такого пакета..

    Сценарий для воспроизведения
    mkdir /tmp/test
    cd /tmp/test
    curl -sS https://getcomposer.org/installer | php
    mkdir ./substitute_private
    cd ./substitute_private
    echo '{"name": "my_substitute/my_substitute", "type": "library", "description": "substitute_private", "license": "LGPL-3.0+"}' > ./composer.json;
    git init
    git add .
    git commit -m 'initial commit'
    git tag '0.0.0'
    cd ..
    mkdir ./application
    cd ./application
    echo '{
        "name": "my_application/my_application",
        "type": "application",
        "description": "Система управления лицевыми счетами",
        "keywords": [],
        "license": "LGPL-3.0+",
        "repositories": [
            {"packagist": false},
            {"type": "git",
            "url": "../substitute_private"}],
        "require":{
            "my_substitute/my_substitute": "~0.0"
        }
    }' > composer.json
    ../composer.phar install
    ../composer.phar update
    
    echo '------------> updated from(without packagist)'
    git --git-dir=./vendor/my_substitute/my_substitute/.git config --get remote.composer.url
    
    echo '{
        "name": "my_application/my_application",
        "type": "application",
        "description": "Система управления лицевыми счетами",
        "keywords": [],
        "license": "LGPL-3.0+",
        "repositories": [
            {"type": "git",
            "url": "../substitute_private"}],
        "require":{
            "my_substitute/my_substitute": "~0.0"
        }
    }' > composer.json
    ../composer.phar update
    echo '------------> updated from(with packagist)'
    git --git-dir=./vendor/my_substitute/my_substitute/.git config --get remote.composer.url
    


    P.P.S. В документации сказано, что пакеты из собственных репозиториев имеют приоритет перед пакетами packagist, но это правда только когда в качестве версии указана ветка('dev-master'), а не номер версии(0.0.0).

    P.P.P.S. Поведение изменили. Теперь репозитории имеют приоритет и packagist последний. github.com/composer/composer/pull/3982

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 5

      0
      И composer не представляет никакой опции дающей приоритет приватным репозиториям?
        0
        Нет, список репозиториев и список необходимых пакетов не зависят друг от друга.
          0
          Исправляюсь. Приватные репозитории будут иметь приоритет когда мы указываем в качестве версии ветку, а не номер версии.
          +1
          Когда ставите пакеты (команда) install composer ставит то что написано в composer.lock
          Когда вы делаете update то можно просто посмотреть глазами на то, что скачалось (на тот же .lock), зачем тут делать satis?
          Ну и composer стермится поставить максимальную ту версию которая подходит под зависимости которые вы или составители пакетов указали, всегда можно указать конкретную версии или коммит в composer.json

          Ну и хоть какие-то примеры можете привести (composer.json, форкните репозиторий который вы импортируете и пропишите вместо своего приватного, чтобы можно было просто запустить composer update и увидеть это поведение)? Создать пакет с другим именем и указать у него replace пробовали?
            0
            Да, лучше лишний раз посмотреть в composer.lock, чтобы убедиться, что всё установилось откуда надо. Но тут есть два но. 1. Если появится пакет, который будет подменять Ваш, то Вам придётся после каждого update редактировать composer.lock вручную. 2. Пакет может содержать скрипты, которые будут выполнятся от лица пользователя во время обновления.

            Воспроизводится легко. Обновлю в посте.

            Replace теперь работает по-другому. Раньше, если require пакет начинал конфликтовать с другими, то мог установиться другой пакет.

          Only users with full accounts can post comments. Log in, please.