Veamos cómo se ve realmente una cadena serializada cuando se serializa a una matriz de bytes. Tomé el código de muestra de esta guía .
Código:
// Java code for serialization and deserialization
// of a Java object
import java.io.*;
class Demo implements java.io.Serializable
{
public String s;
// Default constructor
public Demo(String s)
{
this.s = s;
}
}
class Test
{
public static void main(String[] args)
{
Demo object = new Demo("helloWorld");
String filename = "file.ser";
// Serialization
try
{
//Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
// Method for serialization of object
out.writeObject(object);
out.close();
file.close();
System.out.println("Object has been serialized");
}
catch(IOException ex)
{
System.out.println("IOException is caught");
}
}
}
Si veo el archivo binario serializado file.ser
veo: (en un editor de texto que la propiedad maneja binario, subiendo una captura de pantalla porque el editor SE no manejará los caracteres no imprimibles correctamente)
Sidesglosamoseso,vemos:
- Elnombredelobjetoserializado:
Demo
- Elnombredelobjetomiembroserializado:
java/lang/String
- Losdatosdeesteobjeto:
helloWorld
Summary:
SisololeestápermitiendoalatacantemodificarelcontenidodelaCadena(esdecir," helloWorld
", entonces no, no creo que sea posible romperlo. Sin embargo, si le está permitiendo al atacante modificar todo el flujo de bytes, luego puede reemplazar el nombre de la clase (es decir, " java/lang/string
") con cualquier clase de gadget que desee y comprometer su aplicación.
ACTUALIZAR para abordar este comentario:
¿no es ahí donde la visibilidad es útil para la seguridad? p.ej. si la clase "inyectada" no está en el paquete o es privada ... no hay posibilidad de acceder a ella. ¿Tengo razón?
Yo diría que no. No soy un experto, pero tengo entendido que el código de deserialización es parte de la JVM principal y, por lo tanto, ignora por completo los modificadores de acceso como protected
, private
. Prueba de concepto, considere una clase serializable con un miembro privado:
class Demo implements java.io.Serializable
{
public String pub;
private String priv;
// No-args constructor
public Demo() {
pub = "Public data";
priv = "Private data";
}
}
Cuando lo serializa y lo envía a través de la red, debe incluir al miembro privado, y el deserializador en el otro extremo debe poder reconstruirlo:
Agitemoselmitodequelapalabraclavejavaprivate
tienealgoqueverconlaseguridad.Esunaformaparaqueeldesarrolladorqueescribiólaclasediga"Oye, no deberías acceder a esto directamente" al desarrollador que usa la clase, pero de ninguna manera te impide usar la reflexión de Java para leer / modificar miembros o clases privadas. ¿Evita que los datos en miembros o clases privadas sean serializados / deserializados?