
Problema con AWS SAM CLI (CVE-2025-3047, CVE-2025-3048)
Questo README fornisce un'analisi dettagliata di due vulnerabilità di sicurezza riscontrate nell'AWS Serverless Application Model CLI (AWS SAM CLI) – CVE-2025-3047 e CVE-2025-3048 – insieme ai problemi a livello di codice e alle relative correzioni. Entrambe le vulnerabilità comportano una gestione impropria dei collegamenti simbolici (symlink) durante il processo di build tramite container Docker. Ciascuna sezione di seguito tratta una CVE con un riepilogo, il codice interessato (con riferimenti al codice sorgente del SAM CLI), la patch e il modo in cui risolve il problema, e indicazioni sui rimedi.
Queste falle comportano una gestione impropria dei collegamenti simbolici (symlink) durante il processo sam build --use-container. Entrambi i problemi interessano gli ambienti di sviluppo locali (non hanno alcun impatto sui servizi o sulle risorse AWS distribuiti), ma potrebbero consentire un accesso non autorizzato ai file della macchina host abusando del modo in cui AWS SAM CLI elabora i symlink. È fortemente consigliato aggiornare AWS SAM CLI alle versioni corrette (1.133.0+ per la CVE-2025-3047 e 1.134.0+ per la CVE-2025-3048).
GHSA-px37-jpqx-97q9 è una vulnerabilità di path traversal in AWS SAM CLI <= v1.132.0 che consentiva un accesso non autorizzato ai file sulla macchina host durante sam build --use-container. Quando si compilava un'applicazione serverless all'interno di un container Docker, SAM CLI seguiva i symlink nel progetto per impostazione predefinita. Un attaccante in grado di inserire un symlink dannoso nel progetto (che punta a un file sensibile dell'host) poteva sfruttare i permessi elevati del container Docker per far montare quel file nel container e copiarlo in una posizione accessibile al suo interno. In pratica, ciò significava che i file privilegiati dell'host (fuori dalla directory del progetto) potevano essere letti ed esfiltrati tramite il container di build. Il problema è stato risolto nella v1.133.0. (Per preservare la compatibilità all'indietro per i casi legittimi, SAM CLI v1.133.0 ha introdotto un flag di attivazione esplicita --mount-symlinks per riattivare il vecchio comportamento, se necessario.)
Causa principale e componente interessato: Il problema centrale risiede nel modo in cui AWS SAM CLI monta le directory del progetto e i relativi symlink nel container Docker utilizzato per le build. Nel codice di AWS SAM CLI (modulo samcli.local.docker.container), prima della correzione, tutti i symlink di primo livello nella directory del progetto venivano automaticamente risolti e montati tramite bind mount nel container con gli stessi privilegi elevati del processo del container. Il container viene eseguito come root per impostazione predefinita, quindi risolvere e montare un symlink che punta a un percorso sensibile dell'host avrebbe dato al container l'accesso a quel file, accesso che un utente host non privilegiato normalmente non avrebbe. Il codice vulnerabile non limitava sufficientemente quali symlink seguire/montare.
Nello specifico, nella funzione che crea i mount dei volumi Docker per la build, SAM CLI trattava incondizionatamente i symlink come file/directory reali da montare. La vulnerabilità risiedeva nella logica di orchestrazione dei container di SAM CLI, in particolare nel metodo Container.create di samcli/local/docker/container.py. Nelle versioni vulnerabili, questo metodo tentava sempre di risolvere e montare le destinazioni dei symlink dal progetto nel container Docker, indipendentemente dal contesto. Il codice problematico è mostrato di seguito, tratto da SAM CLI v1.132.0:
# samcli/local/docker/container.py (v1.132.0 - vulnerable snippet)
if self._host_dir:
mount_mode = "rw,delegated" if self._mount_with_write else "ro,delegated"
LOG.info("Mounting %s as %s:%s, inside runtime container", self._host_dir, self._working_dir, mount_mode)
_volumes = {
self._host_dir: {
"bind": self._working_dir,
"mode": mount_mode,
},
**self._create_mapped_symlink_files(), # Always resolve and mount symlinks (vulnerable)
}
Nel codice sopra, _create_mapped_symlink_files() analizza i symlink nella directory del progetto e li prepara per il montaggio. Poiché questo veniva incluso incondizionatamente, tutti i symlink (compresi quelli che puntano all'esterno del progetto) venivano montati nel container. (vedi aws/aws-sam-cli#7865)
Il difetto qui è che durante un sam build --use-container, SAM CLI tratta i symlink come file da montare nel container. Se un symlink puntava, ad esempio, a /etc/shadow sull'host, il container Docker (che potrebbe essere eseguito con privilegi elevati) montava quel file tramite bind mount. Questo è un classico path traversal basato su symlink, che porta a una elevazione dei privilegi – i file dell'host a cui l'utente normalmente non avrebbe alcun accesso potevano essere letti dal container e poi finire nell'output di build.
Patch (codice corretto in v1.133.0): La correzione introduce una nozione di contesto di build e disabilita la risoluzione dei symlink durante le build in container. Nella versione corretta, Container.create accetta un parametro aggiuntivo che indica il contesto (BUILD vs INVOKE), e risolve i symlink solo se il contesto è di invocazione (quando si eseguono funzioni localmente), non durante le build. Di seguito è riportato il codice corretto della versione patchata:
# samcli/local/docker/container.py (v1.133.0+ - patched snippet)
if self._host_dir:
mount_mode = "rw,delegated" if self._mount_with_write else "ro,delegated"
LOG.info("Mounting %s as %s:%s, inside runtime container", self._host_dir, self._working_dir, mount_mode)
mapped_symlinks = self._create_mapped_symlink_files() if self._resolve_symlinks(context) else {}
_volumes = {
self._host_dir: {
"bind": self._working_dir,
"mode": mount_mode,
},
**mapped_symlinks, # Only mount symlinks if explicitly allowed by context (not in build)
}
Nel codice corretto, _create_mapped_symlink_files() è racchiuso dietro un controllo del contesto. Il nuovo enum ContainerContext definisce contesti come BUILD e INVOKE, e _resolve_symlinks(context) restituisce False per il contesto di build. Pertanto, mapped_symlinks sarà un dict vuoto durante le build, il che significa che nessun symlink viene montato nel container per impostazione predefinita.
Riferimento alla modifica del codice: La correzione è stata implementata nella Pull Request#7865 (“fix: Resolve symlinks on local invoke only”) e rilasciata come parte della v1.133.0. Il diff su GitHub mostra l'introduzione di ContainerContext e della logica di montaggio condizionale. Non montando le destinazioni dei symlink durante la build, il container non ottiene più accesso ai file esterni alla directory del progetto. (Se un utente vuole comunque consentire i symlink verso percorsi dell'host, ora deve attivarli esplicitamente tramite il flag --mount-symlinks, aggiunto dopo questa correzione.)
Come la patch risolve il problema: Dopo la patch, qualsiasi symlink nel progetto non verrà più seguito durante la fase di build. Rimarranno semplicemente come symlink nel container (che puntano a percorsi che non verranno montati) o verranno ignorati, invece di essere sostituiti dal contenuto della loro destinazione. Questo chiude il varco attraverso cui un attaccante poteva indurre il processo di build a copiare file sensibili dell'host. In breve, la visibilità del container di build è ora limitata alla directory del progetto stessa (più i volumi esplicitamente consentiti), eliminando l'elevazione dei privilegi non intenzionale.
Rimedio: Tutti gli utenti dovrebbero aggiornare ad AWS SAM CLI v1.133.0 o versioni successive per ottenere questa correzione. Dopo l'aggiornamento, il comportamento predefinito è sicuro. Solo se si ha fiducia esplicita nel proprio progetto e si ha bisogno del vecchio comportamento, si dovrebbe usare sam build --use-container --mount-symlinks. Per la maggior parte degli sviluppatori, si consiglia di lasciare questo flag disattivato (il valore predefinito) per garantire che i symlink non possano uscire dallo spazio di lavoro. È anche buona pratica controllare i symlink nei propri progetti per assicurarsi che non puntino a posizioni sensibili.
GHSA-pp64-wj43-xqcr è una vulnerabilità correlata che interessa AWS SAM CLI <= v1.133.0 (corretta nella v1.134.0). Una vulnerabilità nella cache degli artefatti di build di AWS SAM CLI poteva consentire la fuoriuscita di file sensibili dal container verso lo spazio di lavoro dell'host dopo una build. Se un progetto includeva symlink, dopo l'esecuzione di sam build --use-container, i contenuti delle destinazioni dei symlink venivano copiati nella directory della cache di build locale come file o cartelle normali. In pratica, uno sviluppatore senza accesso a determinati file dell'host poteva ottenerlo perché il contenuto di quei file finiva nell'output di build .aws-sam sull'host. Ad esempio, un symlink nel progetto che punta a /secret/config poteva far sì che il contenuto effettivo di /secret/config comparisse nella cartella .aws-sam/build del progetto dopo la build nel container, anche se l'utente non poteva leggere /secret/config direttamente.
Causa principale e componente interessato: Il cuore del problema era nel modo in cui SAM CLI copiava i file dal container (o dal processo di build) nella directory degli artefatti di build del progetto locale. La funzione responsabile della copia dei file si trova in samcli/lib/utils/osutils.py, in particolare nell'utility personalizzata copytree. Nelle versioni vulnerabili, questa funzione usava shutil.copy2 di Python senza specificare follow_symlinks=False, che per impostazione predefinita segue i symlink e copia il contenuto dei file. Lo snippet seguente (dalla v1.133.0) mostra la logica problematica:
# samcli/lib/utils/osutils.py (v1.133.0 - vulnerable snippet)
# ... inside osutils.copytree ...
else:
try:
shutil.copy2(new_source, new_destination) # follow_symlinks is True by default (vulnerable)
except OSError as e:
if e.errno != errno.EINVAL:
raise e
Qui, se new_source è un symlink, shutil.copy2 risolverà il symlink e copierà il file di destinazione in new_destination. Non c'era alcun flag per indicare di preservare il symlink. Pertanto, un symlink a un file sensibile avrebbe fatto sì che il contenuto di quel file comparisse nella directory di destinazione. (vedi aws/aws-sam-cli#7890)
In termini pratici, immaginate che il processo di build abbia creato un symlink config -> /etc/secret-config (magari come parte della stratificazione delle dipendenze o come residuo dello scenario della CVE-2025-3047). Il codice sopra copierebbe il contenuto di /etc/secret-config nell'output di build locale come config. Un utente locale che non poteva leggere /etc/secret-config direttamente poteva ora semplicemente aprire il file in .aws-sam/build/.../config e vedere il suo contenuto.
Patch (codice corretto in v1.134.0): La correzione è stata semplice: preservare i symlink invece di seguirli durante la copia. In shutil di Python, questo si ottiene passando follow_symlinks=False. Il codice corretto (v1.134.0) modifica la chiamata di copia come segue:
# samcli/lib/utils/osutils.py (v1.134.0 - patched snippet)
else:
try:
shutil.copy2(new_source, new_destination, follow_symlinks=False) # Do not follow symlinks (fixed)
except OSError as e:
if e.errno != errno.EINVAL:
raise e
Con follow_symlinks=False, se new_source è un symlink, la funzione copierà il symlink stesso anziché il file a cui punta. In altre parole, l'output di build conterrà un symlink con la stessa destinazione, invece di un file reale con il contenuto della destinazione.
Riferimento alla modifica del codice: La modifica è stata apportata nella Pull Request#7890 (“fix: Keep symlinks when copying files after build”) e rilasciata nella v1.134.0. Il diff su GitHub di questa PR conferma l'aggiunta del parametro follow_symlinks=False a shutil.copy2, insieme a test unitari aggiornati per garantire che i symlink vengano preservati. La descrizione della PR nota esplicitamente: “I symlink smetteranno di essere trasformati in copie dei file e manterranno il loro stato di symlink.” Ciò significa che gli artefatti di build conterranno symlink (che fanno riferimento ai percorsi dei file originali) invece di copie non autorizzate dei dati dei file.
Come la patch risolve il problema: Dopo questa correzione, la copia dei file post-build del SAM CLI non fa più fuoriuscire il contenuto dei file. Se un symlink è stato creato durante la build, rimarrà un symlink nell'output. L'utente locale non otterrà magicamente l'accesso in lettura al contenuto della destinazione – vedrà semplicemente un symlink che punta ancora al percorso originale. A meno che l'utente non avesse già il permesso di leggere il file di destinazione, il symlink nell'output è innocuo (genererà un errore se dereferenziato senza i dovuti permessi). In sostanza, l'impatto sulla riservatezza è mitigato: i file sensibili non vengono materializzati inavvertitamente nello spazio di lavoro dell'utente. Questa correzione completa la patch della CVE-2025-3047: ha impedito al container di catturare file dell'host tramite symlink; la correzione per la CVE-2025-3048 impedisce a quelli che sono passati (o che esistevano legittimamente) di essere persistiti come file normali nell'output.
Rimedio: Gli utenti dovrebbero aggiornare ad AWS SAM CLI v1.134.0 o versioni successive per ottenere questa patch. Una volta sulla v1.134.0+, il processo di build preserverà i symlink per impostazione predefinita, correggendo questa vulnerabilità. Dopo l'aggiornamento, si consiglia di pulire e ricompilare tutte le applicazioni SAM per garantire che gli artefatti di build memorizzati nella cache vengano rigenerati con il nuovo comportamento più sicuro (il bollettino di sicurezza AWS consiglia di eseguire un nuovo sam build --use-container dopo l'aggiornamento). Non esistono workaround per questo problema nelle versioni precedenti, se non rimuovere manualmente i symlink sensibili o non utilizzare le build in container, quindi l'aggiornamento è l'unica soluzione robusta. In generale, trattate la cartella di build locale del SAM CLI come un output sensibile – con la patch non dovrebbe più contenere segreti inattesi, ma è buona pratica tenere d'occhio ciò che finisce negli artefatti di build.
Sia CVE-2025-3047 che CVE-2025-3048 riguardano debolezze nella gestione dei symlink che potrebbero portare all'esposizione di file riservati durante le build locali. La CVE-2025-3047 potrebbe consentire la lettura di file all'interno del container Docker (e potenzialmente la loro copia all'esterno), mentre la CVE-2025-3048 potrebbe far sì che quei file finiscano nell'output locale, dove un utente o un attaccante potrebbe leggerli in seguito. Queste vulnerabilità sono state valutate di gravità moderata, poiché richiedono una certa interazione con l'utente (eseguire una build su un progetto dannoso) ma potrebbero avere un impatto elevato sulla riservatezza. Le patch coordinate garantiscono che, per impostazione predefinita, SAM CLI non segua i symlink durante le build in container né copi le destinazioni dei symlink nell'output.
Gli sviluppatori e i professionisti DevSecOps che utilizzano SAM CLI dovrebbero assicurarsi che la propria CLI sia aggiornata (v1.134.0 o successiva) e rimanere cauti riguardo ai progetti che contengono symlink inattesi. Se mantenete versioni fork o personalizzate di SAM CLI, dovete incorporare queste stesse correzioni. Comprendendo queste modifiche al codice, si può apprezzare come una piccola modifica alla logica – come l'aggiunta di una condizione o di un parametro di funzione – possa chiudere un serio buco di sicurezza. Considerate sempre la sicurezza nella gestione dei file, soprattutto per quanto riguarda i symlink e le interazioni con i container, per prevenire problemi simili di path traversal nei vostri progetti.
Riferimenti:
container.py e osutils.py che dimostrano le correzioni