Skip to content
Open
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
11 changes: 10 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
contents: read # lecture du code
contents: write # attacher la provenance a la release (Signed-Releases)
packages: write # push vers GHCR
id-token: write # OIDC keyless (provenance + cosign)
attestations: write # attestations natives GitHub
Expand Down Expand Up @@ -53,6 +53,7 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Attestation de provenance SLSA (native)
id: attest
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
with:
subject-name: ${{ env.IMAGE }}
Expand Down Expand Up @@ -81,3 +82,11 @@ jobs:
IMAGE: ${{ env.IMAGE }}
DIGEST: ${{ steps.build.outputs.digest }}
run: cosign sign --yes "${IMAGE}@${DIGEST}"
- name: Attacher la provenance à la release (Scorecard Signed-Releases)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.release.tag_name }}
BUNDLE: ${{ steps.attest.outputs.bundle-path }}
run: |
cp "$BUNDLE" provenance.intoto.jsonl
gh release upload "$TAG" provenance.intoto.jsonl --clobber
35 changes: 26 additions & 9 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,39 @@ logicielle sécurisée sur GitHub Actions. Il applique les pratiques qu'il ensei

## Signaler une vulnérabilité

Utilisez l'onglet **Security > Report a vulnerability** du dépôt (GitHub Private
Vulnerability Reporting). En l'absence de cette option, ouvrez une issue **sans
détail exploitable** et demandez un canal privé.
Nous pratiquons la **divulgation coordonnée** (coordinated disclosure). Merci de
**ne pas** ouvrir d'issue publique pour une vulnérabilité.

Délais indicatifs :
Deux canaux privés pour signaler une vulnérabilité :

- Accusé de réception sous 48 heures.
- Évaluation initiale sous 5 jours ouvrés.
- Correctif ou plan de remédiation communiqué selon la gravité.
- **De préférence**, via l'avis de sécurité privé GitHub :
<https://github.com/stephrobert/secure-python-pipeline/security/advisories/new>
- Par courriel, à l'adresse : **security@stephane-robert.info**

Merci d'inclure une description de la vulnérabilité, les étapes de reproduction,
la version ou le digest de l'image concernée, et l'impact estimé.

## Engagements de délai

Pour toute vulnérabilité signalée, nous nous engageons sur les délais suivants :

- **Accusé de réception** sous **48 heures**.
- **Évaluation initiale** et première réponse sous **5 jours** ouvrés.
- **Correctif ou plan de remédiation** communiqué sous **30 jours**, plus tôt
selon la gravité.
- **Divulgation publique coordonnée** après correctif, dans un délai maximum de
**90 jours** à compter du signalement (coordinated disclosure window).

Nous créditons publiquement les personnes qui signalent une vulnérabilité de
manière responsable, sauf demande contraire de leur part.

## Garanties de la chaîne de build

Chaque image publiée sur `ghcr.io` est accompagnée de :

- une **attestation de provenance SLSA** signée (Sigstore keyless, log Rekor) ;
- un **SBOM** (CycloneDX et SPDX) attaché au registre ;
- une **signature Cosign** vérifiable du digest.
- une **signature Cosign** vérifiable du digest ;
- un fichier **`provenance.intoto.jsonl`** attaché à chaque release.

La vérification est décrite dans le README.
La procédure de vérification est décrite dans le [README](README.md).
42 changes: 42 additions & 0 deletions fuzz/fuzz_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Harnais de fuzzing Atheris pour l'API.

Scorecard détecte le fuzzing Python par la présence de `import atheris`.
Ce harnais envoie des chemins et payloads aléatoires à l'application pour
débusquer des plantages non gérés (exceptions non attendues, 500).

Lancement local :
pip install atheris
python fuzz/fuzz_api.py
"""

import sys

import atheris

with atheris.instrument_imports():
from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)


def test_one_input(data: bytes) -> None:
"""Un tour de fuzzing : construit une requête à partir de données aléatoires."""
fdp = atheris.FuzzedDataProvider(data)
path = fdp.ConsumeUnicodeNoSurrogates(64)
try:
response = client.get("/" + path)
except Exception: # noqa: BLE001 - le fuzzing doit tolérer toute erreur applicative
return
# Une réponse serveur (5xx) sur une entrée malformée signale un bug à corriger.
assert response.status_code < 500


def main() -> None:
atheris.Setup(sys.argv, test_one_input)
atheris.Fuzz()


if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ line-length = 88
select = ["E", "F", "I", "S", "B", "C4", "UP"]

[tool.ruff.lint.per-file-ignores]
# S101 = usage d'assert, normal dans les tests pytest
# S101 = usage d'assert, normal dans les tests pytest et les harnais de fuzzing
"tests/**/*.py" = ["S101"]
"fuzz/**/*.py" = ["S101"]

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
3 changes: 3 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ httpx>=0.28.1

# Build et compilation des dépendances épinglées par hash
pip-tools>=7.4.0

# Fuzzing
atheris>=2.3.0