Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Bloquer les packages sur l'âge de la version
Important
Le blocage par ancienneté des versions ne protège pas contre les vulnérabilités découvertes dans les versions existantes qui ont déjà dépassé la période de quarantaine. CodeArtifact À utiliser avec Amazon Inspector pour analyser les vulnérabilités des packages établis.
Lorsqu'une version de package est publiée dans un registre public, le registre enregistre l'horodatage de publication. CodeArtifact préserve ces horodatages initiaux en amont lorsqu'il met en cache des packages provenant de connexions externes. Vous pouvez lire ces horodatages dans votre CI/CD pipeline et rejeter les versions publiées trop récemment.
La plupart des paquets malveillants sont détectés et supprimés dans les heures qui suivent leur publication. Une période de quarantaine de 3 à 7 jours bloque la majorité des attaques liées à la chaîne d'approvisionnement, notamment la confusion liée aux dépendances, le piratage du compte du responsable et le typosquatting.
Note
Les exemples présentés dans cette rubrique interrogent l'URL du CodeArtifact référentiel, qui est le même point de terminaison que votre gestionnaire de packages utilise pour télécharger des packages. Toutes les demandes nécessitent une authentification. Passez un jeton CodeArtifact d'autorisation valide dans l'Authorization: Beareren-tête. Pour obtenir un jeton, exécutez aws codeartifact get-authorization-token (voir l' CI/CD exemple plus loin dans cette rubrique pour l'invocation complète avec --domain et--domain-owner).
N'utilisez pas le publishedTime champ renvoyé par aws codeartifact describe-package-version pour la détermination de l'âge. Ce champ est renseigné au moment de l'ingestion. Pour les enregistrements dont l'heure de publication initiale en amont n'a pas été capturée (y compris les packages ingérés avant l'introduction de la capture de l'horodatage par artefact et certains chemins d'ingestion), elle revient silencieusement à l'heure de dernière mise à jour de l'enregistrement. La réponse de l'API n'indique pas laquelle des deux valeurs vous êtes en train de lire. Vous ne pouvez donc pas vous y fier comme date de publication en amont. Utilisez plutôt les champs par format décrits dans cette rubrique.
Les détails par format diffèrent, mais le schéma de sélection est le même pour tous les formats : lisez l'horodatage de publication en amont pour chaque version résolue, comparez-le à votre limite de quarantaine (l'heure actuelle moins la fenêtre que vous avez choisie) et faites échouer la compilation si une version est plus récente que la date limite. Si vous utilisez plusieurs formats de package, vous devez appliquer le même modèle avec le champ spécifique au format illustré ci-dessous.
npm
CodeArtifact renvoie l'horodatage de publication original de npmjs.org pour chaque version dans le champ npm packument. time De nombreux gestionnaires de packages et outils de sécurité lisent ce champ de manière native. Il s'agit notamment de l'npmMinimalAgeGateoption Yarn 4, du minimumReleaseAge paramètre Renovate et du minimumReleaseAge paramètre pnpm, qui fonctionnent tous CodeArtifact sans modification.
Requête :
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/npm/my-repo/axios
Réponse (abrégée) :
{ "name": "axios", "time": { "1.6.0": "2023-10-26T21:15:55.685Z", "1.6.5": "2024-01-05T19:52:15.051Z", "1.7.0": "2024-05-19T20:25:03.615Z", "1.7.1": "2024-05-20T13:32:52.757Z", "1.7.2": "2024-05-21T16:58:04.163Z" } }
Champ clé : time["<version>"] — la valeur est la date de publication originale sur npmjs.org. Par exemple2024-05-21T16:58:04.163Z, time["1.7.2"] renvoie l'horodatage exact enregistré par npmjs.org lorsque cette version a été publiée. Pour déterminer l'âge, comparez cette valeur à l'heure actuelle moins votre période de quarantaine.
Maven
Pour les artefacts Maven, CodeArtifact renvoie l'horodatage de publication original de Maven Central dans l'en-tête de réponse Last-Modified HTTP lorsque vous téléchargez un fichier (JAR, POM ou autre artefact).
Requête :
curl -I -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/maven/my-repo/\ org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.pom
En-têtes de réponse :
HTTP/2 200 content-type: application/xml Last-Modified: Fri, 26 Feb 2021 20:40:52 GMT content-length: 22672
Champ clé : Last-Modified en-tête — il s'agit de la date de publication originale de Maven Central. Comparez-le à votre limite de quarantaine pour déterminer si l'artefact est trop récent.
Note
Le <lastUpdated> champ à l'intérieur maven-metadata.xml indique la date à laquelle le cache a été actualisé pour la CodeArtifact dernière fois, et non la date de publication en amont. N'utilisez pas d'maven-metadata.xmlhorodatage pour la datation.
NuGet
Pour les NuGet packages, CodeArtifact renvoie l'horodatage de publication original de nuget.org dans le published champ de réponse d'enregistrement de la V3.
Requête :
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/nuget/my-repo/\ v3/registration4/newtonsoft.json/index.json
Réponse (abrégée, montrant une version) :
{ "items": [{ "items": [{ "catalogEntry": { "id": "Newtonsoft.Json", "version": "13.0.3", "published": "2023-03-08T07:42:54.647+00:00", "listed": true } }] }] }
Champ clé : catalogEntry.published — il s'agit de la date de publication originale de nuget.org. Par exemple, "2023-03-08T07:42:54.647+00:00" cela signifie que la Newtonsoft.Json version 13.0.3 a été publiée le 8 mars 2023.
Cargo (rouille)
Pour les caisses Cargo extraites de crates.io, CodeArtifact préserve l'horodatage de publication d'origine dans la réponse de l'API crates.io V1. versions Demandez au point de terminaison de l'API V1 une caisse pour lire l'created_athorodatage de chaque version.
Requête :
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/cargo/my-repo/\ api/v1/crates/serde/versions
Champ clé : L'created_athorodatage par version indiqué dans la versions réponse V1 correspond à la date de publication originale de crates.io.
Note
Cargo utilise le protocole sparse index (<prefix>/<crate>) pour la résolution normale des dépendances. L'index clairsemé renvoievers, cksumyanked, et features pour chaque version, mais il n'inclut pas d'horodatage de publication. Pour limiter les dépendances de Cargo en fonction de l'âge, interrogez l'API V1 illustrée ci-dessus dans une étape distincte de votre pipeline. La norme cargo build et cargo update les commandes n'appellent pas l'API V1.
PyPI
Pour les packages Python, CodeArtifact prend en charge les protocoles PEP 691 (API simple JSON) et PEP 700, qui incluent le upload-time champ pour chaque fichier de distribution.
Requête :
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ -H "Accept: application/vnd.pypi.simple.v1+json" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/pypi/my-repo/simple/requests/
Réponse (abrégée) :
{ "files": [{ "filename": "requests-2.31.0-py3-none-any.whl", "upload-time": "2023-05-22T15:12:42.313790Z", "size": 62574, "url": "../../packages/requests/2.31.0/requests-2.31.0-py3-none-any.whl" }] }
Champ clé : upload-time — il s'agit de la date de publication originale de PyPI. Des outils tels que le uv prennent en charge de manière native :
# Only install versions published before a specific date uv pip install --exclude-newer 2026-05-01T00:00:00Z -r requirements.txt
Note
L'API JSON PEP 691 nécessite l'Accept: application/vnd.pypi.simple.v1+jsonen-tête. L'API HTML Simple par défaut n'inclut pas les horodatages.
Pour les fichiers de distribution ingérés avant l'introduction de la capture au moment du téléchargement par artefact (anciens enregistrements), le upload-time champ peut être absent des entrées. files[] Votre logique de blocage doit traiter une version manquante upload-time comme une version qu'elle ne peut pas vérifier et décider de l'autoriser ou de la bloquer conformément à votre politique.
Exemple : synchronisation des packages npm dans CI/CD
Le script Python suivant lit un package-lock.json fichier, CodeArtifact demande l'horodatage de publication de chaque dépendance et sort avec un statut différent de zéro si une version a été publiée dans la fenêtre de quarantaine.
#!/usr/bin/env python3 """ gate_package_age.py - Block npm packages published too recently. Reads package-lock.json, queries CodeArtifact for each dependency's publish timestamp, and rejects versions newer than QUARANTINE_HOURS. Environment variables: CODEARTIFACT_AUTH_TOKEN - from `aws codeartifact get-authorization-token` CODEARTIFACT_NPM_ENDPOINT - from `aws codeartifact get-repository-endpoint` QUARANTINE_HOURS - minimum version age in hours (default: 72) """ import json, os, sys, urllib.request from datetime import datetime, timezone, timedelta def get_publish_time(endpoint, token, package, version): """Fetch the publish timestamp for a specific version from CodeArtifact.""" url = f"{endpoint.rstrip('/')}/{package}" req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"}) data = json.loads(urllib.request.urlopen(req, timeout=30).read()) time_str = data.get("time", {}).get(version) if not time_str: return None return datetime.fromisoformat(time_str.replace("Z", "+00:00")) token = os.environ["CODEARTIFACT_AUTH_TOKEN"] endpoint = os.environ["CODEARTIFACT_NPM_ENDPOINT"] quarantine_hours = int(os.environ.get("QUARANTINE_HOURS", "72")) cutoff = datetime.now(timezone.utc) - timedelta(hours=quarantine_hours) with open("package-lock.json") as f: lockfile = json.load(f) blocked = [] checked = 0 for path, info in lockfile.get("packages", {}).items(): if not path.startswith("node_modules/"): continue name = path.replace("node_modules/", "", 1) version = info.get("version") if not name or not version: continue checked += 1 pub_time = get_publish_time(endpoint, token, name, version) if pub_time and pub_time > cutoff: age_h = (datetime.now(timezone.utc) - pub_time).total_seconds() / 3600 blocked.append(f" {name}@{version} (age: {age_h:.0f}h, published {pub_time.isoformat()})") if blocked: print(f"BLOCKED: {len(blocked)} package(s) newer than {quarantine_hours} hours:") print("\n".join(blocked)) sys.exit(1) print(f"PASSED: all {checked} packages older than {quarantine_hours} hours.")
CI/CD intégration :
# Step 1: Authenticate export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \ --domain my-domain --domain-owner 111122223333 \ --query authorizationToken --output text) export CODEARTIFACT_NPM_ENDPOINT=$(aws codeartifact get-repository-endpoint \ --domain my-domain --domain-owner 111122223333 \ --repository my-repo --format npm \ --query repositoryEndpoint --output text) # Step 2: Set quarantine window (72 hours = 3 days) export QUARANTINE_HOURS=72 # Step 3: Generate lockfile without installing npm install --package-lock-only # Step 4: Gate on age — fails if any dependency is too new python3 gate_package_age.py # Step 5: If gate passes, install npm ci
Exemple de sortie lorsqu'un package est bloqué :
BLOCKED: 1 package(s) newer than 72 hours: evil-package@1.0.0 (age: 2h, published 2026-06-03T08:30:00+00:00)
Exemple de sortie lorsque tous les packages sont transmis :
PASSED: all 847 packages older than 72 hours.
Attaques atténuées
| Le type d'attaque | Comment ça marche | Comment la datation peut vous aider |
|---|---|---|
| Confusion de dépendance | L'attaquant publie un package de haute version portant le même nom qu'un package interne dans un registre public. | La version malveillante est toute nouvelle. Bloqué par une fenêtre de quarantaine. |
| Prise de contrôle de compte | Un attaquant compromet les informations d'identification d'un responsable et publie une mise à jour malveillante (par exemple, event-stream). | La nouvelle version est conservée. La communauté le détecte et le rétablit pendant la période de quarantaine. |
| Typosquattage | L'attaquant publie un package avec un nom similaire à un package populaire (par exemple, lodashs au lieu delodash). |
Toutes les versions du package typosquat sont nouvelles. Toutes les versions sont bloquées. |
| Star-jacking | Un attaquant injecte un logiciel malveillant dans une version de correctif d'un package légitime qu'il contrôle. | Le correctif malveillant est une version récemment publiée. Bloqué jusqu'à ce qu'il vieillit après la période de quarantaine. |
Résumé des formats pris en charge
| Format | Où lire l'horodatage de publication | Champ clé | Statut |
|---|---|---|---|
| npm | Réponse au colis () GET /<package> |
time["<version>"] |
Available |
| Maven | En-tête de réponse HTTP lors du téléchargement de l'artefact | Last-Modified |
Available |
| NuGet | Indice d'enregistrement V3 | catalogEntry.published |
Available |
| Cargo | Réponse aux versions de l'API V1 | created_at |
Available |
| PyPI | API simple PEP 691 JSON | upload-time |
Available |