Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Pacchetti di controllo sulla pagina della versione
Importante
Il version age gating non protegge dalle vulnerabilità rilevate nelle versioni esistenti che hanno già superato la finestra di quarantena. Utilizzalo CodeArtifact con Amazon Inspector per la scansione delle vulnerabilità di pacchetti consolidati.
Quando una versione del pacchetto viene pubblicata in un registro pubblico, il registro registra il timestamp di pubblicazione. CodeArtifact conserva questi timestamp originali originali quando memorizza nella cache i pacchetti da connessioni esterne. Puoi leggere questi timestamp nella tua CI/CD pipeline e rifiutare le versioni pubblicate troppo di recente.
La maggior parte dei pacchetti dannosi viene rilevata e rimossa entro poche ore dalla pubblicazione. Una finestra di quarantena da 3 a 7 giorni blocca la maggior parte degli attacchi alla catena di fornitura, tra cui la confusione legata alle dipendenze, l'acquisizione dell'account del manutentore e gli errori di battitura.
Nota
Gli esempi in questo argomento interrogano l'URL del CodeArtifact repository, che è lo stesso endpoint utilizzato dal gestore di pacchetti per scaricare i pacchetti. Tutte le richieste richiedono l'autenticazione. Passa un token di CodeArtifact autorizzazione valido nell'Authorization: Bearerintestazione. Per ottenere un token, esegui aws codeartifact get-authorization-token (vedi l' CI/CD esempio più avanti in questo argomento per la chiamata completa con --domain and). --domain-owner
Non utilizzare il publishedTime campo restituito da aws codeartifact describe-package-version for age gating. Questo campo viene compilato al momento dell'inserimento. Per i record in cui non è stata rilevata l'ora di pubblicazione originale (compresi i pacchetti importati prima dell'introduzione dell'acquisizione del timestamp per elemento e determinati percorsi di inserimento), torna silenziosamente all'ora dell'ultimo aggiornamento del record. La risposta dell'API non indica quale dei due valori stai leggendo, quindi non puoi fare affidamento su di essa come data di pubblicazione iniziale. Utilizzate invece i campi per formato descritti in questo argomento.
I dettagli in base al formato variano, ma lo schema di limitazione è lo stesso per tutti i formati: leggete il timestamp di pubblicazione originale per ogni versione risolta, confrontatelo con il limite di quarantena (l'ora corrente meno la finestra scelta) e fallite la compilazione se una versione è più recente del limite. Se utilizzi più di un formato di pacchetto, applichi lo stesso modello con il campo specifico del formato mostrato di seguito.
npm
CodeArtifact restituisce il timestamp di pubblicazione originale di npmjs.org per ogni versione nel campo npm packument. time Molti gestori di pacchetti e strumenti di sicurezza leggono questo campo in modo nativo. Questi includono l'npmMinimalAgeGateopzione Yarn 4, l'minimumReleaseAgeimpostazione Renovate e l'minimumReleaseAgeimpostazione pnpm, che funzionano tutte senza modifiche. CodeArtifact
Richiesta:
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/npm/my-repo/axios
Risposta (abbreviata):
{ "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" } }
Campo chiave: time["<version>"] — il valore è la data di pubblicazione originale da npmjs.org. Ad esempio, time["1.7.2"] return2024-05-21T16:58:04.163Z, che è il timestamp esatto registrato da npmjs.org quando quella versione è stata pubblicata. Per limitare l'età, confronta questo valore con l'ora corrente, escludendo la finestra di quarantena.
Maven
Per gli artefatti di Maven, CodeArtifact restituisce il timestamp di pubblicazione originale di Maven Central nell'intestazione di risposta Last-Modified HTTP quando scarichi un file (JAR, POM o altro elemento).
Richiesta:
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
Intestazioni di risposta:
HTTP/2 200 content-type: application/xml Last-Modified: Fri, 26 Feb 2021 20:40:52 GMT content-length: 22672
Campo chiave: Last-Modified intestazione: questa è la data di pubblicazione originale di Maven Central. Confrontalo con il limite di quarantena per determinare se l'artefatto è troppo nuovo.
Nota
Il <lastUpdated> campo interno maven-metadata.xml riflette l' CodeArtifact ultima data di aggiornamento della cache, non la data di pubblicazione originaria. Non utilizzare maven-metadata.xml timestamp per determinare l'età.
NuGet
Per NuGet i pacchetti, CodeArtifact restituisce il timestamp di pubblicazione originale di nuget.org nel campo della risposta di registrazione V3. published
Richiesta:
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
Risposta (abbreviata, che mostra una versione):
{ "items": [{ "items": [{ "catalogEntry": { "id": "Newtonsoft.Json", "version": "13.0.3", "published": "2023-03-08T07:42:54.647+00:00", "listed": true } }] }] }
Campo chiave: catalogEntry.published — questa è la data di pubblicazione originale di nuget.org. Ad esempio, "2023-03-08T07:42:54.647+00:00" significa che Newtonsoft.Json 13.0.3 è stato pubblicato l'8 marzo 2023.
Cargo (ruggine)
Per le casse Cargo estratte da crates.io, CodeArtifact conserva il timestamp di pubblicazione originale nella risposta dell'API crates.io V1. versions Interroga l'endpoint dell'API V1 per cercare una cassa per leggere il timestamp per versione. created_at
Richiesta:
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
Campo chiave: il created_at timestamp per versione nella risposta V1 è la data di pubblicazione originale di crates.io. versions
Nota
Cargo utilizza il protocollo sparse index () per la normale risoluzione delle dipendenze. <prefix>/<crate> L'indice sparse restituiscevers, cksumyanked, e features per ogni versione, ma non include un timestamp di pubblicazione. Per eliminare le dipendenze di Cargo dall'età, interroga l'API V1 mostrata sopra in un passaggio separato della pipeline. Lo standard cargo build e cargo update i comandi non chiamano l'API V1.
PyPI
Per i pacchetti Python, CodeArtifact supporta PEP 691 (JSON Simple API) e PEP 700, che includono il upload-time campo per ogni file di distribuzione.
Richiesta:
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/
Risposta (abbreviata):
{ "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" }] }
Campo chiave: upload-time — questa è la data di pubblicazione originale di PyPI. Strumenti come lo uv supportano in modo nativo:
# Only install versions published before a specific date uv pip install --exclude-newer 2026-05-01T00:00:00Z -r requirements.txt
Nota
L'API JSON PEP 691 richiede l'intestazione. Accept: application/vnd.pypi.simple.v1+json L'API HTML Simple predefinita non include i timestamp.
Per i file di distribuzione importati prima dell'introduzione dell'acquisizione del tempo di caricamento per elemento (record precedenti), il campo potrebbe non essere presente nelle voci in. upload-time files[] La vostra logica di controllo dovrebbe considerare una versione mancante upload-time come una versione che non può verificare e decidere se consentirla o bloccarla in base alla vostra politica.
Esempio: Gating dei pacchetti npm in CI/CD
Il seguente script Python legge un package-lock.json file, richiede il timestamp di CodeArtifact pubblicazione di ogni dipendenza ed esce con uno stato diverso da zero se una versione è stata pubblicata nella finestra di quarantena.
#!/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 integrazione:
# 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
Esempio di output quando un pacchetto è bloccato:
BLOCKED: 1 package(s) newer than 72 hours: evil-package@1.0.0 (age: 2h, published 2026-06-03T08:30:00+00:00)
Esempio di output quando tutti i pacchetti passano:
PASSED: all 847 packages older than 72 hours.
Attacchi mitigati
| Tipo di attacco | Come funziona | In che modo l'age gating aiuta |
|---|---|---|
| Confusione di dipendenza | Attacker pubblica un pacchetto ad alta versione con lo stesso nome di un pacchetto interno in un registro pubblico. | La versione dannosa è nuova di zecca. Bloccato dalla finestra di quarantena. |
| Acquisizione dell'account | L'aggressore compromette le credenziali del manutentore e pubblica un aggiornamento dannoso (ad esempio, event-stream). | La nuova versione è disponibile. La comunità lo rileva e lo ripristina entro il periodo di quarantena. |
| Errore di battitura | Attacker pubblica un pacchetto con un nome simile a un pacchetto popolare (ad esempio, invece di). lodashs lodash |
Tutte le versioni del pacchetto typosquat sono nuove. Tutte le versioni sono bloccate. |
| Star-jacking | L'aggressore inserisce malware in una versione di patch di un pacchetto legittimo da lui controllato. | La patch dannosa è una versione appena pubblicata. Bloccato fino a quando non supera la finestra di quarantena. |
Riepilogo dei formati supportati
| Formato | Dove leggere il timestamp di pubblicazione | Campo chiave | Stato |
|---|---|---|---|
| npm | Risposta del pacchetto () GET /<package> |
time["<version>"] |
Disponibilità |
| Maven | Intestazione di risposta HTTP durante il download degli artefatti | Last-Modified |
Disponibilità |
| NuGet | Indice di registrazione V3 | catalogEntry.published |
Disponibilità |
| Cargo | Risposta alle versioni dell'API V1 | created_at |
Disponibilità |
| PyPI | API JSON semplice PEP 691 | upload-time |
Disponibilità |