Security basic definitions
In the review questions of chapter 22 I missed some easy questions because I mixed definitions. Here some things to remember:
Designing a secure object
To design a secure object, you have to:
- Limit accessibility
- private or package-private fields, getters/setters
- principle of least privilege
- only export packages to the specific modules that should have access
- Restrict extensibility
- Marking class final
To create an immutable object class:
- Mark the class as final
- Mark all the instance variables private
- Don’t define setter methods and make fields final
- Don’t allow referenced mutable objects to be modified (no getter for mutable variable)
- Use a constructor to set all properties of the object, making a copy if needed
Using clone() to copy objects can be a good idea, but check clone’s implementation. Default implementation gives a shallow copy that might still be mutable. Method clone() gives runtime error if Cloneable is not implemented.
Injection and input validation
Injection is related to I/O and database. Keywords: SQL injection and Command injection. Prevent it by:
- Use PreparedStatement with bind variables
- Validate input (command injection) with whitelist
Invalid input should result in log message or exception. It should not be ignored.
Working with confidential information
Avoid leaks of confidential information by:
- not putting confidential information in String
- beware of log file
- beware of printed exceptions or stack traces
- beware of System.out and System.err messages
- beware of data you write to files
Protecting data in memory:
- Don’t put sensitive data in a String as it gets into the string pool. Use char[] instead.
- char[] can be overwritten (null out) as soon as you don’t need it anymore. That is good.
- If sensitive data cannot be overwritten, set it to null as soon as possible.
- Generally, keep sensitive data in memory as short as possible.
Limiting file access:
- Use the principle of least privilege
Serializing and deserializing objects
- Use transient
- Use serialPersistantFields (even better, it is whitelist)
- Do further customization for further protection (see other blog post.
Constructing sensitive objects
To make sure subclasses cannot change the behaviour of a class:
- Make methods final
- Make class final
- Make the constructor private (use static factory method for creating instances)
Make sure a constructor does not call methods that subclasses can override (make them final). Or make the constructor private or make the class itself final.
Preventing denial of service attacks
A DoS attack can be done by a single request from a single machine, a DDoS attack requires multiple machines and therefore multiple requests.
DoS/DDoS attacks can have the following forms:
- Provoke leaking of resources by calling poorly written methods (Solution: use try-with resources)
- Reading very large resources (Solution: check file size)
- Inclusion attacks: including potentially large resources with zip bomb or billion laughs attack (no solution given)
- Overflowing numbers. Integers have maximum size and become negative if you go past that number. This can harm a validation process, for example if filesize > INTEGER_MAX_VALUE. (Solution: check if file is too large or too small)
- Wasting data structures. Code that creates very large data structures, or a hashmap where every entry has about the same hash value. (Solution: do code reviews and beware of untrusted classes. Don’t allow evil people to set the size of arrays themselves.)