Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/source-provenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
persist-credentials: true

- name: Attest source governance (SLSA Source Track)
uses: slsa-framework/source-actions/slsa_with_provenance@v0.1.0
uses: slsa-framework/source-actions/slsa_with_provenance@dea965cdca5e0cb422bf7b2653c9d15f678ad01c # v0.1.0
with:
version: v0.6.3

Expand Down
4 changes: 2 additions & 2 deletions dfetch/util/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def run_on_cmdline(
logger.debug(f"Running {cmd}")

try:
proc = subprocess.run( # nosec
cmd, env=env, input=input_data, capture_output=True, check=True
proc = subprocess.run( # nosec B603 — shell=False, list-form args from internal code
cmd, shell=False, env=env, input=input_data, capture_output=True, check=True
)
except subprocess.CalledProcessError as exc:
raise SubprocessCommandError(
Expand Down
29 changes: 22 additions & 7 deletions doc/explanation/compliance_track.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
* - **ECR-C** — Ensure that vulnerabilities can be addressed through security updates, including automatic updates enabled by default, with an opt-out mechanism, user notification, and the option to postpone updates.
- SO.Updateability
- —
- —
- Satisfied by pip distribution (``pip install --upgrade dfetch``); no dfetch-specific control required — see note below table.
- ✓ Implemented
* -
- SO.AutomaticUpdates
Expand All @@ -165,7 +165,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
- ⚠ Partial
* -
- SO.AccessControlReport
- :ref:`C-009 <c-009>`
- :ref:`C-045 <c-045>`
- No persistent log of unauthorised access attempts
- ⚠ Partial
* - **ECR-E** — Protect the confidentiality of stored, transmitted or otherwise processed data by state-of-the-art mechanisms such as encryption at rest and in transit.
Expand All @@ -180,12 +180,12 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
- ✓ Implemented
* -
- SO.DataTransmittedConfidentiality
- :ref:`C-005 <c-005>`, :ref:`C-009 <c-009>`
- :ref:`C-005 <c-005>`, :ref:`C-045 <c-045>`
- —
- ✓ Implemented
* -
- SO.ComAuth
- :ref:`C-003 <c-003>`, :ref:`C-004 <c-004>`, :ref:`C-009 <c-009>`
- :ref:`C-003 <c-003>`, :ref:`C-004 <c-004>`, :ref:`C-045 <c-045>`
- —
- ✓ Implemented
* -
Expand All @@ -210,7 +210,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
- ⚠ Partial
* -
- SO.IntegrityReport
- :ref:`C-009 <c-009>`
- :ref:`C-045 <c-045>`
- No persistent integrity-violation log
- ⚠ Partial
* - **ECR-G** — Process only data, personal or other, that are adequate, relevant and limited to what is necessary in relation to the intended purpose of the product with digital elements (data minimisation).
Expand Down Expand Up @@ -260,7 +260,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
- ⚠ Partial
* -
- SO.MonitorSecurityRelevantActivities
- :ref:`C-009 <c-009>`
- :ref:`C-045 <c-045>`
- —
- ⚠ Partial
* -
Expand All @@ -276,7 +276,7 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
* - **ECR-M** — Provide the possibility for users to securely and easily remove on a permanent basis all data and settings and, where such data can be transferred to other products or systems, ensure that this is done in a secure manner.
- SO.SecureDataDeletion
- —
- —
- No dfetch-specific control required — satisfied by design (no personal data stored); standard OS file deletion suffices — see note below table.
- ✓ Implemented
* -
- SO.DataTransmittedConfidentiality
Expand All @@ -294,6 +294,21 @@ The table below summarises dfetch's implementation of each prEN 40000-1-4 Securi
- —
- — N/A

.. rubric:: Notes on "Implemented" rows with no control listed

**ECR-C SO.Updateability** — No dfetch-specific control is needed. SUM-1/SUM-2
are satisfied by the PyPI distribution mechanism (``pip install --upgrade dfetch``
and GitHub Releases binary packages). pip's TLS-protected download channel provides
the required secure update path. The update mechanism is the responsibility of the
user's package manager, not of dfetch itself.

**ECR-M SO.SecureDataDeletion** — No dfetch-specific control is needed. DLM-1 is
satisfied by design: dfetch stores no personal data, credentials, or cryptographic
keying material on disk. The only on-disk state is ``.dfetch_data.yaml`` (non-sensitive
dependency metadata — credentials stripped by :ref:`C-036 <c-036>`) and vendored
source files (third-party code). Standard OS file deletion (``rm`` / ``del``) is
sufficient to remove all dfetch data; no secure-wipe facility is warranted.

----

Part II — Vulnerability Handling (prEN 40000-1-3)
Expand Down
11 changes: 9 additions & 2 deletions doc/explanation/control_register.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ requirements not independently surfaced by the risk analysis.
* - .. _c-024:

C-024
- ``secrets: inherit`` scope
- Explicit secret forwarding
- Risk-driven
- —
- `.github/workflows/ci.yml <https://github.com/dfetch-org/dfetch/blob/main/.github/workflows/ci.yml>`_
* - .. _c-026:

C-026
Expand Down Expand Up @@ -208,6 +208,13 @@ requirements not independently surfaced by the risk analysis.
- Data minimisation policy
- Compliance-only
- :doc:`compliance_track`
* - .. _c-045:

C-045
- Plaintext transport detection
- Risk-driven
- `dfetch/manifest/project.py <https://github.com/dfetch-org/dfetch/blob/main/dfetch/manifest/project.py>`_,
`dfetch/project/subproject.py <https://github.com/dfetch-org/dfetch/blob/main/dfetch/project/subproject.py>`_
* - .. _c-046:

C-046
Expand Down
55 changes: 55 additions & 0 deletions doc/explanation/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,61 @@ For an overview of how this documentation set is produced — the threat-model
pipeline, compliance pipeline, release attestations, and the full artifact
inventory — see :doc:`security_pipeline`.

.. _risk-rating-methodology:

Risk Rating Methodology
-----------------------

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Both threat models use a qualitative two-axis risk framework aligned with
`BSI TR-03183-1 §5.3 <https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-1.pdf>`_
(Cyber Resilience Requirements for Manufacturers, Chapter 5).

Each threat entry carries two independent ratings:

**Severity (Sev)** — the maximum potential impact if the threat is fully
realised, assessed without regard to likelihood or existing controls.
Determined from the Confidentiality / Integrity / Availability ratings of
the targeted asset and the scope of harm to downstream consumers.

**Risk** — the *residual* risk after factoring in the likelihood of
successful exploitation (attacker capability, required access, known
exploitation evidence) and any controls already partially in place.
Risk can therefore be lower than Severity when the attack path is
constrained, and must be reassessed whenever the control set changes.

.. list-table::
:header-rows: 1
:widths: 12 20 68

* - Rating
- Label
- Guidance (BSI TR-03183-1 §5.3)

* - 🟢L
- Low
- Negligible impact or extremely unlikely. No mandatory control action; document and monitor.

* - 🟡M
- Medium
- Moderate impact or realistic but non-trivial exploit path. Controls advisable; track in backlog.

* - 🟠H
- High
- Significant impact or credible attack path with meaningful probability. Controls required before next release.

* - 🔴VH
- Very High
- Severe impact (system compromise, data exfiltration) or well-documented exploit path. Priority controls required.

* - 🔴C
- Critical
- Catastrophic, near-certain potential (e.g. unencrypted channel with no compensating control). Immediate mitigation required; accept decision requires explicit sign-off.

The risk treatment decisions (Mitigate / Accept / Transfer) in each threat
table follow the same vocabulary as ISO/IEC 27005 and BSI TR-03183-1: an
**Accept** decision requires explicit rationale citing the assumption under
which the residual risk is acceptable, documented alongside the threat entry.

Threat Models
-------------

Expand Down
8 changes: 5 additions & 3 deletions doc/explanation/threat_model_supply_chain.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Risk Context
This report follows the risk-based approach of `BSI TR-03183-1
<https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-1.pdf>`_
Chapter 5.
The Sev / Risk rating scale and treatment vocabulary (Mitigate / Accept / Transfer)
are defined in the :ref:`Risk Rating Methodology <risk-rating-methodology>` section of the main security page.

Threat model for dfetch. Covers the pre-install lifecycle: code contribution, CI/CD, build (wheel / sdist), PyPI distribution, Winget manifest submission, and consumer installation. The installed dfetch package is the handoff point to tm_usage.py.

Expand Down Expand Up @@ -879,7 +881,7 @@ Controls
* - C-009
- Actions commit-SHA pinning
- DFT-07
- Every third-party GitHub Action is pinned to a full commit SHA, preventing tag-mutable supply-chain substitution. ``.github/workflows/*.yml``
- All third-party GitHub Actions are pinned to a full commit SHA (``@<40-hex>``), preventing tag-mutable supply-chain substitution. ``.github/workflows/*.yml``
* - C-010
- OIDC trusted publishing
- DFT-07
Expand Down Expand Up @@ -917,9 +919,9 @@ Controls
- DFT-02
- A CycloneDX SBOM is generated during the build and published alongside the PyPI release, satisfying CRA Article 13 requirements.
* - C-024
- ``secrets: inherit`` scope
- Explicit secret forwarding
- DFT-07
- ``ci.yml`` only passes required repository secrets to the test and docs workflows, preventing malicious PR steps from exfiltrating unrelated secrets.
- ``ci.yml`` explicitly names only the secrets each child workflow requires (``CODACY_PROJECT_TOKEN`` → ``test.yml``; ``GH_DFETCH_ORG_DEPLOY`` → ``docs.yml``); all other repository secrets are not forwarded. ``secrets: inherit`` is deliberately not used so that malicious PR steps cannot exfiltrate unrelated secrets. ``.github/workflows/ci.yml``
* - C-026
- Consumer-side package provenance verification
- DFT-17, DFT-25
Expand Down
8 changes: 5 additions & 3 deletions doc/explanation/threat_model_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Risk Context
This report follows the risk-based approach of `BSI TR-03183-1
<https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-1.pdf>`_
Chapter 5.
The Sev / Risk rating scale and treatment vocabulary (Mitigate / Accept / Transfer)
are defined in the :ref:`Risk Rating Methodology <risk-rating-methodology>` section of the main security page.

Threat model for dfetch. Covers the post-install lifecycle: reading the manifest, fetching dependencies from VCS and archive sources, applying patches, writing vendored files, and generating reports (SBOM, SARIF, check output). The installed dfetch package - produced by the supply chain in tm_supply_chain.py - is the entry point.

Expand Down Expand Up @@ -1013,7 +1015,7 @@ Threats
| **Risk:** 🟠H
| **STRIDE:** T
| **Status:** Accept
- Git submodules are followed: ``git submodule update --init --recursive`` is called unconditionally during every Git fetch (``dfetch/vcs/git.py``), and each submodule is recorded as a ``Dependency`` with ``source_type='git-submodule'`` (``gitsubproject.py``). SVN ``export`` is invoked without ``--ignore-externals``; each ``svn:externals`` entry triggers an additional fetch, and ``SvnSubProject._fetch_externals()`` records it as a ``Dependency`` with ``source_type='svn-external'`` (``svnsubproject.py``). Both behaviours are intentional — dfetch vendors submodule and external trees and surfaces them in metadata — but the fetched URLs come from the upstream repository (``.gitmodules`` / ``svn:externals``), not from ``dfetch.yaml``, and therefore bypass manifest code review and carry no integrity hash. Suppressing these fetches (e.g. passing ``--no-recurse-submodules`` or ``--ignore-externals``) would be a design change that removes intentional vendoring behaviour. Accepted based on the **Manifest under code review** assumption: the choice to vendor an upstream that contains submodules or svn:externals is declared in ``dfetch.yaml`` and subject to code review; the decision to trust those nested URLs is made at the manifest-review boundary.
- Git submodules are followed: ``git submodule update --init --recursive`` is called unconditionally during every Git fetch (``dfetch/vcs/git.py``), and each submodule is recorded as a ``Dependency`` with ``source_type='git-submodule'`` (``gitsubproject.py``). SVN ``export`` is invoked without ``--ignore-externals``; each ``svn:externals`` entry triggers an additional fetch, and ``SvnSubProject._fetch_externals()`` records it as a ``Dependency`` with ``source_type='svn-external'`` (``svnsubproject.py``). Both behaviours are intentional — dfetch vendors submodule and external trees and surfaces them in metadata — but the fetched URLs come from the upstream repository (``.gitmodules`` / ``svn:externals``), not from ``dfetch.yaml``, and therefore bypass manifest code review and carry no integrity hash. Suppressing these fetches (e.g. passing ``--no-recurse-submodules`` or ``--ignore-externals``) would be a design change that removes intentional vendoring behaviour. The initial decision to vendor a given upstream repository (which may contain submodules or SVN externals) is declared in ``dfetch.yaml`` and subject to code review. However, the specific nested URLs in ``.gitmodules`` or ``svn:externals`` are not visible in ``dfetch.yaml`` and are not independently reviewed; if an upstream maintainer adds a new submodule after the initial review, dfetch will fetch it on the next ``dfetch update`` without a new ``dfetch.yaml`` change triggering review. Residual risk: a compromised upstream maintainer could inject a malicious submodule URL that bypasses the manifest review boundary. Accepted based on the **dfetch scope boundary** assumption: the security of fetched third-party source code and its nested dependencies is the responsibility of the manifest author who selects and pins each upstream; ``dfetch check`` version-drift notifications prompt review before any upstream change (including new submodules) is vendored.
* - DFT-16
- Configured destination path allows writes to security-sensitive project directories
- A-22: dfetch Process
Expand Down Expand Up @@ -1101,7 +1103,7 @@ Threats
| **Risk:** 🟠H
| **STRIDE:** T I
| **Status:** Mitigate
- C-009 emits a visible warning immediately before the VCS command when a plaintext scheme (``http://``, ``git://``, ``svn://``) is detected, with credentials redacted and ``https://`` / ``svn+ssh://`` recommended. Detection only — dfetch does not reject or upgrade plaintext URLs; scheme selection remains the manifest author's responsibility.
- C-045 emits a visible warning immediately before the VCS command when a plaintext scheme (``http://``, ``git://``, ``svn://``) is detected, with credentials redacted and ``https://`` / ``svn+ssh://`` recommended. Detection only — dfetch does not reject or upgrade plaintext URLs; scheme selection remains the manifest author's responsibility.
* - DFT-28
- CI/CD build cache poisoned to silently substitute a malicious compiled artifact
- A-20: Local VCS Cache (temp)
Expand Down Expand Up @@ -1188,7 +1190,7 @@ Controls
- Manifest input validation
- DFT-04, DFT-08
- StrictYAML schema with ``SAFE_STR = Regex(r"^[^\x00-\x1F\x7F-\x9F]*$")`` rejects control characters in all string fields. ``dfetch/manifest/schema.py``
* - C-009
* - C-045
- Plaintext transport detection
- DFT-26
- ``plaintext_warning()`` (``dfetch/manifest/project.py``) inspects the resolved remote URL immediately before each VCS command is issued (inside the ``check_for_update`` and ``update`` spinners in ``subproject.py``). If the scheme is ``http://``, ``git://``, or ``svn://``, a visible warning is emitted naming the redacted URL (credentials stripped from the userinfo component) and recommending ``https://`` or ``svn+ssh://``. Detection only — dfetch still proceeds with the plaintext connection; the control raises user awareness but does not enforce scheme selection. ``dfetch/manifest/project.py, dfetch/project/subproject.py``
Expand Down
Loading
Loading