@@ -21,6 +21,8 @@ When you are executing the job, you are trusting the people building the image a
In some cases, the image may have been corrupted by an attacker. This is what we call a [supply chain attack](https://en.wikipedia.org/wiki/Supply_chain_attack). There are famous cases like the [Codecov incident](https://blog.gitguardian.com/codecov-supply-chain-breach/) in which hackers managed to leak credentials from several services and cloud platforms.
Supply chain attacks can also occur when installing application dependencies in your CI/CD pipeline ([Shai-Hulud](https://about.gitlab.com/blog/gitlab-discovers-widespread-npm-supply-chain-attack/)).
## Mitigations
### Variables scoping
@@ -50,6 +52,26 @@ Every project is encouraged to maintain his own Docker image in order to fit to
> [!tip]
> Whenever building your own image or using an upstream image, you can use [Renovate](https://docs.renovatebot.com/) to watch updates for your tools, test the new version and integrate them seamlessly.
### Application dependencies
#### Using lock files
We highly recommend using lock files ([package-lock.json](https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json), [yarn.lock](https://classic.yarnpkg.com/lang/en/docs/yarn-lock/), [poetry.lock](https://python-poetry.org/docs/basic-usage#committing-your-poetrylock-file-to-version-control), etc.) to list all direct and transitive dependencies. These lock files should be commited to your git repositories. This ensures consistent installs between machines (including CI/CD pipelines).
When using lock files, the CI/CD pipelines based on to-be-continuous always use the dependencies versions listed in the lock file, they will never try to install newer versions of your dependencies (they use `npm ci` instead of `npm install` for example).
To add new dependencies, a developper needs to update the lock file directly on his development machine (the developper should run `npm install` or a similar command). Once done, this new lock file needs to be committed to the git repository.
To upgrade dependencies, we recommend using [Renovate](https://gitlab.com/to-be-continuous/renovate) in a Gitlab CI pipeline. It will handle lock files for you.
Keep in mind that some templates might install dependencies not covered by project lock file.
#### Limit the risk of supply chain attack
When a dependency is compromised ([Shai-Hulud](https://about.gitlab.com/blog/gitlab-discovers-widespread-npm-supply-chain-attack/) for example), it is generally detected and removed from the repositories (NPM, PyPI, etc.) in the first hours/days after it has been published. A good practice is to configure your package managers (npm, yarn, poetry, etc.) on your development machines so that they do not download dependencies that have been published very recently. [pnpm](https://pnpm.io/settings#minimumreleaseage) and [yarn](https://yarnpkg.com/configuration/yarnrc#npmMinimalAgeGate) already support such settings.
Renovate also has a similar [option](https://docs.renovatebot.com/key-concepts/minimum-release-age/) when updating dependencies.