Skip to main content

Eliminación de datos confidenciales de un repositorio

Los datos confidenciales se pueden quitar del historial de un repositorio si puedes coordinarte cuidadosamente con todos los usuarios que los han clonado y estás dispuesto a administrar los efectos secundarios.

Acerca de eliminar datos confidenciales de un repositorio

Al modificar el historial del repositorio mediante herramientas como , es fundamental comprender las implicaciones. La reescritura del historial requiere una coordinación cuidadosa con los colaboradores para ejecutarse correctamente y conlleva una serie de efectos secundarios que se deben administrar.

Es importante tener en cuenta que si la información confidencial que necesitas quitar es un secreto (por ejemplo, contraseña, token o credencial), como suele ser el caso, como primer paso debes revocar o rotar ese secreto. Una vez que se revoca o rota el secreto, ya no podrá ser utilizado para acceder, y puede que esta medida sea suficiente para resolver su problema. Es posible que no esté justificado dar los pasos adicionales para reescribir el historial y quitar el secreto.

Efectos secundarios de la reescritura del historial

Hay muchos efectos secundarios que se derivan de la reescritura del historial, entre los que se incluyen los siguientes:

  • Alto riesgo de recontaminación: desafortunadamente, es fácil volver a subir los datos confidenciales al repositorio y empeorar la situación. Si un compañero desarrollador tiene un clon de antes de su reescritura, y después de su reescritura simplemente ejecuta seguido de , se devolverán datos confidenciales. Deben descartar su clon y volverlo a clonar, o bien seguir con atención varios pasos para limpiar primero su clon.
  • Riesgo de perder el trabajo de otros desarrolladores: si otros desarrolladores siguen actualizando ramas que contienen los datos confidenciales mientras intentas limpiar, se te obligará a rehacer la limpieza o a descartar su trabajo.
  • Hashes de confirmación modificados: la reescritura del historial cambiará los hashes de las confirmaciones que introdujeron los datos confidenciales ytodas las confirmaciones posteriores. Cualquier herramienta o automatización que dependa de que los hashes de confirmación no cambien dejará de funcionar o tendrá problemas.
  • Desafíos de protección de ramas: si tiene protecciones de ramas que impiden inserciones forzadas, esas protecciones tendrán que desactivarse (al menos temporalmente) para eliminar los datos confidenciales.
  • Vista de diferencias rota para las solicitudes de incorporación de cambios: la eliminación de los datos confidenciales requerirá quitar las referencias internas usadas para mostrar la vista de diferencias en las solicitudes de incorporación de cambios, por lo que ya no podrá visualizar estas diferencias. Esto es cierto no solo para la solicitud de incorporación de cambios que introdujo los datos confidenciales, sino para cualquier solicitud de incorporación de cambios que se basa en una versión del historial posterior a la combinación de la solicitud de incorporación de cambios de datos confidenciales (incluso si esas solicitudes de incorporación de cambios posteriores no agregaron ni modificaron ningún archivo con datos confidenciales).
  • Interacción deficiente con las solicitudes de incorporación de cambios abiertas: los SHA de confirmación modificados darán lugar a una diferencia de solicitud de incorporación de cambios diferente y las antiguas diferencias de las solicitudes de incorporación de cambios se pueden invalidar y perder, lo que puede provocar confusión para los autores y revisores. Se recomienda combinar o cerrar todas las solicitudes de incorporación de cambios abiertas antes de quitar archivos del repositorio.
  • Firmas perdidas en confirmaciones y etiquetas: las firmas para confirmaciones o etiquetas dependen de hashes de confirmación; dado que los hash de confirmación se modifican mediante reescrituras del historial, las firmas ya no serían válidas y muchas herramientas de reescritura del historial (incluidas ) simplemente quitarán las firmas. De hecho, también quitará las firmas de confirmación y las firmas de etiquetas para las confirmaciones anteriores a la eliminación de datos confidenciales. (Técnicamente, se puede solucionar con la opción en , si es necesario, pero deberá asegurarse de especificar todas las referencias que tengan datos confidenciales en su historial y que contengan las confirmaciones en las que se introdujeron los datos confidenciales en su rango).
  • Dirigir a otros usuarios directamente a los datos confidenciales: Git se diseñó con comprobaciones criptográficas integradas en identificadores de confirmación para que las personas malvadas no pudieran entrar en un servidor y modificar el historial sin que se note. Esto resulta útil desde una perspectiva de seguridad, pero desde una perspectiva de datos confidenciales significa que la supresión de datos confidenciales es un proceso de coordinación muy complejo; además, significa que cuando se modifica el historial, los usuarios astutos con un clon existente observarán la divergencia del historial y pueden usarlo para encontrar rápidamente y fácilmente los datos confidenciales todavía en su clon que quitaste del repositorio central.

Acerca de la exposición de datos confidenciales

La eliminación de datos confidenciales de un repositorio implica cuatro pasos generales:

  • Volver a escribir el repositorio localmente mediante git-filter-repo.
  • Actualice el repositorio en GitHub mediante el historial reescrito localmente.
  • Coordinarte con compañeros para limpiar otros clones que existan
  • Evitar repeticiones y futuros desbordamientos de datos confidenciales.

Si solo reescribe el historial y fuerza la inserción, es posible que las confirmaciones con datos confidenciales sigan siendo accesibles en otras ubicaciones.

  • En los clones o bifurcaciones de su repositorio
  • Directamente mediante sus hash SHA-1 en vistas almacenadas en caché en GitHub
  • A través de las solicitudes de cambios que hacen referencia a ellas

No puede eliminar de su repositorio datos confidenciales de los clones de otros usuarios; tendrá que enviarles las instrucciones del manual sobre cómo asegurarse de limpiar otras copias: clones de compañeros, para que lo hagan ellos mismos. Pero puedes quitar permanentemente las vistas almacenadas en caché y las referencias a los datos confidenciales en las solicitudes de incorporación de cambios en lGitHub poniéndote en contacto con el administrador del sitio.

Si el commit que introdujo los datos confidenciales existe en algún fork, seguirá siendo accesible allí. Deberá coordinarse con los propietarios de las bifurcaciones, pidiéndoles que eliminen los datos confidenciales o eliminen la bifurcación por completo.

Considera estas limitaciones y dificultades a la hora de tomar la decisión de reescribir el historial de tu repositorio.

Purga de un archivo del historial del repositorio local mediante git-filter-repo

  1. Instala la versión más reciente de la herramienta . Necesitas una versión con la marca , es decir, al menos la versión 2.47. Puede instalar manualmente o mediante un administrador de paquetes. Por ejemplo, para instalar la herramienta con HomeBrew, use el comando .

    brew install git-filter-repo
    

    Para más información, vea INSTALL.md en el repositorio .

  2. Clona el repositorio en el equipo local. Consulta AUTOTITLE.

    git clone https://HOSTNAME/YOUR-USERNAME/YOUR-REPOSITORY
    
  3. Vaya al directorio de trabajo del repositorio.

    cd YOUR-REPOSITORY
    
  4. Ejecuta un comando para limpiar los datos confidenciales.

    Si deseas eliminar un archivo específico de todas las ramas, etiquetas/refs, ejecuta el siguiente comando reemplazando por la ruta de acceso de Git al archivo que deseas quitar, no solo su nombre de archivo (por ejemplo, ):

    git-filter-repo --sensitive-data-removal --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
    

    Importante

    Si el archivo con datos confidenciales ya existía en alguna otra ruta (porque se movió o cambió de nombre), debes agregar un argumento extra para ese archivo, o ejecutar este comando una segunda vez nombrando la ruta alternativa.

    Si deseas reemplazar todo el texto que aparece en de cualquier archivo no binario que se encuentre en cualquier parte del historial del repositorio, ejecuta el siguiente comando:

    git-filter-repo --sensitive-data-removal --replace-text ../passwords.txt
    
  5. Comprueba que has quitado todo lo que querías del historial del repositorio.

  6. Averigua cuántas solicitudes de incorporación de cambios se verán afectadas negativamente por esta reescritura del historial. Necesitarás esta información a continuación.

    $ grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refs
    4
    

    Puede eliminar para ver qué solicitudes de incorporación de cambios se ven afectadas:

    $ grep '^refs/pull/.*/head$' .git/filter-repo/changed-refs
    refs/pull/589/head
    refs/pull/602/head
    refs/pull/604/head
    refs/pull/605/head
    

    Esta salida incluye el número de solicitudes de incorporación de cambios entre la segunda y la tercera barra diagonal. Si el número de solicitudes de incorporación de cambios afectadas es mayor de lo esperado, puedes descartar este clon sin efectos negativos y rehacer la reescritura o abandonar la eliminación de datos confidenciales. Una vez que pases al paso siguiente, la reescritura se vuelve irreversible.

  7. Una vez que estés satisfecho con el estado de su repositorio, fuerce la inserción de los cambios locales para sobrescribir el repositorio en tu instancia de GitHub Enterprise Server. Aunque está implícito en , lo incluimos a continuación como recordatorio de que estás actualizando forzosamente todas las ramas, etiquetas y referencias, y estás descartando los cambios que otros usuarios puedan haber realizado en esas referencias mientras estabas limpiando el repositorio.

    git push --force --mirror origin
    

    Este comando no podrá insertar ninguna referencia a partir de , ya queGitHub las marca como de solo lectura. Estos fallos de inserción se tratarán en la sección siguiente. Si alguna de las otras referencias no se puede insertar, es probable que tenga la protección de ramas habilitada para esa rama y tendrá que deshabilitarla temporalmente y volver a hacer la inserción. Repita el proceso hasta que los únicos fallos al actualizar sean referencias que comiencen con .

Eliminar los datos de GitHub por completo

Después de usar para quitar los datos confidenciales e insertar los cambios en GitHub, debes realizar algunos pasos adicionales para eliminar totalmente los datos de GitHub.

  1. Ponte en contacto con el administrador del sitioy proporciona la siguiente información:

    • El nombre del propietario y del repositorio en cuestión (por ejemplo, YOUR-USERNAME/YOUR-REPOSITORY).
    • El número de solicitudes de incorporación de cambios afectadas, que se encuentra en el paso anterior. El administrador del sitio lo usa para comprobar que comprendes cuánto se verá afectado.
    • Las primeras confirmaciones modificadas notificadas por (busca en tu salida).
    • Si aparece en la salida del repositorio git-filter-repo (justo después de la primera confirmación modificada), menciona que tenía objetos LFS huérfanos y carga también el archivo con nombre en el vale.

    Si has limpiado correctamente todas las referencias distintas de PR y ninguna bifurcación tiene referencias a los datos confidenciales, el administrador del sitio hará:

    • Desreferencia o elimina las solicitudes de incorporación de cambios afectadas en GitHub.
    • Ejecuta una recolección de basura en el servidor para suprimir los datos confidenciales del almacenamiento.
    • Quita las vistas almacenadas en caché.
    • Si hay objetos LFS involucrados, elimina y/o purga los objetos LFS huérfanos.

    Para obtener más información sobre cómo los administradores del sitio pueden quitar objetos Git inaccesibles, consulta AUTOTITLE. Para obtener más información sobre cómo los administradores del sitio pueden identificar confirmaciones accesibles, consulta Identificación de confirmaciones accesibles.

  2. Los colaboradores deben fusionar mediante cambio de base, no combinar, las ramas que hayan creado fuera del historial de repositorios antiguos (contaminado). Una confirmación de fusión podría volver a introducir algo o todo el historial contaminado sobre el que acabas de tomarte el trabajo de purgar. Es posible que también necesiten realizar pasos adicionales; consulte Asegurarse de limpiar otras copias: clones de compañeros en el manual.

Identificación de confirmaciones accesibles

Para eliminar completamente datos no deseados o confidenciales de un repositorio, es necesario que la confirmación que introdujo inicialmente los datos no tenga ninguna referencia en ramas, etiquetas, solicitudes de incorporación de cambios y bifurcaciones. Una sola referencia en cualquier lugar impedirá que el recolector de basura pueda eliminar los datos por completo.

Puede comprobar si hay referencias existentes mediante los siguientes comandos cuando se conecta al dispositivo a través de SSH. Necesitará el SHA del commit que introdujo originalmente los datos confidenciales.

ghe-repo OWNER/REPOSITORY -c 'git ref-contains COMMIT_SHA_NUMBER'
ghe-repo OWNER/REPOSITORY -c 'cd ../network.git && git ref-contains COMMIT_SHA_NUMBER'

Si cualquiera de estos comandos devuelve algún resultado, deberá eliminar esas referencias para que se puedan recopilar correctamente los elementos no utilizados de la confirmación. El segundo comando identificará las referencias que existen en bifurcaciones del repositorio (si el repositorio no tiene bifurcaciones, puede omitir su ejecución).

  • Los resultados que comienzan por o indican ramas y etiquetas, respectivamente, que siguen teniendo referencias a la confirmación infractora, lo que sugiere que la confirmación no se ha eliminado por completo del repositorio modificado o que no se ha insertado a la fuerza.
  • Los resultados que comienzan por o indican solicitudes de incorporación de cambios que hacen referencia a la confirmación infractora. Estas solicitudes de incorporación de cambios deben eliminarse para permitir la recopilación de los elementos no utilizados de la confirmación. Una solicitud de incorporación de cambios se puede eliminar en el panel de administración del sitio en ; sustituyendo por el número de solicitud de incorporación de cambios.

Si las referencias se encuentran en cualquier bifurcación, los resultados tendrán un aspecto similar, pero comenzarán por . Para identificar la bifurcación por nombre, puede ejecutar el siguiente comando.

ghe-nwo NWO

Los datos confidenciales se pueden quitar de las bifurcaciones de un repositorio. Para ello, vaya a un clon de uno de ellos, recupere del repositorio limpiado, y luego fusione mediante cambio de base todas las ramas y etiquetas que contengan los datos confidenciales sobre la rama o etiqueta pertinente del repositorio limpiado. Como alternativa, las bifurcaciones se pueden eliminar por completo y, si es necesario, el repositorio se puede volver a bifurcar una vez completada la limpieza del repositorio raíz.

Una vez que haya eliminado las referencias de la confirmación, vuelva a ejecutar los comandos para comprobarlo.

Si no hay resultados de ninguno de los comandos , puede ejecutar la recopilación de elementos no utilizados con la marca para eliminar las confirmaciones sin referencia ejecutando el siguiente comando.

ghe-repo-gc -v --prune OWNER/REPOSITORY

Una vez que la recolección de basura haya eliminado correctamente la confirmación, navegue al panel de administración del sitio del repositorio, seleccione Red y, a continuación, haga clic en Invalidar la caché de Git para eliminar los datos almacenados en caché.

Evitar confirmaciones accidentales en el futuro

Impedir que los colaboradores realicen confirmaciones accidentales puede ayudarte a evitar que se exponga información confidencial. Para obtener más información, consulta AUTOTITLE.

Hay algunas cosas que puede hacer para evitar confirmar o insertar elementos que no deben compartirse:

  • Si es probable que los datos confidenciales se encuentren en un archivo al que Git no debe realizar el seguimiento, agrega ese nombre de archivo a (y asegúrate de confirmar e insertar ese cambio en para que otros desarrolladores estén protegidos).
  • Evita secretos codificados de forma rígida en el código. Use variables de entorno o servicios de administración de secretos como Azure Key Vault, AWS Secrets Manager o HashiCorp Vault para administrar e insertar secretos en tiempo de ejecución.
  • Crea un hook de pre-confirmación para comprobar si hay datos confidenciales antes de confirmarlos o empujarlos a cualquier destino, o bien usa una herramienta conocida en un hook de pre-confirmación, como git-secrets o gitleaks. (Asegúrate de pedir a cada colaborador que configure el enlace de confirmación previa que has elegido).
  • Use un programa visual como GitHub Desktop o gitk para confirmar los cambios. Los programas visuales suelen hacer que sea más sencillo ver exactamente qué archivos se agregarán, eliminarán y modificarán con cada confirmación.
  • Evite los comandos generales y en la línea de comandos; en su lugar use y para agregar al "stage" los archivos de manera individual.
  • Use para revisar y agregar al "stage" los cambios en cada archivo.
  • Use a fin de revisar los cambios que ha agregado al "stage" para la confirmación. Esta es la diferencia exacta que producirá siempre que no use la marca .
  • Habilita la protección de inserción para que el repositorio detecte e impida que las inserciones que contienen secretos codificados de forma rígida se confirmen en el código base. Para más información, consulta AUTOTITLE.

Información adicional

  • página del manual, especialmente la subsección "Eliminación de datos confidenciales" de la sección "discusión".
  • Pro Git: Herramientas de Git - Reescritura del historial
  • AUTOTITLE