Jan Ouwens
February 23, 2018
Jan Ouwens
EqualsVerifier.forClass(Foo.class)
.verify();
Happy accidents
Evil consequences
Demo
Demo
Demo
Scala demo
Kotlin demo
Rating: ☠️💣
Demo
Demo
Demo
However…
Demo
Demo
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by demos.reflection.CallOfTheVoid (file:/Users/jqno/w/personal/dont-hack-the-platform-talk/target/classes/) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of demos.reflection.CallOfTheVoid
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
--add-opens java.base/java.lang=ALL-UNNAMED
[INFO] --- kotlin-maven-plugin:1.2.20:compile (compile) @ dont-hack-the-platform ---
WARNING: An illegal reflective access operation has occurred
Rating: ☠️
Demo
Was this hack evil? ✋
Are Calendars and arrays evil? ✋
Are JPA entities evil? 👹
Rating: ☠️💣💥
Demo
Demo
close()
on URLClassLoader
CompilationTask
¯\_(ツ)_/¯
@Test
public void equalsverifierSucceeds_whenOneOfTheFieldsIsSynthetic() {
if (!isJava8Available()) {
return;
}
Class<?> java8ClassWithSyntheticField = compile(JAVA_8_CLASS_WITH_SYNTHETIC_FIELD_NAME, JAVA_8_CLASS_WITH_SYNTHETIC_FIELD);
EqualsVerifier.forClass(java8ClassWithSyntheticField)
.verify();
}
private static final String JAVA_8_CLASS_WITH_SYNTHETIC_FIELD_NAME = "Java8ClassWithSyntheticField";
private static final String JAVA_8_CLASS_WITH_SYNTHETIC_FIELD =
"\nimport java.util.Comparator;" +
"\nimport java.util.Objects;" +
"\n" +
"\npublic final class Java8ClassWithSyntheticField {" +
"\n private static final Comparator<Java8ClassWithSyntheticField> COMPARATOR =" +
"\n (c1, c2) -> 0; // A lambda is a synthetic class" +
"\n" +
"\n private final String s;" +
"\n " +
"\n public Java8ClassWithSyntheticField(String s) {" +
"\n this.s = s;" +
"\n }" +
"\n " +
"\n @Override" +
"\n public boolean equals(Object obj) {" +
"\n if (!(obj instanceof Java8ClassWithSyntheticField)) {" +
"\n return false;" +
"\n }" +
"\n return Objects.equals(s, ((Java8ClassWithSyntheticField)obj).s);" +
"\n }" +
"\n " +
"\n @Override" +
"\n public int hashCode() {" +
"\n return Objects.hash(s);" +
"\n }" +
"\n}";
Rating: ☠️💣💥
use annotations
to trick the Java compiler
into generating bytecode
that does something else
use annotations
to trick the Java runtime
into generating bytecode
that does something else
Rating: ☠️
Objenesis
Demo
Rating: ☠️
“[An enum] provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. […] A single-element enum type is often the best way to implement a singleton”
– Joshua Bloch, Effective Java 3rd Edition
😇
Demo
Rating: ☠️💣
Demo
Rating: ☠️💣💥
Demo
Rating: ☠️💣
ByteBuddy
&
ByteBuddy Agent
Use cases for agents
Demo
Idea shamelessly stolen from
/TOPdesk/time-transformer-agent
There’s more
Demo
mvn clean package
mvn exec:java -DmainClass=demos.libraries.RemoteTimeTraveling -Darg0=target/dont-hack-the-platform-0.1-SNAPSHOT.jar -Darg1=???
Demo
System.setSecurityManager(new SecurityManager());
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by demos.reflection.CallOfTheVoid (file:/Users/jqno/w/personal/dont-hack-the-platform-talk/target/classes/) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of demos.reflection.CallOfTheVoid
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
--illegal-access=deny
Maybe not at work though?
slides & code at
/jqno/dont-hack-the-platform-talk
me at
jqno