Opciones de registro de carga privada y entrega de cajas verificada

Ya están disponibles los parches de php2shell (CVE-2026-109618 y CVE-2026-109619) para PHP en fin de vida útil. Dado que las respuestas del departamento de ventas están tardando más de lo habitual debido a la elevada demanda, la forma más rápida de obtener los paquetes parcheados es comprar ELS para Runtimes en línea (se abre en una pestaña nueva). Lee las preguntas frecuentes sobre los parches

Ir directamente al resumen generado por IA de esta entrada del blog

  • Resume esta entrada con Perplexity
  • Resume esta publicación con Gemini

Principales conclusiones

  • La sustitución de la fuente de carga parte de la base de que la sustitución se aplica al mismo contenido de la caja, por lo que no es necesario realizar cambios en el archivo de proyecto.
  • La selección por parte del registro evalúa una caja en función de su contenido, y no de la reputación de su nombre.
  • La ruta de verificación es una .cargo/config.toml cambio, sin modificaciones en Cargo.toml o Cargo.lock.
  • Las cajas parcheadas son la excepción, y optar por una de ellas supone un cambio deliberado y manifiesto.

Confiar en crates.io por defecto es una decisión que casi nadie toma a propósito. Simplemente es la opción predeterminada, hasta que alguien la analiza detenidamente. La siguiente pregunta suele ser, en alguna de sus variantes, qué hacer en su lugar, y ahí es donde un registro privado de Cargo deja de ser una opción obvia.

El término abarca al menos tres configuraciones diferentes, y Cargo las trata de forma tan distinta que elegir la incorrecta puede acarrear problemas más adelante. Una de ellas no requiere ningún cambio en los archivos del proyecto. La otra implica modificar cada manifiesto que declare las dependencias que se desean redirigir. La mayoría de los equipos no se dan cuenta de cuál es cuál hasta que ya llevan un buen trecho en el proceso.

Hay una excepción que conviene destacar antes que nada, ya que es lo que se descubre más tarde. La verificación no implica cambios en los archivos del proyecto. Los crates parcheados sí los implican, y optar por uno de ellos siempre supone una modificación deliberada.

Qué suele significar un registro de carga privado

Se analizan tres enfoques bajo un mismo epígrafe: «vendoring», sustitución de fuentes (duplicación) y registros alternativos, incluidos los privados. La propia documentación de Cargo considera la sustitución de fuentes como algo distinto de un registro privado, en lugar de como un tipo de registro privado.

Tres formas de redirigir crates.io: incluirlo en el repositorio como proveedor, sustituir el código fuente mediante un espejo verificado y utilizar un registro alternativo con un nombre específico para cada dependencia

Arquitectura El contenido puede diferir del de crates.io Es necesario modificar el archivo Cargo.toml
Subir archivos al repositorio Sí, es tuyo No, pero añade un vendor/ directorio
Espejo de recambio original No, tiene que ser lo mismo. No
Registro alternativo Sí Sí, por dependencia

La sustitución de la fuente es la que da lugar a la afirmación de que no se produce ningún cambio en el flujo de trabajo, y la razón por la que esto es así es que Cargo da por hecho que el contenido del crate es el mismo en ambos lados.

La sustitución de la fuente de carga está diseñada para los espejos. Se parte de la base de que la sustitución contiene la misma fuente que el original y no permite que la sustitución introduzca cajas que el original no tenga. Vale la pena ser preciso en este punto, ya que es aquí donde muchos textos publicitarios se exceden.

Cargo no vuelve atrás para cotejar la sustitución con crates.io. Lo que se aplica en un proyecto real es Cargo.lock, ya que una suma de comprobación ya registrada allí no coincidirá con una caja cuyo contenido haya cambiado, y la compilación fallará en lugar de aceptar el sustituto sin dar aviso.

Eso suena a una limitación. En el caso de un espejo de verificación, ese es precisamente el objetivo: se espera que el servidor sustituto proporcione a tu compilación el mismo contenido de crate que ya ha resuelto.

SecureChain funciona, en esencia, de la misma manera. Recompila los crates a partir del código fuente, los verifica y se integra en tu configuración actual, de modo que los desarrolladores siguen ejecutando los mismos comandos de Cargo de siempre.

Dos formas en las que Cargo te permite redirigir los contenedores

La fuente de sustitución se encuentra en .cargo/config.toml y no modifica nada de tu proyecto.

[source.crates-io]
replace-with = "securechain"

[source.securechain]
registry = "<your SecureChain registry index URL>"

El registro alternativo es el otro mecanismo, y su funcionamiento es diferente por diseño.

[registries.securechain]
index = "<your SecureChain registry index URL>"

Con un registro alternativo, cada dependencia debe asignarle un nombre.

[dependencies]
serde = { version = "1.0", registry = "securechain" }

Se trata de una modificación por dependencia que afecta a todos los manifiestos que declaran uno de esos crates, lo cual es precisamente el coste de migración que evita la vía de sustitución de la fuente.

Una visión realista: un proveedor que afirme que ofrece crates modificados y que, al mismo tiempo, nada cambia en los archivos de tu proyecto, está describiendo algo que la sustitución estándar de fuentes de Cargo no admite. Pregunta cuál de los dos mecanismos utiliza realmente una integración, y el resto de la evaluación resultará mucho más sencilla.

Por qué la sustitución de fuentes mantiene la validez de tu archivo de bloqueo

Un archivo «crate» descargado o bien coincide con la suma de comprobación de Cargo.lock y la compilación continúa, o bien no coincide y la compilación falla.

La primera pregunta que se plantea un ingeniero de Rust meticuloso es si Cargo.lock se interrumpe. En la ruta de verificación no ocurre así, y el motivo es importante, ya que también constituye el argumento más sólido de que disponemos.

A .crate El archivo es un archivo tar comprimido que contiene el código fuente del crate empaquetado. La verificación de la suma de comprobación que realiza Cargo confirma que el archivo descargado coincide con la suma de comprobación que espera según los metadatos del registro y el archivo de bloqueo, y eso es todo lo que hace. No recompila nada. El paso independiente de recompilación y comparación tiene lugar en una fase anterior, en un servicio como SecureChain, antes de que el crate se sirva a través de la fuente de sustitución.

Cuando una compilación difiere del artefacto publicado, esa discrepancia se convierte en un hallazgo que hay que investigar, en lugar de pasar por alto sin más. La divergencia no es, por sí sola, prueba de manipulación, ya que también puede deberse a peculiaridades del empaquetado o a pasos de lanzamiento no reproducibles. La cuestión es que sale a la luz en lugar de desaparecer.

Por lo tanto, la propiedad útil no es que la verificación sea invisible, sino que los crates verificados llegan sin cambios, mientras que cualquier elemento inesperado se hace visible en lugar de aceptarse en silencio.

rm -rf ~/.cargo/registry
cargo build --locked

Si se limpia la caché del Registro y, además, --locked genera una compilación correcta con tu código sin modificar Cargo.lock, la afirmación sobre la compatibilidad se demuestra en tu entorno, en lugar de en una diapositiva. --locked Es este indicador el que importa aquí, ya que, en lugar de reescribir el archivo de bloqueo de forma silenciosa, genera un error. Borrar primero la caché es lo que obliga a que se recuperen todos los crates y se vuelva a verificar su suma de comprobación.

Consejo de experto: Ejecuta el programa piloto con --locked y --offline en pasadas separadas. --locked demuestra que el archivo de bloqueo existente se puede utilizar tal cual. --offline confirma que la compilación se completa sin necesidad de más acceso a la red. Para asegurarte de que no se ha descargado nada directamente de crates.io, utiliza el registro de tráfico saliente o una regla de cortafuegos (véase la Fase 4) en lugar de confiar en --offline solo.

Lo que detectan las pruebas de cribado y lo que no

Dos amenazas relacionadas con los crates: la suplantación de identidad mediante un nombre muy parecido y la apropiación indebida cuando un crate de confianza cambia de manos

Un registro privado de carga justifica su existencia frente a dos amenazas relacionadas, y ninguna de ellas se resuelve comprobando un nombre o una suma de comprobación.

La primera es la suplantación de identidad, en la que se publica un crate con un nombre lo suficientemente parecido a uno popular como para que un error tipográfico o un vistazo rápido a un Cargo.toml, lo instala de todos modos. La segunda es la «toma de control», en la que un proyecto en el que se ha confiado durante años cambia de manos —ya sea porque el responsable deja el proyecto, se produce un ataque a la cuenta o se lleva a cabo una transferencia silenciosa de la propiedad— y, a continuación, empieza a distribuir algo diferente bajo un nombre en el que tu equipo ya confía.

Ninguna de las dos cosas depende de una línea de código vulnerable situada en algún punto del árbol de dependencias. Ambas dependen del modelo predeterminado de crates.io, donde cualquiera puede publicar y un nombre con historial no dice nada sobre quién lo controla actualmente.

La comprobación previa a la incorporación de un crate a tu compilación tiene precisamente ese objetivo. El crate se recompila a partir del código fuente y se comprueba en busca de patrones de malware conocidos y comportamientos sospechosos, de modo que se evalúa en función de su propio contenido, en lugar de heredar la confianza de su nombre. Esto reduce considerablemente las probabilidades. No es una garantía de que se identifique todos los crates maliciosos, y cualquier proveedor que ofrezca esa garantía está exagerando.

Además, no es lo mismo que garantizar que nada de tu compilación ejecute jamás código arbitrario. La comprobación se lleva a cabo antes de que el crate llegue a tu árbol. Una vez que está en tu árbol, tu propio cargo build funciona como siempre.

Capa ¿Quién se encarga de revisarlo o de ponerlo en un entorno aislado? Lo que atrapa
Marcar la casilla en el registro, antes de la instalación El registro Suplantación de identidad, apropiación de cuentas, patrones de malware conocidos
El tuyo propio cargo build Cargo no lo ejecuta en un entorno aislado build.rs y las macros «proc» siguen ejecutándose a menos que se añada aislamiento externo

Cómo las cajas modificadas cambian la integración

Aquí es también donde la adquisición deja de ser una mera cuestión de control. Una caja cuya propiedad cambia de manos de forma discreta no es un problema que se detecte una sola vez. Se trata de una deficiencia de mantenimiento continuada, y el control de un único envío no la subsana.

La aplicación continua de parches a los crates que el desarrollador original ha abandonado es un servicio independiente de la verificación, y da lugar a crates cuyo contenido difiere deliberadamente del publicado en crates.io. Un contenido diferente implica sumas de comprobación diferentes y, por diseño, la sustitución del código fuente rechaza todo aquello que no coincida.

Por lo tanto, la aplicación de parches es una opción que hay que activar explícitamente para cada crate. En el caso de una dependencia que figure en tu propio manifiesto, basta con indicar el nombre del registro alternativo.

[dependencies]
abandoned-crate = { version = "1.2.4", registry = "securechain" }

En el caso de una caja que solo aparece de forma transitiva, esa declaración no tiene ningún efecto, ya que rige la única dependencia que has indicado. Una de nivel superior [patch] La «sobrescritura» es el mecanismo diseñado para el caso transitivo.

[patch.crates-io]
abandoned-crate = { version = "1.2.4", registry = "securechain" }

Entre Cargo.toml en los albaranes, se indica «Carga» [patch] solo a partir del que se encuentra en la raíz del espacio de trabajo, y desde allí se aplica a todo el grafo de dependencias. También puede ubicarse en .cargo/config.toml, aunque la documentación de Cargo desaconseja hacerlo con cualquier elemento compartido, ya que los archivos de configuración no suelen incluirse en el control de versiones.

Por lo tanto, en la práctica, una implementación real tiene una estructura de dos niveles.

Necesidad Mecanismo Cambios en el archivo del proyecto
Cajas verificadas, sin modificar Sustitución de la fuente Ninguno
Cajas abandonadas remendadas Registro alternativo o [patch] Una pequeña entrada explícita por caja

Hay algo que esa tabla oculta y que merece la pena mencionar. La elección de un contenedor modificado puede alterar el código fuente y la suma de comprobación registrados en Cargo.lock, por lo que el archivo de bloqueo se actualiza, y esa actualización debe confirmarse y revisarse como cualquier otro cambio en las dependencias. La verificación no modifica el archivo de bloqueo. La aplicación de parches sí lo hace.

Eso es mejor que una afirmación general, porque el comprador de servicios de seguridad puede ver cuánto cuesta la aplicación de parches antes de firmar nada. Pedir un pequeño cambio deliberado por cada contenedor que decidan que se actualice es razonable. Descubrir a mitad de la fase piloto que hay que editar todos los manifiestos no lo es.

Las auditorías de código fuente del sector publicadas por SC Media revelaron que el 93 % de los códigos fuente analizados contenían componentes sin actividad de desarrollo en los últimos dos años. En el caso de los que están realmente abandonados dentro de ese grupo, ya no queda ningún mantenedor en la cadena de desarrollo que pueda publicar una versión corregida, y la retrocompatibilidad implica reconstruir el contexto desde cero. Reproducir el error, escribir una corrección que no altere el comportamiento del que dependen los usuarios y validarla sin poder contar con la revisión o el criterio de un mantenedor activo en quien apoyarse. La postura de TuxCare con SecureChain en este sentido es la de una gestión a largo plazo, más que la sustitución del desarrollo original, y por eso ambas capacidades se integran de forma diferente.

Puesta en marcha

Cuatro fases, ordenadas de tal manera que cada una de ellas aporte pruebas antes de que la siguiente amplíe el alcance.

Fase Acción Lo que demuestra
1 Sustituir la fuente en un servicio, limpiar la caché Las sumas de comprobación siguen siendo válidas
2 cargo build --offline tras la fase 1 La compilación se completa utilizando únicamente lo que ya se había descargado en la Fase 1
3 Implementación de CI en todos los repositorios ¿Qué pipelines tenían una configuración de origen codificada de forma fija?
4 Bloquear el acceso al índice público de crates.io y a los puntos finales de descarga ¿Qué era lo que se saltaba silenciosamente la configuración?

La fase 3 es donde estos lanzamientos realmente salen mal. Fusión de carga .cargo/config.toml archivos del directorio actual y, sucesivamente, de sus directorios superiores, y, a continuación, recurre a $CARGO_HOME/config.toml, siendo el archivo más profundo el que prevalece y el directorio de inicio el que ocupa el último lugar en la jerarquía. Una imagen de CI puede introducir configuraciones inesperadas, y el directorio desde el que se ejecutó cargo determina qué archivos se incluyen en la fusión. Comprueba la configuración efectiva en el ejecutor en lugar de dar por sentada cuál es.

cargo +nightly -Z unstable-options config get --show-origin source

Esto muestra la configuración real de la fuente y el origen de cada valor. Ejecútalo en un agente de compilación en lugar de en un ordenador portátil, ya que ambos suelen ser diferentes y solo uno de ellos está documentado.

Nota: Para ello es necesario ejecutar Cargo cada noche con -Z unstable-options, por lo que no es algo que deba integrarse tal cual en un proceso de integración continua estable.

Consejo profesional: Ejecuta la Fase 4 en el entorno de prueba durante una semana antes de pasar a producción. Bloquea el índice disperso en index.crates.io y las descargas en static.crates.io, y si algún elemento de la flota sigue utilizando el protocolo Git, también hay que bloquear el repositorio del índice de crates.io en github.com. Los procesos que fallen suelen revelar rutas de las que nadie sabía que seguían obteniendo datos directamente de crates.io, y esa lista tiene más valor como documento que como análisis a posteriori.

Cuando un registro privado por sí solo no es suficiente

La duplicación verificada, es decir, la sustitución de la fuente, resuelve el problema de «¿es este el mismo paquete?». El crate que se incluye en tu compilación es el que tu archivo de bloqueo ya ha resuelto. No te indica si el crate merecía confianza en primer lugar, y eso es precisamente lo que aprovechan los nombres similares o la apropiación de un crate.

SecureChain para Rust cubre ambos aspectos. Cada crate se recompila a partir del código fuente y se verifica su integridad; a continuación, se analiza en busca de comportamientos maliciosos o sospechosos antes de que llegue a tus manos, de modo que las versiones afectadas por typosquatting o por apropiación maliciosa se evalúan en función de su contenido, en lugar de basarse únicamente en su nombre y su historial.

Además, sigue aplicando parches a lo que ya hay en tu pila cuando los responsables del mantenimiento dejan de estar activos, y una vez que un crate llega al final de su ciclo de vida, el servicio «Endless Lifecycle Support» proporciona de forma continuada las correcciones retrocompatibles para que una dependencia abandonada no se convierta silenciosamente en una sin parches.

Comprueba cuánto cuesta la cobertura verificada y con parches para tu árbol de dependencias real y solicita un presupuesto.

PREGUNTAS FRECUENTES

¿Qué es un registro de carga privado?

Un registro privado de Cargo es un registro alternativo, interno o gestionado por un proveedor, para los crates de Rust. Se diferencia de la incorporación de crates a tu repositorio mediante un proveedor y de la creación de un espejo de crates.io a través de la sustitución de la fuente de Cargo. Estas opciones controlan el origen de los crates de diferentes maneras, pero solo un registro alternativo funciona como registro privado según la propia definición de Cargo.

¿El hecho de replicar crates.io mediante la sustitución de fuentes afecta al archivo Cargo.lock?

No, siempre que la fuente de sustitución proporcione crates verificados y sin modificar, ya que el contenido es el mismo y las sumas de comprobación registradas siguen siendo válidas según tu archivo de bloqueo existente. Los crates con contenido modificado no pueden pasar en absoluto por la sustitución de la fuente.

¿Cómo se configura la sustitución de fuentes en Cargo?

Añadir un [source.crates-io] bloque con replace-with si se hace referencia a una fuente concreta, definir dicha fuente con la URL de su índice de registro, tanto en .cargo/config.toml. No hay cambios en Cargo.toml o Cargo.lock son necesarios.

¿Detecta la sustitución de fuentes los crates que son objeto de «typosquatting» o que han sido secuestrados?

La sustitución de la fuente por sí sola no lo hace. Su función es redirigir Cargo a una fuente equivalente, mientras que el contenido del crate permanece igual. Detectar un nombre similar o un crate que haya cambiado de manos es una función de filtrado, que se evalúa cuando se vuelve a compilar un crate por primera vez y de nuevo a medida que se publican nuevas versiones; no es una propiedad del mecanismo de redireccionamiento.

¿Cómo funcionan las cajas «patched» con Cargo?

Las cajas parcheadas tienen un contenido diferente al publicado en crates.io, por lo que no se pueden distribuir mediante la sustitución del código fuente. Una dependencia directa puede apuntar a un registro alternativo, mientras que una de primer nivel [patch] La función «override» sustituye la copia modificada en todo el grafo de dependencias, incluidos los usos transitivos. En cualquier caso, el archivo de bloqueo registra el cambio.

¿Cómo puedo verificar yo mismo la afirmación de compatibilidad?

Borrar ~/.cargo/registry, y luego ejecuta cargo build --locked. Una compilación con caché limpia que se haya realizado correctamente con tu archivo de bloqueo sin modificar demuestra que el código fuente sustitutivo es compatible con el conjunto de dependencias bloqueadas y que los paquetes descargados cumplen con las sumas de comprobación que espera Cargo. Al ejecutar cargo build --offline Posteriormente, se confirma que la compilación se completa sin necesidad de más acceso a la red, aunque no se confirma el origen de lo que ya está almacenado en la caché, por lo que para ello debes utilizar el registro de tráfico saliente o una regla de cortafuegos.

Resumen
Opciones de registro de carga privada y entrega de cajas verificada
Nombre del artículo
Opciones de registro de carga privada y entrega de cajas verificada
Descripción
En qué se diferencia un registro privado de carga del «vendoring» y el «mirroring», y qué cambia realmente en Cargo.lock cuando se aplican parches a las cajas.
Autor
Nombre del editor
TuxCare
Logotipo de la editorial

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.

Índice
Obtenga las respuestas de seguridad de código abierto que necesita

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.