¿Por qué es una mala idea almacenar contraseñas en el control de versiones?

Mi amigo me preguntó: "¿por qué es realmente tan malo poner varias contraseñas directamente en el código fuente del programa, cuando solo las almacenamos en nuestro servidor Git privado?"

Le di una respuesta que destacaba un par de puntos, pero sentí que no estaba lo suficientemente organizada y decidí que esto podría tener sentido para crear una pregunta canónica.

Además, ¿cómo el almacenamiento de contraseñas en el código fuente no se relaciona con el principio de privilegios mínimos y otros fundamentos de la seguridad de la información?

117
@DaveCarruthers Muchas configuraciones usan variables de entorno en su lugar. Se llenan a mano (por ejemplo, para trabajo de desarrollo) o desde un valor encriptado (por ejemplo, Travis CI ) o a través de una base de datos cifrada (por ejemplo, HashiCorp Vault ) oa través de un servicio seguro (ej. Heroku). La idea es reducir su superficie de ataque a una sola clave almacenada en un demonio (como Vault) o en un servicio (como Heroku o Travis).
agregado el autor danieltalsky, fuente
Uber recientemente descubrió de manera difícil que esta es una mala idea.
agregado el autor Jesse Vogt, fuente
agregado el autor devlop, fuente
Una buena razón es que significa que necesitaría dos procesos diferentes para productos de código abierto y de código cerrado. Definitivamente no puede almacenar contraseñas en el control de código fuente para productos de código abierto. Más sencillo si se utiliza un proceso común.
agregado el autor Erik vanDoren, fuente
@DaveCarruthers Puede almacenar un archivo de configuración de ejemplo en su repositorio y agregar manualmente ese archivo de configuración en la primera implementación, o puede almacenar las contraseñas de texto plano en variables de CI como Gitlab y generar esos archivos de configuración + implementar en una secuencia de comandos de CI, que oculta esa información del uso diario, a menos que tenga derechos de administrador/haya comprometido el servidor privado de git.
agregado el autor Jacque Goupil, fuente
¿Para qué son estas contraseñas?
agregado el autor Sean, fuente
Es más bien un concepto de la industria, el giro del desarrollador, la separación del rol de los operadores de desarrollo, el control general y tener múltiples entornos para una aplicación, todas las razones no tienen contraseñas en el código (fuente, si lo desea).
agregado el autor pogo, fuente
¿Qué tiene de malo usar control de versión para las contraseñas? /deliberada interpretación errónea
agregado el autor jsHate, fuente
Porque no quieres un Factura de $ 14,000 de AWS .
agregado el autor caceves, fuente
En este punto, pensé que era muy apreciado que solo las contraseñas de hash (tal vez con "sal", etc.) debían almacenarse en algún lugar ...?
agregado el autor GilbertErik, fuente
La respuesta es bastante breve, porque nunca debe almacenar una contraseña en texto sin formato. Ni siquiera en un archivo llamado TotallyNotMyPasswords.txt. En ninguna parte.
agregado el autor user149788, fuente
@DaveCarruthers Hay configuraciones en las que esto es posible (por ejemplo, con Windows y autenticación AD) además de eso, las contraseñas se pueden guardar en configuración protegida
agregado el autor user149788, fuente
¿Por qué los devs incluso saben las contraseñas para cualquier entorno además de dev/test?
agregado el autor pinguinos, fuente
@EpicKip buena suerte implementando cualquier tipo de servidor web sin contraseñas de texto sin formato almacenadas en cualquier archivo.
agregado el autor Ted, fuente
Me gustaría una pequeña aclaración: ¿Las respuestas a esta pregunta deberían centrarse en el aspecto de seguridad del almacenamiento de contraseñas en el control de versiones? (Creo que sí, porque está publicado en "seguridad de la información"). Pensé en esta pregunta y creo que hay razones para no almacenar la contraseña junto con el código fuente que va más allá de la seguridad.
agregado el autor user156489, fuente

8 Respuestas

La forma en que lo veo, no almacenar contraseñas en Git (u otro control de versión) es una convención . Supongo que uno podría decidir no imponerlo con varios resultados, pero aquí está la razón por la que esto es generalmente mal visto:

  1. Git hace que sea difícil eliminar las contraseñas del historial del código fuente, lo que podría dar a las personas una idea falsa de que la contraseña ya se eliminó en la versión actual.
  2. Al poner la contraseña en el control de origen, básicamente decide compartir la contraseña con cualquier persona que tenga acceso al repositorio, incluidos los futuros usuarios. Esto complica el establecimiento de roles dentro de un equipo de desarrolladores, lo que podría tener diferentes privilegios.
  3. El software de control de fuente tiende a ser bastante complicado, especialmente los sistemas "todo en uno". Esto significa que existe un riesgo de que este sistema pueda verse comprometido, lo que podría provocar una pérdida de la contraseña.
  4. Otros desarrolladores pueden ignorar que la contraseña está almacenada y manejar mal el repositorio; tener claves en la fuente significa que se debe tener un cuidado especial al compartir el código (incluso dentro de la empresa; esto podría crear una necesidad de cifrado. canales).

I no puedo decir que todos los patrones relacionados con infosec son buenos , pero antes de romperlos, siempre es una buena idea considerar su Modelo de amenaza y vectores de ataque. Si esta contraseña en particular se filtró, ¿qué tan difícil sería para un atacante usarla para dañar a la compañía?

138
agregado
Me refiero a que "las cosas que otras personas hacen" la convención funciona, pero también puede significar que "otras personas (conocedoras) piensan que es una buena idea y es un lugar común por una razón".
agregado el autor Sarah Jean, fuente
Eso es una toma justa.
agregado el autor Sarah Jean, fuente
No estoy seguro de que sea justo llamar a un anti-patrón conocido de "contraseñas cortas" una "convención infosec".
agregado el autor Sarah Jean, fuente
Además del artículo 4, git es un sistema repo distribuido. Cualquiera que pueda clonar el repositorio a, digamos, una computadora portátil de desarrollo podría perder esa computadora portátil, y ahora las contraseñas son parte de esa violación de datos.
agregado el autor jdinunzio, fuente
Tenga en cuenta que al eliminar contraseñas del control de código fuente, no necesita eliminarlas del historial: solo necesita cambiar las contraseñas.
agregado el autor Albert, fuente
La "convención", para mí, implica que "en general, todos están de acuerdo en hacerlo de esta manera, a pesar de que no tiene ninguna ventaja particularmente significativa, aparte de que todos están de acuerdo en que se debe hacer de esta manera", pero está dando algunas declaraciones bastante significativas. Ventajas, que se inclina más hacia "esta es una mala idea". Eliminar las partes sobre la convención mejoraría bastante la respuesta IMO.
agregado el autor NeilS, fuente
Estoy con @Adonalsium: la convención no logra transmitir su significado y hay mejores términos disponibles: mala idea. innecesariamente arriesgado etc
agregado el autor 3498DB, fuente
@Adonalsium Lo que quise decir es que es un patrón relacionado con infosec que no se encuentra dentro de las mejores prácticas y no se deberían seguir los patrones de otras personas sin pensar.
agregado el autor user15648, fuente
@NotThatGuy No, convención significa "todos en general aceptan hacerlo de esta manera". Es importante tener en cuenta, porque seguir las convenciones es generalmente muy importante y valioso por derecho propio.
agregado el autor user1472751, fuente
Además, y en menor grado, la contraseña historial está expuesta. Si la contraseña ha sido cambiada a lo largo del tiempo, conocer las contraseñas anteriores puede ser útil para adivinar que las contraseñas futuras deben ser revocadas.
agregado el autor roberto06, fuente
Me gustaría agregar que en muchos entornos, a los desarrolladores no se les permite el acceso a los sistemas de producción y ops/admins tendrán que mantener todas las contraseñas. Dado que las contraseñas caducarán en 45/60/90/180 días en muchos sistemas, los desarrolladores no pueden mantener las contraseñas y no desea que ops tenga que ingresar el código, por lo que debe ingresar todas las credenciales. un archivo de configuración independiente y cuando ops implementa la compilación, colocan las contraseñas de producción actuales en el archivo de configuración y actualizan ese archivo cuando las contraseñas caducan. Es posible que los desarrolladores que no conozcan las contraseñas de producción sean legalmente requeridos en los sistemas federales.
agregado el autor pinguinos, fuente
@OrangeDog, a menos que el historial de contraseñas sea un buen indicador para futuras contraseñas (lo que no se cumple si sus contraseñas son seguras y aleatorias, pero esto no siempre es así).
agregado el autor Syzyy77, fuente
Además, puede haber empleados que trabajen ocasionalmente desde casa. Algunos de estos (y he conocido algunos) usan su PC doméstico para desarrollar, en lugar del portátil de la empresa. Esto significa confiar en la seguridad de la PC de su hogar en lugar de la de la empresa.
agregado el autor Craig P, fuente

Primero, la razón de no seguridad:

Flujo de trabajo de cambio de contraseña

Las contraseñas cambian independientemente de un código de aplicación de software. Si un DBA cambia la contraseña de una base de datos, ¿tiene sentido que los desarrolladores tengan que actualizar el código, obtener una nueva compilación y lanzamiento para producción e intentar cronometrarlo todo? Las contraseñas son un artefacto de configuración en tiempo de ejecución, no un artefacto de desarrollo. Deben inyectarse a través de archivos de configuración, variables de entorno o cualquier paradigma de configuración que esté utilizando.

Ámbito de autorización

En general, los sistemas de control de versiones proporcionan control de autorización para que solo los usuarios autorizados puedan acceder a él. Pero dentro de un repositorio, los permisos son generalmente de lectura/escritura, o de solo lectura, o posiblemente algunas campanas y silbidos como GitHub proporciona. Es poco probable que encuentre restricciones de seguridad que permitan a los desarrolladores obtener el código fuente, pero las contraseñas no . Si puede clonar un repositorio, puede clonar un repositorio. Período. En muchos entornos, los desarrolladores no tienen acceso completo a la producción. A veces tienen acceso de solo lectura a bases de datos de producción, a veces no tienen acceso. ¿Qué sucede si los desarrolladores generalmente tienen acceso, pero no desea que todos los internos, nuevas contrataciones, etc. tengan acceso?

Entornos

¿Qué sucede si tiene varios entornos, como un entorno de desarrollo, un entorno de control de calidad, una puesta en escena y producción? ¿Almacenarías todas sus contraseñas en el control de versiones? ¿Cómo sabría la aplicación cuál usar? La aplicación debería tener una forma de conocer el entorno, lo que terminaría siendo un ajuste de configuración. Si puede hacer del nombre del entorno un ajuste de configuración, puede hacer que la contraseña de la base de datos sea un ajuste de configuración (junto con la cadena de conexión, el nombre de usuario, etc.)

Historia

Como otros han mencionado, el control de versiones está diseñado para preservar la historia. Por lo tanto, las contraseñas más antiguas aún serán recuperables, lo que puede no ser lo mejor.

Compromiso

¿Cuántas veces hemos visto titulares en las noticias sobre el código fuente de algún producto que se está filtrando al mundo? El código fuente es lo que está en el control de versiones. ¡Esta es probablemente la razón principal para no poner contraseñas en el control de versiones!

Sin embargo ...

Dicho esto, las contraseñas deben almacenarse en algún lugar . Lo que se refiere a las preocupaciones anteriores no es necesariamente que no deban almacenarse en el control de versiones, sino que no deben almacenarse en el repositorio de código fuente del producto en el control de versiones. Tener un repositorio separado para la administración de configuraciones, operaciones, etc. es muy razonable. La clave es dividir las operaciones del desarrollo cuando se trata de credenciales de seguridad, no necesariamente para evitar por completo el control de versiones.

Además, para entornos que no son de producción, he almacenado contraseñas y claves de API para sistemas externos en archivos de configuración dentro del código fuente del producto como valores predeterminados. ¿Por qué? Para hacer que sea más fácil cuando un desarrollador revisa el código, puede simplemente compilarlo y ejecutarlo sin tener que ir a buscar archivos de configuración adicionales. Estas son credenciales que rara vez cambian y no conducen a ningún secreto comercial. Pero nunca haría esto con secretos de producción.

Así que la línea de fondo es ... depende.

90
agregado
@TobySpeight Debemos tener definiciones muy diferentes de "imposible". En un entorno de desarrollo sería bastante extraño cambiar las contraseñas de todos modos, después de todo, no son un secreto, por lo que rara vez hay una razón para cambiarlas. Y si lo hay, debería ser trivial reemplazar los archivos de configuración antiguos con los nuevos como parte de su secuencia de comandos bisect. Quiero decir que es, con mucho, la parte más fácil del script que tiene que construir todo el proyecto y luego hospedarlo.
agregado el autor Cascabel, fuente
Su primer punto es más grande de lo que parece: tener contraseñas vinculadas a la versión del código fuente puede hacer imposible git-bisect de manera confiable para encontrar cuándo se originaron los errores, por ejemplo.
agregado el autor brandonmack, fuente
+1 por sugerir un repositorio separado con más acceso granular.
agregado el autor Mauro Rocha, fuente

Siempre es importante tener en cuenta que las sugerencias deben adaptarse a su caso de uso. Las salvaguardas de seguridad adoptadas por, digamos, la NSA para proteger todos los días cero que mantienen durante un día lluvioso deben ser mucho más estrictas que las salvaguardas de seguridad tomadas para proteger los votos en un sitio de publicación de imágenes de gatos. En un extremo, puedo pensar en un ejemplo cuando mantener las contraseñas/tokens/etc en un repositorio privado de git podría ser razonable:

Si solo una persona accede al repositorio y la aplicación no almacena ninguna información de ningún valor.

En ese caso, vete a la ciudad! Simplemente tenga en cuenta lo que dijo @ d33tah en su respuesta: limpiar las cosas de un repositorio de git puede ser sorprendentemente difícil (todo el punto, después de todo, es mantener un historial de todo para siempre), así que si decide hacerlo, decida que quiere colabore con más personas pero no quiera que obtengan acceso total a todos sus sistemas, entonces tendrá un poco de dolor de cabeza en sus manos.

Eso es lo que realmente se reduce a Su repositorio de código es de alguna manera "público", incluso si solo se comparte con los colaboradores. El hecho de que quiera colaborar con alguien no significa que quiera darles acceso completo a su infraestructura (que es lo que sucede cuando coloca contraseñas/tokens en su repositorio de códigos). Es fácil pensar "sí, pero confío en las personas con las que estoy colaborando", pero esa es simplemente la forma incorrecta de ver el escenario, por varias razones:

  1. En la práctica real, una gran parte de las filtraciones de datos comienzan con actores internos (colaboradores, empleados). Por un estudio aproximadamente el 43% de Las violaciones de datos comenzaron con un actor interno. La mitad de ellos fueron intencionales y la otra parte accidentales.
  2. El último punto es importante y por qué no se trata solo de confianza. Aproximadamente el 20% de las violaciones de datos son accidentales y causadas por personas internas. Soy lo suficientemente inteligente como para saber que no soy lo suficientemente inteligente como para que todo esté bien todo el tiempo. ¿Qué sucede si convierto el repositorio en público para dejar espacio para una herramienta de integración divertida y olvido que tengo credenciales en ella? ¿Qué sucede si tengo un disco duro de copia de seguridad que olvidé cifrar y sale de mi oficina? ¿Qué sucede si una de mis contraseñas se filtra y alguien la usa para adivinar la contraseña de la cuenta a mi repositorio de git ( tos gentoo github repositorio tos )? Hay una serie de errores accidentales que I puede hacer que puedan exponer mi repositorio git, y si eso sucede y tengo credenciales allí y la persona que los encuentra sabe lo que están mirando, podría muy bien ser indagada. Eso suena como un montón de y pero la realidad es que así es como ocurren las brechas.
  3. Incluso si confío en alguien, eso no significa que tenga que darles acceso completo a todo [Insertar una cita cursi sobre cómo corrompe el poder]. Una vez más, colocar las credenciales en un repositorio git significa que potencialmente estoy dando acceso completo a toda mi infraestructura a todos mis colaboradores. Siempre existe la posibilidad de que no conozcas a esa persona tan bien como crees, y podrían decidir hacer algo que no deberían. Incluso si conoces personalmente y confías en todos y cada uno de tus colaboradores con tu vida, eso no significa que no cometan algunos de los errores anteriores (o cualquiera de las infinitas opciones que no mencioné) para liberar accidentalmente tu código.

En resumen, una buena seguridad es tener defensas en capas. La mayoría de los hacks ocurren porque los hackers encuentran debilidades en un área que les permite explotar las debilidades en otra área, lo que lleva a otra parte, lo que finalmente los lleva a la gran ganancia . Tener tantas salvaguardas de seguridad como convenga para su situación es lo que mantiene todo seguro. De esta manera, cuando un disco duro de copia de seguridad sale de su oficina y se da cuenta de que no estaba cifrado, no tiene que preguntar "¿Fue este un ataque dirigido y ahora tengo que cambiar cada credencial que tengo en todas partes porque? estaban todos en el repositorio de git en esa unidad de copia de seguridad? ". De nuevo, dependiendo de su situación, es posible que esto no se aplique a usted, pero esperamos que esto ayude a explicar en qué escenarios podría ser importante.

25
agregado
+1 por "... así es como ocurren las brechas". La vida es caóticamente aleatoria, y es absolutamente sorprendente la cantidad de veces que una larga serie de actos aparentemente aleatorios pueden coludirse para formar el accidente perfecto (brechas, incendios, colisiones de vehículos). Mantener la contraseña fuera del repositorio elimina la posibilidad de que una infracción exponga la contraseña.
agregado el autor chappar, fuente

Esta convención, al igual que muchas otras "mejores prácticas" de seguridad, es una forma práctica de asegurarse de que las cosas no salgan mal debido a los malos hábitos o la rutina.

If you always remember that your sensitive passwords are in your version control system and if you never give anyone who shouldn't have the password access to the repository and if your repository is stored as safely as these secrets require and if your deployment process is likewise safe, secure and protected from unauthorized people and if you can be sure that all the backups and copies of your repository are and... you can probably add a couple more "if"s specific to your context.

... entonces puede almacenar sus contraseñas en su sistema de control de versiones.

En la mayoría de los casos, al menos uno de esos "si" no cumple lo suficiente con sus condiciones o está fuera de su control.

Por ejemplo, en muchas configuraciones, sus desarrolladores no deberían tener acceso a la base de datos de producción. O el sistema de respaldo está subcontratado a otro departamento. O su proceso de construcción se subcontrata a la nube.

Por eso, en general , no almacenar sus contraseñas en su sistema de control de versiones es una buena práctica que garantiza que no caiga en una de esas trampas porque no pensó en ellas. "no hay contraseñas en git" es más fácil de recordar que una larga lista de condiciones que debe cumplir para almacenar de forma segura las contraseñas bajo el control de versiones.

12
agregado

Mantener los secretos (contraseñas, certificados, claves) separados del código fuente permite administrar las fuentes y los secretos de acuerdo con las diferentes políticas. Al igual que todos los ingenieros pueden leer el código fuente, solo las personas que son directamente responsables de los servidores de producción pueden acceder a los secretos.

Esto hace la vida más fácil para los desarrolladores porque no están sujetos a las estrictas políticas de seguridad que se necesitan para proteger los secretos. Las políticas de control de fuente se pueden hacer mucho más convenientes para ellos.

12
agregado
@MontyHarder Eso definitivamente se debe a la tensión entre el objetivo de las operaciones de "no romper, y no perder" y el objetivo de desarrollo "arreglar las cosas ahora".
agregado el autor Brian De Smet, fuente
@WayneWerner No es solo "no se rompa, y no se escape", es "asegúrese de que pueda replicar esto de manera confiable". La separación de roles entre dev y ops los obliga a comunicar explícitamente las dependencias para que podamos hacer esa replicación confiable. Repárelo ahora en dev, documente para mí lo que hizo para solucionarlo, así puedo solucionarlo en el control de calidad, y si eso no funcionó, no lo documentó lo suficientemente bien. Inténtalo de nuevo.
agregado el autor KS.Pan, fuente
Como persona directamente responsable de los servidores de producción, puedo decirle que bajo ninguna circunstancia quiero que los desarrolladores tengan credenciales de control de calidad o entorno de producción. Si los tienen, entonces "arreglarán" un problema, modificando las cosas hasta que empiecen a trabajar, no documentarán sus cambios y todo se derrumbará porque la proporción de Wolfsbane con Eye of Newt está desactivada. Haga lo que quiera en su entorno Dev, pero dame un paquete de código limpio para implementarlo, con la documentación de lo que tengo que hacer para que funcione, y el único acceso que puedo otorgarle es de solo lectura para los registros.
agregado el autor KS.Pan, fuente

Otras respuestas son excelentes, pero considere también el problema de las copias de seguridad. Tiene mucha más flexibilidad sobre dónde, cómo y durante cuánto tiempo almacena las copias de seguridad del repositorio de códigos si no contienen información confidencial sobre cómo acceder a las cuentas de su servidor o administrador.

Desde otro ángulo más centrado en la seguridad, solo su copia de seguridad de código podría ser un objetivo interesante para los competidores poco éticos en su negocio. Dependiendo de su negocio, la mayoría de los competidores en un país de "ley de derecho" no lo tocarían de todos modos. Una copia de seguridad de código con contraseñas será un objetivo para cualquier organización delictiva que esté interesada en los datos de sus usuarios o que esté interesada en chantajear a su empresa.

El daño de una violación del repositorio de código sería mayor con las contraseñas por razones similares. ¿Prefiere que le roben y publiquen su código fuente, o que todos sus usuarios estén expuestos al robo de identidad, con una demanda potencial o incluso un caso penal en su contra por no asegurar su información privada (piense en GDPR)?

4
agregado

"¿Por qué es realmente tan malo poner tus llaves directamente en tu puerta principal, cuando vivimos lejos de la civilización?"

Debido a que las personas que quieren hacer cosas malas, lo harán con facilidad y el costo de hacer cosas difíciles para ellos no es demasiado alto. Mantenga sus llaves con usted no al lado de la puerta. Sentido común.

Repo privado? ¿Cuántas personas tienen acceso para descargarlo? ¿Y cuántas personas están conectadas a sus computadoras? Y luego ... ¿Están todos libres de peligro?

2
agregado
Para ampliar la metáfora: ¿Hacemos una copia de las llaves de la puerta de la oficina para cada empleado o simplemente las entregamos según sea necesario?
agregado el autor TN., fuente

También depende del sistema de control de código fuente.

Git tiene la actitud de que el sistema de control de código fuente debería darle un historial confiable del proyecto. Que no es una mala actitud tener. Pero existe el efecto de que si ingresó una contraseña en git, es muy difícil eliminarla de su repositorio.

Perforce tiene un comando "borrar" para ese propósito. Si ingresó una contraseña, o alguien registró un archivo de video sin comprimir de 8 gigabytes, o alguien ingresó un código de terceros que infringe los derechos de autor de alguien y nunca debería haber ingresado, o alguien que fue despedido registró muchas pornografías en Su último día en el trabajo, puedes "borrarlo". Se ha ido completamente del repositorio y de la historia.

1
agregado