.. SPDX-FileCopyrightText: 2023 cusy GmbH
..
.. SPDX-License-Identifier: BSD-3-Clause
Security
========
In previous chapters, we have already provided some tips designed to help ensure
safer operation.
.. seealso::
* :ref:`secure-release-workflow`
* :ref:`zizmorcore`
* :ref:`add_2fa`
Here, we would like to summarise and expand on the individual elements once
again. We will be using the `OpenSSF Scorecard
`_ as our guide. Alternatively, you can also
refer to :ref:`open_chain`.
.. _check-vulnerabilities:
Check vulnerabilities
---------------------
Risk: High
This check determines whether the project has open, unfixed vulnerabilities in
its own code base or in its dependencies. An open vulnerability can be easily
exploited and should be closed as soon as possible.
For such a check, you can use for example ``uv audit`` Alternatively, you can
use `osv `_ or `pip-audit
`_.
``uv audit`` is a new command introduced in uv≥0.11.19 that checks the
dependencies in your project for known vulnerabilities in the `OSV
`_ database and ‘undesirable’ project statuses, such as
*deprecated*:
.. code-block:: console
$ uv audit
warning: `uv audit` is experimental and may change without warning. Pass `--preview-features audit-command` to disable this warning.
Resolved 115 packages in 16ms
Found 12 known vulnerabilities and no adverse project statuses in 114 packages
Vulnerabilities:
idna 3.12 has 1 known vulnerability:
- GHSA-65pc-fj4g-8rjx: Internationalized Domain Names in Applications (IDNA): Specially crafted inputs to idna.encode() can bypass CVE-2024-3651 fix
Fixed in: 3.15
Advisory information: https://github.com/kjd/idna/security/advisories/GHSA-65pc-fj4g-8rjx
…
``uv add``, ``uv sync``, and so on can now be run during every synchronisation
process to check for previously identified malware. This feature is not enabled
by default, but it can be easily enabled by setting ``UV_MALWARE_CHECK=1`` in
the shell.
.. seealso::
* `uv audit `_
* `uv audit settings `_
If a vulnerability is found in a dependency, you should update to a
non-vulnerable version; if no update is available, you should consider removing
the dependency.
If you believe that the security vulnerability does not affect your project, you
can define exceptions for ``uv audit`` in the :file:`pyproject.toml` file, for
example:
.. code-block:: toml
:caption: pyproject.toml
[tool.uv.audit]
ignore = ["PYSEC-2022-43017", "GHSA-5239-wwwm-4pmq"]
or better still:
.. code-block:: toml
:caption: pyproject.toml
[tool.uv.audit]
ignore-until-fixed = ["PYSEC-2022-43017"]
.. seealso::
* `ignore `_
* `ignore-until-fixed
`_
You can also add the vulnerability analysis using ``uv-audit`` to your
:doc:`pre-commit ` checks:
.. code-block:: yaml
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 73c2d77a42a113aee9e4b748c24937f09557b82d # 0.11.24
hooks:
- id: uv-audit
files: ^(uv\.lock|pyproject\.toml)$
Maintenance
-----------
.. _automatic-update:
Are the dependencies updated automatically?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: High
Outdated dependencies make a project vulnerable to attacks on known
vulnerabilities. Therefore, the process of updating dependencies should be
automated by checking for outdated or insecure requirements and updating them if
necessary. You can use `dependabot `_ or `Safety
`_ for this purpose.
You can also update your :doc:`/productive/envs/uv/index` environments
automatically.
.. seealso::
* :ref:`Update uv.lock `
Are the dependencies still maintained?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: High
This indicates possible unpatched security vulnerabilities. Therefore, it should
be checked regularly whether a project has been archived. Conversely, the
OpenSSF scorecard assumes that with at least one commit a week for 90 days, the
project is very actively maintained. However, a lack of active maintenance is
not necessarily always a problem: smaller utilities in particular usually do not
need to be maintained, or only very rarely. So a lack of active maintenance only
tells you that you should investigate the situation more closely.
You can also display the activities of a project with badges, for example:
.. image:: https://img.shields.io/github/commit-activity/y/veit/python4datascience
:alt: Annual commit activity
.. image:: https://img.shields.io/github/commit-activity/m/veit/python4datascience
:alt: Monthly commit activity
.. image:: https://img.shields.io/github/commit-activity/w/veit/python4datascience
:alt: Weekly commit activity
Is there a safety concept for the project?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Medium
Ideally, a :ref:`python-basics:security` or similar file should have been
published with the project. This file should contain information
* how a security vulnerability can be reported without it becoming publicly
visible,
* on the procedure and schedule for disclosing the vulnerability,
* to links, for example URLs and emails, where support can be requested.
.. seealso::
* `Guide to implementing a coordinated vulnerability disclosure process for
open source projects
`_
* `Adding a security policy to your repository
`_
* `Runbook
`_
Does the project contain a usable licence?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Low
A :doc:`license ` indicates how the source code may or
may not be used. The absence of a licence complicates any kind of security
review or audit and poses a legal risk for potential use.
OSSF-Scorecard uses the `GitHub License API
`_
for projects hosted on GitHub, otherwise it uses its own heuristics to detect a
published license file. Files in a :file:`LICENSES` directory should be named
with their :ref:`SPDX ` licence identifier followed
by an appropriate file extension as described in the :ref:`REUSE `
specification.
OpenSSF Best Practices Badge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Low
You can also get a corresponding badge with the `OpenSSF Best Practices Badge
Program `_.
Continuous testing
------------------
Are CI tests carried out in the project?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Low
Before code is merged into pull or merge requests, tests should be performed to
help detect errors early and reduce the number of vulnerabilities in a project.
.. seealso::
* :ref:`coverage-github-actions`
Does the project use fuzzing tools?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
risk: Medium
Fuzzing or fuzz testing passes unexpected or random data to your programme to
detect bugs. Regular fuzzing is important to detect vulnerabilities that can be
exploited by others, especially since fuzzing can also be used in an attack to
find the same vulnerabilities.
* Does your project use `fuzzing `_?
* Is the name of the repository included in the `OSS fuzz
`_ project list?
* Is `ClusterFuzzLite `_ used in the
repository?
* Are custom language-specific fuzzing features present in the repository, for
example with `atheris `_?
Does your project use static code analysis tools?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Medium
:term:`Static test procedures` test the source code before the application is
run. This can prevent known types of errors from being inadvertently introduced
into the codebase.
.. _bandit:
`Bandit `__, which you can use with
:doc:`qa/ruff`, allows you to check for the following vulnerabilities, amongst
others:
+--------+-----------------------------------------------------------------------+
| Rule | Description |
+--------+-----------------------------------------------------------------------+
| `S105`_| Hard-coded secrets |
+--------+-----------------------------------------------------------------------+
| `S301`_| :doc:`/data-processing/serialisation-formats/pickle/index` and other |
| | insecure deserialisation |
+--------+-----------------------------------------------------------------------+
| `S307`_| Use of :func:`eval` with untrusted input |
+--------+-----------------------------------------------------------------------+
| `S113`_| Missing timeouts |
+--------+-----------------------------------------------------------------------+
| `S324`_| Weak cryptography, such as MD5 collisions |
+--------+-----------------------------------------------------------------------+
| `S608`_| SQL injection via string formatting |
+--------+-----------------------------------------------------------------------+
.. seealso:
`flake8-bandit `_
You can also integrate Bandit into Jupyter Notebooks, IDEs and the pre-commit
framework.
In addition, you can use :doc:`/productive/qa/pysa` for `taint
`_ analyses.
For GitHub repositories you can also use `CodeQL `_;
see `codeql-action `_.
Risk assessment of the source code
----------------------------------
Is the project free of checked-in binaries?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: High
Generated executables in the source code repository (for example Java
:file:`.class` files, Python :file:`.pyc` files) increase risk because they are
difficult to verify, so they may be out of date or maliciously tampered with.
These problems can be countered with verified, reproducible builds, but their
executables should not end up back in the source code repository.
Is the development process vulnerable to the introduction of malicious code?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: High
With :ref:`protected Git branches `, rules can be defined
for the adoption of changes in standard and release branches, for example
automated `static code analyses
`_ with :doc:`qa/flake8`,
:doc:`qa/pysa`, :doc:`qa/wily` and :ref:`code reviews ` via
:doc:`merge requests `.
.. seealso::
* `Reproducible Builds `_
* `Python 3.12.0 from a supply chain security perspective
`_
* `Defending against the PyTorch supply chain attack PoC
`_
.. _code_reviews:
Are code reviews performed?
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: High
Code reviews can detect unintentional vulnerabilities or possible introduction
of malicious code. Possible attacks can be detected in which the account of a
team member has been infiltrated.
Does the project involve people from several organisations?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Low
This is taken as an indication of a lower number of trustworthy code reviewers.
For this purpose, you can search for different entries in the * Company* field
in the profiles. At least three different companies in the last 30 commits are
desirable, whereby each of these team members should have made at least five
commits.
Risk assessment of the builds
-----------------------------
.. _lock-dependencies:
Are dependencies declared and fixed in the project?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Risk: Medium
In your project, dependencies used during the build and release process should
be pinned. A pinned dependency should be explicitly set to a specific hash and
not just to a mutable version or version range.
:doc:`envs/spack/index` writes these hashes for the respective environment in
:ref:`spack_lock`, :doc:`envs/uv/index` in :ref:`uv_lock`.
.. tip::
Üblicherweise verwalte ich diese Dateien jedoch nur bei
:doc:`python-basics:packs/apps` in :doc:`git/index`. Bei
:doc:`python-basics:libs/index` schränke ich üblicherweise lediglich den
Versionsbereich der Abhängigkeiten in der :file:`pyproject.toml`-Datei ein.
:doc:`envs/spack/index` writes these hashes for the respective environment in
:ref:`spack_lock`, :doc:`envs/uv/index` in :ref:`uv_lock`. These files should
therefore also be checked in with the source code.
This can reduce the following security risks for
:doc:`python-basics:packs/apps`:
* Testing and deployment are done with the same software, which reduces
deployment risks, simplifies debugging and enables reproducibility.
* Compromised dependencies do not undermine the security of the project.
* Substitution attacks, :abbr:`i.e. (id est)` attacks that aim to confuse
dependencies, can thus be countered.
However, fixing dependencies should not prevent software updates. You can
reduce this risk by
* automated tools that notify you when dependencies in your project are out of
date
* update applications that lock dependencies quickly.
.. _S105: https://docs.astral.sh/ruff/rules/hardcoded-password-string/
.. _S301: https://docs.astral.sh/ruff/rules/suspicious-pickle-usage/
.. _S307: https://docs.astral.sh/ruff/rules/suspicious-eval-usage/
.. _S113: https://docs.astral.sh/ruff/rules/request-without-timeout/
.. _S324: https://docs.astral.sh/ruff/rules/hashlib-insecure-hash-function/
.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/
.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/