As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Pacotes de bloqueio na página da versão
Importante
O controle de idade de versões não protege contra vulnerabilidades descobertas em versões existentes que já passaram pela janela de quarentena. Use CodeArtifact com o Amazon Inspector para verificação de vulnerabilidades de pacotes estabelecidos.
Quando uma versão do pacote é publicada em um registro público, o registro registra o timestamp de publicação. CodeArtifact preserva esses carimbos de data/hora originais do upstream quando armazena em cache pacotes de conexões externas. Você pode ler esses carimbos de data/hora em seu CI/CD funil e rejeitar versões que foram publicadas muito recentemente.
A maioria dos pacotes maliciosos é detectada e removida poucas horas após a publicação. Uma janela de quarentena de 3 a 7 dias bloqueia a maioria dos ataques à cadeia de suprimentos, incluindo confusão de dependências, invasão da conta do mantenedor e typosquatting.
nota
Os exemplos neste tópico consultam a URL do CodeArtifact repositório, que é o mesmo endpoint que seu gerenciador de pacotes usa para baixar pacotes. Todas as solicitações exigem autenticação. Passe um token de CodeArtifact autorização válido no Authorization: Bearer cabeçalho. Para obter um token, execute aws codeartifact get-authorization-token (veja o CI/CD exemplo mais adiante neste tópico para ver a invocação completa com --domain e--domain-owner).
Não use o publishedTime campo retornado por aws codeartifact describe-package-version para restrição de idade. Esse campo é preenchido no momento da ingestão. Para registros em que o horário de publicação original do upstream não foi capturado (incluindo pacotes ingeridos antes da introdução da captura de timestamp por artefato e determinados caminhos de ingestão), ele volta silenciosamente para o horário da última atualização do registro. A resposta da API não indica qual dos dois valores você está lendo, então você não pode confiar nela como a data de publicação inicial. Em vez disso, use os campos por formato descritos neste tópico.
Os detalhes por formato são diferentes, mas o padrão de controle é o mesmo para todos os formatos: leia o timestamp de publicação upstream de cada versão resolvida, compare-o com o limite de quarentena (a hora atual menos a janela escolhida) e falhe na compilação se alguma versão for mais recente que o limite. Se você usar mais de um formato de pacote, aplique o mesmo padrão com o campo específico do formato mostrado abaixo.
npm
CodeArtifact retorna o timestamp de publicação original do npmjs.org para cada versão no campo npm packument. time Muitos gerenciadores de pacotes e ferramentas de segurança leem esse campo nativamente. Isso inclui a npmMinimalAgeGate opção Yarn 4, a minimumReleaseAge configuração Renovate e a minimumReleaseAge configuração pnpm, todas as quais funcionam sem CodeArtifact modificação.
Solicitação:
curl -H "Authorization: Bearer $CODEARTIFACT_AUTH_TOKEN" \ https://my-domain-111122223333.d.codeartifact.us-east-1.amazonaws.com/npm/my-repo/axios
Resposta (abreviada):
{ "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-chave: time["<version>"] — o valor é a data de publicação original em npmjs.org. Por exemplo, time["1.7.2"] retorna2024-05-21T16:58:04.163Z, que é o registro de data e hora exato registrado pelo npmjs.org quando essa versão foi publicada. Para determinar a idade, compare esse valor com a hora atual menos a janela de quarentena.
Maven
Para artefatos do Maven, CodeArtifact retorna o timestamp de publicação original do Maven Central no cabeçalho da resposta Last-Modified HTTP quando você baixa um arquivo (JAR, POM ou outro artefato).
Solicitação:
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
Cabeçalhos de resposta:
HTTP/2 200 content-type: application/xml Last-Modified: Fri, 26 Feb 2021 20:40:52 GMT content-length: 22672
Campo-chave: Last-Modified cabeçalho — esta é a data de publicação original do Maven Central. Compare-o com o limite de quarentena para determinar se o artefato é muito novo.
nota
O <lastUpdated> campo interno maven-metadata.xml reflete quando seu cache CodeArtifact foi atualizado pela última vez, não a data de publicação inicial. Não use maven-metadata.xml carimbos de data/hora para definir a idade.
NuGet
Para NuGet pacotes, CodeArtifact retorna o timestamp de publicação original do nuget.org no published campo da resposta de registro V3.
Solicitação:
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
Resposta (abreviada, mostrando uma versão):
{ "items": [{ "items": [{ "catalogEntry": { "id": "Newtonsoft.Json", "version": "13.0.3", "published": "2023-03-08T07:42:54.647+00:00", "listed": true } }] }] }
Campo-chave: catalogEntry.published — esta é a data de publicação original do nuget.org. Por exemplo, "2023-03-08T07:42:54.647+00:00" significa que Newtonsoft.Json 13.0.3 foi publicado em 8 de março de 2023.
Carga (Ferrugem)
Para caixas de carga retiradas de crates.io, CodeArtifact preserva o carimbo de data/hora de publicação original na resposta da API crates.io V1. versions Consulte o endpoint da API V1 para obter uma caixa para ler o carimbo de data/hora por versão. created_at
Solicitação:
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-chave: O registro de created_at data e hora por versão na versions resposta V1 é a data de publicação original do crates.io.
nota
O Cargo usa o protocolo de índice esparso (<prefix>/<crate>) para resolução normal de dependências. O índice esparso retornavers,, cksumyanked, e features para cada versão, mas não inclui um carimbo de data e hora de publicação. Para limitar a idade das dependências do Cargo, consulte a API V1 mostrada acima em uma etapa separada do seu pipeline. O padrão cargo build e cargo update os comandos não chamam a API V1.
PyPI
Para pacotes Python, CodeArtifact suporta PEP 691 (JSON Simple API) e PEP 700, que incluem o upload-time campo para cada arquivo de distribuição.
Solicitação:
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/
Resposta (abreviada):
{ "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-chave: upload-time — esta é a data de publicação original do PyPI. Ferramentas como uv oferecem suporte nativo a isso:
# Only install versions published before a specific date uv pip install --exclude-newer 2026-05-01T00:00:00Z -r requirements.txt
nota
A API JSON PEP 691 requer o cabeçalho. Accept: application/vnd.pypi.simple.v1+json A API HTML Simple padrão não inclui carimbos de data/hora.
Para arquivos de distribuição ingeridos antes da introdução da captura no momento do upload por artefato (registros legados), o upload-time campo pode estar ausente das entradas. files[] Sua lógica de bloqueio deve tratar uma versão ausente upload-time como uma versão que ela não pode verificar e decidir se deseja permiti-la ou bloqueá-la de acordo com sua política.
Exemplo: bloqueio de pacotes npm em CI/CD
O script Python a seguir lê um package-lock.json arquivo, consulta o timestamp CodeArtifact de publicação de cada dependência e sai com um status diferente de zero se alguma versão for publicada na janela de quarentena.
#!/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 integração:
# 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
Exemplo de saída quando um pacote é bloqueado:
BLOCKED: 1 package(s) newer than 72 hours: evil-package@1.0.0 (age: 2h, published 2026-06-03T08:30:00+00:00)
Exemplo de saída quando todos os pacotes são aprovados:
PASSED: all 847 packages older than 72 hours.
Ataques mitigados
| Tipo de ataque | Como funciona | Como a restrição de idade ajuda |
|---|---|---|
| Confusão de dependência | O atacante publica um pacote de alta versão com o mesmo nome de um pacote interno em um registro público. | A versão maliciosa é totalmente nova. Bloqueado pela janela de quarentena. |
| Aquisição de conta | O atacante compromete as credenciais do mantenedor e publica uma atualização maliciosa (por exemplo, fluxo de eventos). | A nova versão está em vigor. A comunidade o detecta e o reverte dentro do período de quarentena. |
| Typosquatting | O atacante publica um pacote com um nome semelhante ao de um pacote popular (por exemplo, lodashs em vez delodash). |
Todas as versões do pacote typosquat são novas. Todas as versões estão bloqueadas. |
| Star-jacking | O atacante injeta malware em uma versão de patch de um pacote legítimo que ele controla. | O patch malicioso é uma versão recém-publicada. Bloqueado até passar da janela de quarentena. |
Resumo dos formatos suportados
| Formato | Onde ler o carimbo de data/hora de publicação | Campo-chave | Status |
|---|---|---|---|
| npm | Resposta do pacote () GET /<package> |
time["<version>"] |
Available (Disponível) |
| Maven | Cabeçalho de resposta HTTP no download do artefato | Last-Modified |
Available (Disponível) |
| NuGet | Índice de registro V3 | catalogEntry.published |
Available (Disponível) |
| Carga | Resposta às versões da API V1 | created_at |
Available (Disponível) |
| PyPI | API simples JSON PEP 691 | upload-time |
Available (Disponível) |