5

How can I secure the serialized object if I send the serialized object over the network? I doubt that hackers may interrupt/hack my data.

can anyone tell in detail about how to implement this?

user1514499
  • 762
  • 7
  • 26
  • 63

8 Answers8

6

This presentation give ideas on how effectively attackers can tamper a Java serialized stream:

  1. https://www.owasp.org/images/e/eb/OWASP_IL_2008_Shai_Chen_PT_to_Java_Client_Server_Apps.ppt

    There is also the risk of injecting unsuspected behavior and inject code in case a vulnerable class exists on the server's classpath. See this article:

[Look-ahead Java deserialization][3]

Pierre Ernst
  • 514
  • 3
  • 7
4

java.crypto.SealedObject is what you are looking for.

user207421
  • 305,947
  • 44
  • 307
  • 483
2

You can encrypt or hash it, but java serialization format is a poot choice for sending over network - better solution would be JSON / XML ( encrypted or signed with some cryptographic algorythm)

nobalG
  • 4,544
  • 3
  • 34
  • 72
Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
1

Look into encryption as said before, but more specifically look at hte SSL/TLS libraries for network communication in java.

http://juliusdavies.ca/commons-ssl/ssl.html

No need to try and implement secure encryption communication when there is a very powerful library built into Java.

sean
  • 3,955
  • 21
  • 28
  • In my webapplication I am using https:// to access the application. Is this enough? – user1514499 Jul 10 '12 at 16:03
  • It may be, can you give more context? – sean Jul 10 '12 at 16:06
  • In Glassfish server, I have network configuration as given in the below url. Is this configuration enough to secure my data? http://javadude.wordpress.com/2010/04/06/getting-started-with-glassfish-v3-and-ssl/ – user1514499 Jul 10 '12 at 16:14
  • That should be fine for your needs. If you are accessing your data over a https:// connection then it should be encrypted. But, if you need to add communication within your system then you can use the SSL/TLS libs to perform the encryption for you. – sean Jul 10 '12 at 16:16
  • Can you please confirm the above given configuration(in Glassfish) will secure my data when I send the send the data after serialisation – user1514499 Jul 10 '12 at 16:23
  • I believe it will be fine for server to client communication security, but remember that there is still data security that should be kept in mind outside of the communication channel. – sean Jul 10 '12 at 17:40
1

In my opinion, you can use either use SSLSocket or SealedObject. However, it will make things a bit heavy for you. However, one of the option is described in this article as well. http://www.ibm.com/developerworks/library/j-5things1/

Ashley
  • 629
  • 3
  • 6
  • 16
1

You can use the signed object and sealed object to secure the serialisation object

Musaddique S
  • 1,539
  • 2
  • 15
  • 36
1

I add a useful resource to the thread here, Oracle's Secure Coding Guidelines for Java SE (particularly, in this case section 8 in the guidelines, "Serialization and Deserialization"):

https://www.oracle.com/java/technologies/javase/seccodeguide.html#8

Dharman
  • 30,962
  • 25
  • 85
  • 135
Gerardo Roza
  • 2,746
  • 2
  • 24
  • 33
1

A good way to secure any object in java is enforcing invariants in the constructor. For example, imagine a class Person where you do not want to allow any instantiation of a person under age 13:

public class Person implements Serializable{
    private String name;
    private Integer age;

    public Person(final String name, final Integer age) {
        if(age < 13) {
            throw new IllegalArgumentException("invalid age");
        }
        this.name = name;
        this.age = age;
    }
}

However, as you are implementing Serializable it is possible to write code bypassing your constructor, which should be our main defense mechanism, so it is possible to break encapsulation:

@Test
void testEncapsulationSerialization() throws IOException, ClassNotFoundException {
    Person a = new Person("dave", 23);
    ByteArrayOutputStream boas = new ByteArrayOutputStream();
    try (ObjectOutputStream oos = new ObjectOutputStream(boas)) {
        oos.writeObject(a);
    }
    byte[] bytes = boas.toByteArray();
    bytes[237] = 12; // trick: we are modifying the array of bytes manually
    try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
        Person b = (Person) ois.readObject();
        System.out.println(a);
        System.out.println(b);
    }
}

With this test we are able to create an object of type Person with age of 12 (which is not allowed in our constructor).

So in this case, if you want to secure serialization you need to override in Person class readResolve() method to call your constructor:

private Object readResolve() throws ObjectStreamException {
    return new Person(this);
}

So that we will enforce that any instantiation follow the invariants declared in our constructor.

Also if you have a parent class that implements Serialization, you may need to also override readObject() and writeObject() methods.

Furthermore, you should ensure immutability of your object, as the default extensibility of java works against security.

To sum up, we should avoid using Serializable (and Clonable) because both can break encapsulation if we do not explicitly secure them.

Alex Blasco
  • 793
  • 11
  • 22