|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 4
Visibility (whether a class or member is public or private) and extensibility (whether or not subclassing can extend a class or method) provide important tools in a software developer's tool chest. However, both, if not used properly, can lead to subtle vulnerabilities.
In the case of subclassing, a subclass can alter the contract implied by the superclass. Existing code, with its implicit dependence on the implied contract, can break or malfunction in a way that affects the application's security. The solution: liberally use the final keyword, which prevents redefinition through subclassing.
In the same way, failure to protect a class's inner workings and state through judicious use of the private keyword can expose a class to unexpected modification by classes subsequently added to a package.
The InterBase design flaw provides an excellent example of why you shouldn't embed secrets in an application. Secrets, often in the form of passwords or encrypted data, are never completely safe from a determined attacker. And once the secret is compromised, the genie is out of the bottle.
Through direct experience, I have come to respect many of the engineers at Sun. However talented they are, they make mistakes just like you and me.
On February 23, Sun announced its discovery of a security flaw in the JDK. In their words:
A vulnerability in certain versions of the Java Runtime Environment may allow malicious Java code to execute unauthorized commands. However, permission to execute at least one command must have been granted in order for this vulnerability to be exploited.
The flaw allowed untrusted Java code, executing within an otherwise secure JVM, to invoke any executable (i.e., format) if the code had been given the legitimate ability to invoke at least one executable (i.e., echo) in certain circumstances. The bug very likely went undetected for so long because the bug's exploitation relied on the existence
of a race condition with a narrow window of opportunity.
The flaw was in the exec() method of the java.lang.Runtime class. Paraphrased slightly, the code was:
public
Process
exec(String [] arstringCommand, String [] arstringEnvironment)
throws IOException
{
// Ensure that the array parameters aren't null, their elements
// aren't null, etc.
.
.
.
// Do some stuff.
.
.
.
// Get the security manager.
SecurityManager securitymanager = System.getSecurityManager();
// Check the first element of the command array -- which should
// be the name of the executable to invoke. Ensure that it has
// executable privilege.
if (securitymanager != null)
securitymanager.checkExec(arstringCommand[0]);
// Now, invoke the executable.
return execInternal(arstringCommand, arstringEnvironment);
}
Do you see the problem?
The error lies in the last three lines (comments and white space excluded). First, the security manager checks the executable's name to see if it has been granted execute permission in the policy file. Second, the code executes the command. Whoops! In a multithreaded environment, the contents of the parameter arrays can change between these two steps. Since the two input parameter arrays are used directly, the caller still holds references to them and can modify their contents.