Bezpieczeństwo w aplikacjach Java
Weryfikacja kodu bajtowego Można wyłączyć podając w linii komend którąś z opcji: -Xverify:none lub -noverify jednak nie jest to zalecane https://stackoverflow.com/questions/2554 1778/does-verification-of-byte-codehappen-twice https://wiki.sei.cmu.edu/confluence/disp lay/java/env04- J.+Do+not+disable+bytecode+verification https://docs.oracle.com/javase/specs/jvm s/se8/html/jvms-4.html#jvms-4.10
Drukowanie informacji na standardowy wyjście printstacktrace zwykle używane do debuggowania, może doprowadzić do wycieku danych import java.io.ioexception; public class A { public static void main(string... args) { try { throw new NullPointerException(); catch (NullPointerException e) { System.out.println(e); java.lang.nullpointerexception Error: null try { java.io.ioexception throw new IOException(); at A.main(A.java:11) catch (IOException e) { System.out.println(e.getMessage()); e.printstacktrace(); System.exit(0);
Łamanie praw dostępu oraz interpretacji zakresu Mechanizmy, którymi można obejść reguły wyznaczone przez modyfikatory dostępu serializacja obiektów: Serializable i użycie transient refleksja: getdeclaredfield, getdeclaredmethod Zakres pola statyczne: static jeśli to ma być wartość niezmieniana, to z modyfikatorem final ograniczenie dziedziczenia jeśli klasa finalna, to z modyfikatorem final
Przykład (serializacja i wyjątki) import java.io.*; class Student implements Serializable { int id; String name; transient int age; public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; try z okrągłymi nawiasami można stosować do obiektów implementujących java.lang.autocloseable, do których public class B { należą obiekty implementujące java.io.closeable public static void m() throws IOException, ClassNotFoundException { Student s = new Student(123, "Jan", 22); try (FileOutputStream f = new FileOutputStream("f.txt"); ObjectOutputStream out = new ObjectOutputStream(f);) { out.writeobject(s); out.flush(); System.out.println("success"); try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("f.txt"));) { s = (Student) in.readobject(); System.out.println(s.id + " " + s.name + " " + s.age); Do wyjątków stłumionych (ang. suppressed) można uzyskać dostęp wywołując metodę Throwable.getSuppressed wyjątku obsługiwanego strukturalnie w bloku catch https://docs.oracle.com/javase/tutorial/essential/exceptions/tryresourceclose.html
Inżynieria odwrotna Dekompilacja kodu bajtowego Javap c można pozyskać ciągi znaków, np. zaszyte hasła można też zaszumić kod, np.: nadpisz niechciany kod wartościami 00 00.. (nop) pamiętaj o argumentach operatorów (x9a0016 zamień na x570000, tj. "ifne +22 " na "pop nop nop" Dekompilatory http://www.crunchytricks.com/2016/07/bes t-offline-java-decompilers.html https://www.thecrazyprogrammer.com/2015/ 07/5-best-java-decompilers.html Mieszacze kodu (obfuscators) https://www.excelsior-usa.com/articles/javaobfuscators.html
Praca z kodem bajtowym (metody o tej samej nazwie i innym typie wartości zwracanej).class public overload.super java/lang/object.field static myint I.field static mydouble D.method static jvmoverload ()I.limit stack 3.limit locals 1 iconst_1 ireturn.end method.method static jvmoverload ()D.limit stack 3.limit locals 1 dconst_1 dreturn.end method.method public static main ([Ljava/lang/String;)V.limit stack 3.limit locals 1 invokestatic overload/jvmoverload ()I putstatic overload/myint I invokestatic overload/jvmoverload ()D putstatic overload/mydouble D return.end method.end class
Praca z kodem bajtowym (po dekompilacji nie można skompilować) >javac -classpath. overload.java overload.java:15: jvmoverload() is already defined in overload static double jvmoverload() ^ 1 error Kompilacja zdekompilowanego kodu kończy się błędem (istnienie dwóch metod o tej samej sygnaturze)
Generatory liczb pseudolosowych Ciągi liczb generowane przez Java.util.random dają się rozpoznać artykuł o rozpoznawaniu id sesji w Jetty: https://www.nccgroup.trust/globalassets/our -research/uk/whitepapers/randomness.pdf Należy stosować bardziej zaawansowane generatory liczb pseudolosowych, np. java.security.securerandom
Wstrzykiwanie poleceń SQL Rada zamiast Statement używać PreparedStatement https://www.journaldev.com/2489/jdbc-statementvs-preparedstatement-sql-injection-example
Podpisy, klucze, szyfrowanie Java Cryptography Architecture (JCA) Reference Guide https://docs.oracle.com/javase/8/docs/technotes/guides/ security/crypto/cryptospec.html Security Features in Java SE: Table of Contents https://docs.oracle.com/javase/tutorial/security/toc.html Packaging Programs in JAR Files https://docs.oracle.com/javase/tutorial/deployment/jar/int ro.html
Domyślna ścieżka User policy user.home/.java.policy user.home\.java.policy System policy Pliki polityki java.home/lib/security/java.policy java.home\lib\security\java.policy (Solaris/Linux) (Windows -%USERPROFILE%) Definicja położenie plików polityki (ścieżka jre) java.home/lib/security/java.security java.home\lib\security\java.security (Solaris/Linux) (Windows) (Solaris/Linux) (Windows) Edycja za pomocą policytool https://docs.oracle.com/javase/8/docs/technotes/guides/s ecurity/policyguide.html Linia komend z definicją pliku polityki java -Djava.security.manager - Djava.security.policy=someURL SomeApp Przykład pliku polityki https://docs.oracle.com/javase/tutorial/security/userper m/policy.html https://docs.oracle.com/javase/8/docs/technotes/guides/security/policyfiles.h tml
Podpisy cyfrowe Generowanie i weryfikowanie podpisów dla wymienianych plików https://docs.oracle.com/javase/tutorial/security/apisign/i ndex.html Podpisywanie i zabezpieczanie kodu https://docs.oracle.com/javase/tutorial/security/toolsign/ index.html Narzędzia keytool, jarsigner, Policy Tool, jar https://docs.oracle.com/javase/8/docs/technotes/guides/sec urity/securitytoolssummary.html Przykładowy scenariusz Publikowanie podpisanej aplikacji: utworzyć jar ze skompilowanymi klasami (jar) podpisać jar używając klucza prywatnego (jarsigner) jarsigner -keystore examplestore -signedjar scount.jar Count.jar signfiles wyeksportować certyfikat klucza publicznego odpowiadający kluczowi prywatnemu użytemu podczas podpisywania Uzyskanie zezwoleń przez podpisaną aplikację zaimportować certyfikat do magazynu kluczy (keytool) wygenerować plik polityki ze wskazaniem na podpisane źródło kodu uruchomić aplikację z menadżerem bezpieczeństwa
Przykład szyfrowania przy użyciu klucza Java Asymmetric Cryptography example https://www.mkyong.com/java/java-asymmetriccryptography-example/ RSA Signing and Encryption in Java http://niels.nu/blog/2016/java-rsa.html