...
It is possible that an exception gets thrown in the finally
block even though it escapes detection at compile time. This can prevent other clean-up statements from getting executed.
...
Noncompliant Code Example
The finally
clause closes the reader
object in this non-compliant noncompliant example. However, it is incorrectly assumed that the statements within the finally
block cannot throw exceptions. Notably, close()
can throw an IOException
which in turn prevents any subsequent clean-up lines from getting executed. This is not detected at compile time since close()
throws the same exception type as read
or write
.
Code Block | ||
---|---|---|
| ||
class Login { static void checkPassword(String password_file) throws IOException { StringBuffer fileData = new StringBuffer(1000); BufferedReader reader = new BufferedReader(new FileReader(password_file)); try { int n; char[] passwd = new char[1024]; while ((n = reader.read(passwd)) >= 0) { String readData = String.valueOf(passwd, 0, n); fileData.append(readData); passwd = new char[1024]; } String realPassword = "javac<at:var at:name="f3b" />b3"; System.out.println(fileData.toString()); if (fileData.toString().equals(realPassword)) { System.out.println("Login successful"); } else { System.out.println("Login failed"); } } finally { reader.close(); //other clean-up code } } public static void main(String[] args) throws IOException { String path = "c:\\password.txt"; checkPassword(path); } } |
Compliant Solution
This compliant solution correctly places the close()
statement in a try-catch
block. Thus As a result an IOException
can be handled without letting it propagate any further.
Code Block | ||
---|---|---|
| ||
class Login { static void checkPassword(String password_file) throws IOException { StringBuffer fileData = new StringBuffer(1000); BufferedReader reader = new BufferedReader(new FileReader(password_file)); try { int n; char[] passwd = new char[1024]; while ((n = reader.read(passwd)) >= 0) { String readData = String.valueOf(passwd, 0, n); fileData.append(readData); passwd = new char[1024]; } String realPassword = "javac<at:var at:name="f3b" />b3"; System.out.println(fileData.toString()); if (fileData.toString().equals(realPassword)) { System.out.println("Login successful"); } else { System.out.println("Login failed"); } } finally { try { //enclose in try-catch block reader.close(); //other clean-up code }catch (IOException ie) {ie.getMessage()} } } public static void main(String[] args) throws IOException { String path = "c:\\password.txt"; checkPassword(path); } } |
Risk Assessment
TODO
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC01-J | ?? | ?? | ?? | P?? | L?? |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Java Puzzlers 5.41
Java I/O