Php composer.lock如何保护您的恶意依赖项目

Php composer.lock如何保护您的恶意依赖项目,php,composer-php,git-tag,Php,Composer Php,Git Tag,在我的项目中,我在github上签入composer.lock文件。 假设我在composer.json中需要一个健康的依赖项,如: "require": { "foo/bar": "v3.0" }, 调用composer install后,将创建一个composer.lock文件 "packages": [ { "name": "foo/bar", "version": "v3.0", "so

在我的项目中,我在github上签入composer.lock文件。 假设我在composer.json中需要一个健康的依赖项,如:

"require": {
    "foo/bar": "v3.0"
  },
调用composer install后,将创建一个composer.lock文件

"packages": [
        {
            "name": "foo/bar",
            "version": "v3.0",
            "source": {
                "type": "git",
                "url": "https://github.com/foo/bar.git",
                "reference": "bbafb0edb791b23220563d113d00371ea42aedaa"
            },
            "type": "project",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Mr.Foo",
                    "email": "mr.foo@bar.de"
                }
            ],
            "time": "2019-09-30T12:13:55+00:00"
        }
假设拥有foo/bar存储库的攻击者会删除v3.0标记。攻击者将命名一个不同的对v3.0的提交。 是否有人可以确认composer install将始终检查composer.lock安装依赖项? 如果运行编写器安装而不运行编写器,则文件编写器将使用新引用(提交id)创建一个新的.lock文件。如果我使用composer.lock运行composer安装,文件编写器将坚持提交id(“参考”:“BBAFB0EDB791B2320563D113D00371EA42AEDAA”,旧版本3.0)。Composer不会加载恶意的伪v3.0。v3.0指向github上的新提交id

有人能确认composer.lock的reference标记比version标记具有“更高的优先级”吗?composer是否能完全保护我的项目免受此类攻击?

TL;博士 当然,你的问题的答案是:

是的,作曲家会保护你的

要么它将根据您的
composer.lock
中声明的提交散列来安装包,如果它存在于存储库中,只需忽略提交和版本之间的不匹配,要么它将失败,并给出一个非常直接的原因:“历史被重写了?”


这个问题确实激起了我的好奇心:我会说是的,因为否则,在锁文件中锁定提交散列将毫无用处,但为了正确性,我不得不测试它

以下是我所做的:

  • 有一种“明显”的情况,攻击者会重写历史记录并删除标记与您的
    composer.json
    约束匹配的提交
  • 再想一想,攻击者还会保留标记为约束的提交,但会添加新的提交,并使用与约束匹配的标记重新标记新的提交

  • 第一种情况: 我将一个基本软件包安装到某个特定版本(不是最新版本,只是为了有版本限制):

    这让我最终得到了一个非常简单的
    composer.json

    {
        "require": {
            "psr/log": "1.0.0"
        }
    }
    
    这个
    composer.lock

    {
        "_readme": [
            "This file locks the dependencies of your project to a known state",
            "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
            "This file is @generated automatically"
        ],
        "content-hash": "2865f724e23cffb23b3afd3a968e0359",
        "packages": [
            {
                "name": "psr/log",
                "version": "1.0.0",
                "source": {
                    "type": "git",
                    "url": "https://github.com/php-fig/log.git",
                    "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
                },
                "dist": {
                    "type": "zip",
                    "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
                    "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
                    "shasum": ""
                },
                "type": "library",
                "autoload": {
                    "psr-0": {
                        "Psr\\Log\\": ""
                    }
                },
                "notification-url": "https://packagist.org/downloads/",
                "license": [
                    "MIT"
                ],
                "authors": [
                    {
                        "name": "PHP-FIG",
                        "homepage": "http://www.php-fig.org/"
                    }
                ],
                "description": "Common interface for logging libraries",
                "keywords": [
                    "log",
                    "psr",
                    "psr-3"
                ],
                "time": "2012-12-21T11:40:51+00:00"
            }
        ],
        "packages-dev": [],
        "aliases": [],
        "minimum-stability": "stable",
        "stability-flags": [],
        "prefer-stable": false,
        "prefer-lowest": false,
        "platform": [],
        "platform-dev": []
    }
    
    {
        "_readme": [
            "This file locks the dependencies of your project to a known state",
            "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
            "This file is @generated automatically"
        ],
        "content-hash": "2865f724e23cffb23b3afd3a968e0359",
        "packages": [
            {
                "name": "psr/log",
                "version": "1.0.0",
                "source": {
                    "type": "git",
                    "url": "https://github.com/php-fig/log.git",
                    "reference": "a7ab552fdb2efb80aeca09da3bbd9335fc945ff0"
                },
                "dist": {
                    "type": "zip",
                    "url": "https://api.github.com/repos/php-fig/log/zipball/a7ab552fdb2efb80aeca09da3bbd9335fc945ff0",
                    "reference": "a7ab552fdb2efb80aeca09da3bbd9335fc945ff0",
                    "shasum": ""
                },
                "type": "library",
                "autoload": {
                    "psr-0": {
                        "Psr\\Log\\": ""
                    }
                },
                "notification-url": "https://packagist.org/downloads/",
                "license": [
                    "MIT"
                ],
                "authors": [
                    {
                        "name": "PHP-FIG",
                        "homepage": "http://www.php-fig.org/"
                    }
                ],
                "description": "Common interface for logging libraries",
                "keywords": [
                    "log",
                    "psr",
                    "psr-3"
                ],
                "time": "2012-12-21T11:40:51+00:00"
            }
        ],
        "packages-dev": [],
        "aliases": [],
        "minimum-stability": "stable",
        "stability-flags": [],
        "prefer-stable": false,
        "prefer-lowest": false,
        "platform": [],
        "platform-dev": []
    }
    
    然后为了测试它,我只需在
    编写器中找到提交散列
    fe0936ee266439e916849d48e3a51d5f5e278b
    的任何地方修改提交散列
    lock
    一个字符:
    fe0936ee266439e916849d48e3a51d5f5e278c
    (最后的
    b
    变成了
    c
    );以此
    编写器.lock结尾

    {
        "_readme": [
            "This file locks the dependencies of your project to a known state",
            "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
            "This file is @generated automatically"
        ],
        "content-hash": "2865f724e23cffb23b3afd3a968e0359",
        "packages": [
            {
                "name": "psr/log",
                "version": "1.0.0",
                "source": {
                    "type": "git",
                    "url": "https://github.com/php-fig/log.git",
                    "reference": "fe0936ee26643249e916849d48e3a51d5f5e278c"
                },
                "dist": {
                    "type": "zip",
                    "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278c",
                    "reference": "fe0936ee26643249e916849d48e3a51d5f5e278c",
                    "shasum": ""
                },
                "type": "library",
                "autoload": {
                    "psr-0": {
                        "Psr\\Log\\": ""
                    }
                },
                "notification-url": "https://packagist.org/downloads/",
                "license": [
                    "MIT"
                ],
                "authors": [
                    {
                        "name": "PHP-FIG",
                        "homepage": "http://www.php-fig.org/"
                    }
                ],
                "description": "Common interface for logging libraries",
                "keywords": [
                    "log",
                    "psr",
                    "psr-3"
                ],
                "time": "2012-12-21T11:40:51+00:00"
            }
        ],
        "packages-dev": [],
        "aliases": [],
        "minimum-stability": "stable",
        "stability-flags": [],
        "prefer-stable": false,
        "prefer-lowest": false,
        "platform": [],
        "platform-dev": []
    }
    
    请注意:如果您在浏览器中尝试此操作,而composer稍后会为您执行此操作,您将得到一个404页面:

    我删除了我的
    供应商
    文件夹,原因如下:

    $ rm -Rf vendor
    
    然后,重新运行依赖项安装,以以下输出结束:

    $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Package operations: 1 install, 0 updates, 0 removals
      - Installing psr/log (1.0.0): Downloading (0%)    Failed to download psr/log from dist: The "https://codeload.github.com/php-fig/log/legacy.zip/fe0936ee26643249e916849d48e3a51d5f5e278c" file could not be downloaded (HTTP/1.1 404 Not Found)
        Now trying to download from source
      - Installing psr/log (1.0.0): Cloning fe0936ee26 from cache
        fe0936ee26643249e916849d48e3a51d5f5e278c is gone (history was rewritten?)
    
    
      [RuntimeException]                                                                                                                  
      Failed to execute git checkout 'fe0936ee26643249e916849d48e3a51d5f5e278c' -- && git reset --hard 'fe0936ee26643249e916849d48e3a51d  
      5f5e278c' --                                                                                                                        
    
      fatal: reference is not a tree: fe0936ee26643249e916849d48e3a51d5f5e278c                                                            
    
    
    install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--] [<packages>]...
    
    $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Package operations: 1 install, 0 updates, 0 removals
      - Installing psr/log (1.0.0): Downloading (100%)         
    Generating autoload files
    
    注意:这次尝试,将下载包含存储库状态的zip,与初始提交时一样:

    重复上述删除
    供应商
    文件夹的操作

    $ rm -Rf vendor
    
    清除了composer缓存,这一次也是因为,扰流板警报,安装将成功:

    $ composer clearcache && rm -Rf vendor
    Clearing cache (cache-vcs-dir): /tmp/cache/vcs
    Clearing cache (cache-repo-dir): /tmp/cache/repo
    Clearing cache (cache-files-dir): /tmp/cache/files
    Clearing cache (cache-dir): /tmp/cache
    All caches cleared.
    
    然后,重新运行依赖项安装,以以下输出结束:

    $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Package operations: 1 install, 0 updates, 0 removals
      - Installing psr/log (1.0.0): Downloading (0%)    Failed to download psr/log from dist: The "https://codeload.github.com/php-fig/log/legacy.zip/fe0936ee26643249e916849d48e3a51d5f5e278c" file could not be downloaded (HTTP/1.1 404 Not Found)
        Now trying to download from source
      - Installing psr/log (1.0.0): Cloning fe0936ee26 from cache
        fe0936ee26643249e916849d48e3a51d5f5e278c is gone (history was rewritten?)
    
    
      [RuntimeException]                                                                                                                  
      Failed to execute git checkout 'fe0936ee26643249e916849d48e3a51d5f5e278c' -- && git reset --hard 'fe0936ee26643249e916849d48e3a51d  
      5f5e278c' --                                                                                                                        
    
      fatal: reference is not a tree: fe0936ee26643249e916849d48e3a51d5f5e278c                                                            
    
    
    install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--] [<packages>]...
    
    $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Package operations: 1 install, 0 updates, 0 removals
      - Installing psr/log (1.0.0): Downloading (100%)         
    Generating autoload files
    
    出于对安装过程与我的相似之处的好奇,我更详细地重新运行了该过程,以了解composer真正在做什么:

    $ rm -Rf vendor/ && composer clearcache && composer install -vvv
    Cache directory does not exist (cache-vcs-dir): 
    Clearing cache (cache-repo-dir): /tmp/cache/repo
    Clearing cache (cache-files-dir): /tmp/cache/files
    Clearing cache (cache-dir): /tmp/cache
    All caches cleared.
    Reading ./composer.json
    Loading config file ./composer.json
    Checked CA file /etc/ssl/certs/ca-certificates.crt: valid
    Executing command (/app): git branch --no-color --no-abbrev -v
    Executing command (/app): git describe --exact-match --tags
    Executing command (/app): git log --pretty="%H" -n1 HEAD
    Executing command (/app): hg branch
    Executing command (/app): fossil branch list
    Executing command (/app): fossil tag list
    Executing command (/app): svn info --xml
    Failed to initialize global composer: Composer could not find the config file: /tmp/composer.json
    To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
    Running 1.8.6 (2019-06-11 15:03:05) with PHP 7.3.8 on Linux / 4.9.184-linuxkit
    Reading ./composer.lock
    Loading composer repositories with package information
    Installing dependencies (including require-dev) from lock file
    Reading ./composer.lock
    Resolving dependencies through SAT
    Looking at all rules.
    
    Dependency resolution completed in 0.000 seconds
    Analyzed 43 packages to resolve dependencies
    Analyzed 43 rules to resolve dependencies
    Package operations: 1 install, 0 updates, 0 removals
    Installs: psr/log:1.0.0
      - Installing psr/log (1.0.0): Downloading https://api.github.com/repos/php-fig/log/zipball/a7ab552fdb2efb80aeca09da3bbd9335fc945ff0
    Downloading (connecting...)
    Following redirect (2) https://codeload.github.com/php-fig/log/legacy.zip/a7ab552fdb2efb80aeca09da3bbd9335fc945ff0
    Downloading https://codeload.github.com/php-fig/log/legacy.zip/a7ab552fdb2efb80aeca09da3bbd9335fc945ff0
    Downloading (100%)Writing /tmp/cache/files/psr/log/6e79f232da13c50e0fd07e74eb2d58c350e71a60.zip into cache from /app/vendor/psr/log/4ff496e542e24af2efd56eaf051e132b
    
     Extracting archiveExecuting command (CWD): unzip -qq  '/app/vendor/psr/log/4ff496e542e24af2efd56eaf051e132b' -d '/app/vendor/composer/9c2feb29'
        REASON: Required by the root package: Install command rule (install psr/log 1.0.0)
    
    Generating autoload files
    
    您可以看到它在提交散列
    a7ab552fdb2efb80aeca09da3bbd9335fc945ff0上安装库,相信
    编写器.lock
    指令可以这样做

    -安装psr/log(1.0.0):下载


    事实上有一个问题,因为锁文件说此提交是版本
    1.0.0
    ,它提示我它在该版本安装了包,但这是一个小问题。

    值得注意的是,这对GitHub是正确的(只要您信任GitHub),但对托管在不同位置的包不一定正确。Composer不涉及任何校验和检查,它只是从
    Composer.lock
    中指定的URL下载zip/存储库-如果您不信任网络或包托管,则存在MITM攻击或包篡改的风险。