Errors and error handling represent a class of API. Errors related to error handling are so common that they deserve a special kingdom of their own. As with "API Abuse," there are two ways to introduce an error-related security vulnerability: the most common one is handling errors poorly (or not at all). The second is producing errors that either give out too much information (to possible attackers) or are difficult to handle.
+=
but it is written as =+
, the operation is still valid. However, instead of carrying out the addition, it re-initializes the variable.numberOne
. However, using the =+
operator actually re-initializes the variable to 1.
uint numberOne = 1;
function alwaysOne() public {
numberOne =+ 1;
}
for
loop statement to refund all involved addresses by using the send
external call.
function refundAll() public {
for(uint x; x < refundAddresses.length; x++) {
require(refundAddresses[x].send(refunds[refundAddresses[x]]));
}
}
...
EXEC CICS
INGNORE CONDITION ERROR
END-EXEC.
...
doExchange()
.
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
were to ever be thrown, the program would continue to execute as though nothing unusual had occurred. The program records no evidence indicating the special situation, potentially frustrating any later attempt to explain the program's behavior.DoExchange()
.
try {
DoExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
were to ever be thrown, the program would continue to execute as though nothing unusual had occurred. The program records no evidence indicating the special situation, potentially frustrating any later attempt to explain the program's behavior.doExchange()
.
try {
doExchange();
}
catch (RareException e) {
// this can never happen
}
RareException
were to ever be thrown, the program would continue to execute as though nothing unusual had occurred. The program records no evidence indicating the special situation, potentially frustrating any later attempt to explain the program's behavior.doExchange()
.
try {
doExchange();
}
catch (exception $e) {
// this can never happen
}
RareException
were to ever be thrown, the program would continue to execute as though nothing unusual had occurred. The program records no evidence indicating the special situation, potentially frustrating any later attempt to explain the program's behavior.open()
.
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except:
# This will never happen
pass
RareException
were to ever be thrown, the program would continue to execute as though nothing unusual had occurred. The program records no evidence indicating the special situation, potentially frustrating any later attempt to explain the program's behavior.
PROCEDURE do_it_all
IS
BEGIN
BEGIN
INSERT INTO table1 VALUES(...);
COMMIT;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
END do_it_all;
Exception
can obscure exceptions that deserve special treatment or that should not be caught at this point in the program. Catching an overly broad exception essentially defeats the purpose of .NET's typed exceptions, and can become particularly dangerous if the program grows and begins to throw new types of exceptions. The new exception types will not receive any attention.
try {
DoExchange();
}
catch (IOException e) {
logger.Error("DoExchange failed", e);
}
catch (FormatException e) {
logger.Error("DoExchange failed", e);
}
catch (TimeoutException e) {
logger.Error("DoExchange failed", e);
}
try {
DoExchange();
}
catch (Exception e) {
logger.Error("DoExchange failed", e);
}
DoExchange()
is modified to throw a new type of exception that should be handled in some different kind of way, the broad catch block will prevent the compiler from pointing out the situation. Further, the new catch block will now also handle exceptions of types ApplicationException
and NullReferenceException
, which is not the programmer's intent.Exception
can obscure exceptions that deserve special treatment or that should not be caught at this point in the program. Catching an overly broad exception essentially defeats the purpose of Java's typed exceptions, and can become particularly dangerous if the program grows and begins to throw new types of exceptions. The new exception types will not receive any attention.
try {
doExchange();
}
catch (IOException e) {
logger.error("doExchange failed", e);
}
catch (InvocationTargetException e) {
logger.error("doExchange failed", e);
}
catch (SQLException e) {
logger.error("doExchange failed", e);
}
try {
doExchange();
}
catch (Exception e) {
logger.error("doExchange failed", e);
}
doExchange()
is modified to throw a new type of exception that should be handled in some different kind of way, the broad catch block will prevent the compiler from pointing out the situation. Further, the new catch block will now also handle exceptions derived from RuntimeException
such as ClassCastException
, and NullPointerException
, which is not the programmer's intent.Exception
or Throwable
makes it difficult for callers to do good error handling and error recovery. Java's exception mechanism is set up to make it easy for callers to anticipate what can go wrong and write code to handle each specific exceptional circumstance. Declaring that a method throws a generic form of exception defeats this system.
public void doExchange()
throws IOException, InvocationTargetException,
SQLException {
...
}
public void doExchange()
throws Exception {
...
}
doExchange()
introduces a new type of exception that should be treated differently than previous exceptions, there is no easy way to enforce this requirement.NullPointerException
.NullPointerException
under three circumstances:NullPointerException
to signal an error condition.NullPointerException
.
try {
mysteryMethod();
}
catch (NullPointerException npe) {
}
NullReferenceException
.NullReferenceException
under three circumstances:NullReferenceException
to signal an error condition.NullReferenceException
.
try {
MysteryMethod();
}
catch (NullReferenceException npe) {
}
finally
block will cause exceptions to be lost.finally
block will cause any exception that might be thrown in the try block to be discarded.MagicException
thrown by the second call to doMagic
with true
passed to it will never be delivered to the caller. The return statement inside the finally
block will cause the exception to be discarded.
public class MagicTrick {
public static class MagicException extends Exception { }
public static void main(String[] args) {
System.out.println("Watch as this magical code makes an " +
"exception disappear before your very eyes!");
System.out.println("First, the kind of exception handling " +
"you're used to:");
try {
doMagic(false);
} catch (MagicException e) {
// An exception will be caught here
e.printStackTrace();
}
System.out.println("Now, the magic:");
try {
doMagic(true);
} catch (MagicException e) {
// No exception caught here, the finally block ate it
e.printStackTrace();
}
System.out.println("tada!");
}
public static void doMagic(boolean returnFromFinally)
throws MagicException {
try {
throw new MagicException();
}
finally {
if (returnFromFinally) {
return;
}
}
}
}
finally
block will cause exceptions to be lost.finally
block will cause any exception that might be thrown in the try block to be discarded.exception
thrown by the second call to doMagic
with True
passed to it will never be delivered to the caller. The return statement inside the finally
block will cause the exception to be discarded."disappear before your very eyes!" . PHP_EOL;
echo "First, the kind of exception handling " .
"you're used to:" . PHP_EOL;
try {
doMagic(False);
} catch (exception $e) {
// An exception will be caught here
echo $e->getMessage();
}
echo "Now, the magic:" . PHP_EOL;
try {
doMagic(True);
} catch (exception $e) {
// No exception caught here, the finally block ate it
echo $e->getMessage();
}
echo "Tada!" . PHP_EOL;
function doMagic($returnFromFinally) {
try {
throw new Exception("Magic Exception" . PHP_EOL);
}
finally {
if ($returnFromFinally) {
return;
}
}
}
?>
ThreadDeath
error is not re-thrown, the thread in question might not actually die.ThreadDeath
errors should only be caught if an applications needs to clean up after being terminated asynchronously. If a ThreadDeath
error is caught, it is important that it be re-thrown so that the thread actually dies. The purpose of throwing ThreadDeath
is to stop a thread. If ThreadDeath
is swallowed, it can prevent a thread from stopping and result in unexpected behavior since whoever originally threw ThreadDeath
expects the thread to stop.ThreadDeath
but does not re-throw it.
try
{
//some code
}
catch(ThreadDeath td)
{
//clean up code
}
throw
statement inside a finally
block breaks the logical progression through the try-catch-finally
.finally
blocks are always executed after their corresponding try-catch
blocks and are often used to free allocated resources, such as file handles or database cursors. Throwing an exception in a finally
block can bypass critical cleanup code since normal program execution will be disrupted.stmt.close()
is bypassed when the FileNotFoundException
is thrown.
public void processTransaction(Connection conn) throws FileNotFoundException
{
FileInputStream fis = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
fis = new FileInputStream("badFile.txt");
...
}
catch (FileNotFoundException fe)
{
log("File not found.");
}
catch (SQLException se)
{
//handle error
}
finally
{
if (fis == null)
{
throw new FileNotFoundException();
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
log(e);
}
}
}
}
javax.net.ssl.SSLHandshakeException
, javax.net.ssl.SSLKeyException
, and javax.net.ssl.SSLPeerUnverifiedException
all convey important errors related to an SSL connection. If these errors are not explicitly handled, the connection can be left in an unexpected and potential insecure state.