From 8b115f4c8a75956caf964ae1d14dbe8a3f78cfaa Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Thu, 13 May 2021 20:48:03 +0100 Subject: [PATCH] BAEL-4946 added in code for java deserialization vulnerabilities article --- .../vulnerabilities/BadThing.java | 28 ++++++++++++++ .../vulnerabilities/MyCustomAttackObject.java | 14 +++++++ .../vulnerabilities/BadThingTest.java | 38 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/BadThing.java create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/MyCustomAttackObject.java create mode 100644 core-java-modules/core-java/src/test/java/com/baeldung/deserialization/vulnerabilities/BadThingTest.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/BadThing.java b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/BadThing.java new file mode 100644 index 0000000000..ce13a9c372 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/BadThing.java @@ -0,0 +1,28 @@ +package com.baeldung.deserialization.vulnerabilities; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Method; + +public class BadThing implements Serializable { + private static final long serialVersionUID = 0L; + + Object looselyDefinedThing; + String methodName; + + private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { + ois.defaultReadObject(); + try { + Method method = looselyDefinedThing.getClass().getMethod(methodName); + method.invoke(looselyDefinedThing); + } catch (Exception e) { + // handle error... + } + } + + private void writeObject(ObjectOutputStream oos) throws IOException { + oos.defaultWriteObject(); + } +} diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/MyCustomAttackObject.java b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/MyCustomAttackObject.java new file mode 100644 index 0000000000..9b4e2d4b76 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/vulnerabilities/MyCustomAttackObject.java @@ -0,0 +1,14 @@ +package com.baeldung.deserialization.vulnerabilities; + +import java.io.IOException; +import java.io.Serializable; + +public class MyCustomAttackObject implements Serializable { + public static void methodThatTriggersAttack() { + try { + Runtime.getRuntime().exec("echo \"Oh, no! I've been hacked\""); + } catch (IOException e) { + // handle error... + } + } +} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/deserialization/vulnerabilities/BadThingTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/deserialization/vulnerabilities/BadThingTest.java new file mode 100644 index 0000000000..1d12403bec --- /dev/null +++ b/core-java-modules/core-java/src/test/java/com/baeldung/deserialization/vulnerabilities/BadThingTest.java @@ -0,0 +1,38 @@ +package com.baeldung.deserialization.vulnerabilities; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class BadThingTest { + + @Test + public void testCodeExecution() throws Exception { + BadThing bt = new BadThing(); + + bt.looselyDefinedThing = new MyCustomAttackObject(); + bt.methodName = "methodThatTriggersAttack"; + + byte[] serializedObject = serialize(bt); + + try (InputStream bis = new ByteArrayInputStream(serializedObject); + ObjectInputStream ois = new ObjectInputStream(bis)) { + + ois.readObject(); // malicious code is run + } + } + + private static byte[] serialize(Object object) throws Exception { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + + oos.writeObject(object); + oos.flush(); + return bos.toByteArray(); + } + } +} \ No newline at end of file