Exception filters considered dangerous

Security Briefs

Syndication

Shawn Farkas recently posted an interesting note about impersonation. He points out that the following code...

WindowsImpersonationContext ctx = identity.Impersonate();
try { DoWork(); } finally { ctx.Undo(); }

... has a subtle hole - if an untrusted caller is above you on the stack somewhere, and if he can cause DoWork to throw an exception for some reason (perhaps by temporarily exhausting some resource that DoWork needs), he can run arbitrary code in the context of an exception filter (e.g., the Where clause in VB).

He's right. This is very subtle. But it applies to many more situations than just impersonation. If you are being called by untrusted code, then you have to assume that this trick can be used to run arbitrary malicious code in the middle of any of your routines. What happens if your state is inconsistent at the moment an exception filter runs? We often use finally blocks to clean things up before we leave the “safety” of a private function. Now we discover that our classes need to worry about reentrancy by potentially malicious code anytime they call a function that could throw an exception?

This is crazy. It seems to me that untrusted code should not be *allowed* to install exception filters in the first place. But the following code runs just fine under the "Internet" permission set:

' VB console application that attacks a C# class library using an exception filter
Imports ClassLibrary
Module Module1
    Sub Main()
        Dim victim As New Victim
        Try
            victim.Update(2, 3)
        Catch When ExploitCode(victim) = True
        End Try
    End Sub
    Function ExploitCode(ByVal victim As Victim) As Boolean
        Console.WriteLine("ExploitCode calling back into victim. IsConsistent returns {0}", victim.IsConsistent)
        Return True
    End Function
End Module

And here is the class under attack (totally benign, but it makes the point). Someone outside this class should never see FALSE returned from IsConsistent. But that's exactly what happens when the VB console app above calls into the code below, because it can reenter the Victim class whenever an exception is thrown (even a handled exception!)

using System;
namespace ClassLibrary {
    public class Victim {
        int a = 0;
        int b = 0;
        int sum = 0;
        public void Update(int newA, int newB) {
            try {
                sum = newA + newB;
                doWork();
                a = newA;
                b = newB;
            }
            finally {
                // ensure state is consistent before we leave
                sum = a + b;
            }
        }
        public bool IsConsistent() {
            return sum == a + b;
        }
        private void doWork() {
            throw new ApplicationException("whatever");
        }
    }
}

The problem here is that the attacker is able to run code between the guarded block and the finally block. The author of this class clearly didn't expect this. One solution is to use a catch block instead of a finally block. That would prevent the attacker's exception filter from running. I wonder if the BCL team thought about this? Time to break out Reflector and search for finally blocks in their code, because if they didn't think about this, there's very likely some vulnerabilities just waiting to be discovered by partially trusted code.


Posted Mar 31 2005, 08:57 AM by keith-brown
Filed under: ,

Comments

Craig wrote re: Exception filters considered dangerous
on 03-31-2005 9:47 AM
This makes me feel better about my usual model of "if you're in my process, I'm hosed anyway, so I only guard stuff from outside."

:)
Michael Entin wrote re: Exception filters considered dangerous
on 03-31-2005 10:57 AM
This problem is noted is guidelines:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/THCMCh21.asp

Do you use exception filters?
If so, be aware that the code in a filter higher in the call stack can run before code in a finally block. Check that you do not rely on state changes in the finally block, because the state change will not occur before the exception filter executes.

I think FxCop catches some if these problems.
Shawn wrote re: Exception filters considered dangerous
on 03-31-2005 2:11 PM
It's definately a problem. Of course, catching and rethrowing everywhere makes debugging a bear. In my code where I safely revert the impersonation, (http://blogs.msdn.com/shawnfa/archive/2005/03/24/401905.aspx), I use the same trick that the attacker uses. Namely, installing an exception filter so that I can revert state on the first pass of handling, yet not interfere with the exception state at all.

-Shawn
.Net Security Blog wrote More on First Pass Exception Issues
on 03-31-2005 3:41 PM
Dirk wrote re: Exception filters considered dangerous
on 04-18-2005 4:25 AM
Never considered using finally directly after try. Always went through the catch block. Good to know.
Bertrand Le Roy wrote re: Exception filters considered dangerous
on 04-18-2005 11:09 AM
One thing you could add to the post is the simple fix which is to add another try/catch block around the one you want to protect. This way, the malicious filter will get the state for the outside try/catch and won't be able to exploit it.
michaels wrote re: Exception filters considered dangerous
on 04-23-2005 1:34 AM
shouldn't the feature be removed? seems a little silly to give access to a class that is in an inconsistant state (i.e. error thrown, 'finally' not executed).

you've basically allowed the insertion of a 'catch' block. Seems to break the idea of 'incapsulation'.

as to the impersonation (which i'm not that familiar with) issues, why does that request grant permission to all 'assemblies'. shouldn't it only grant that priveledge to the one requesting permission? at least by default? it would obviously also need to allow system assemblies...

or would there be a problem with this that I don't see? (or does it do this already and we are assuming malicious code is _in_ our assembly...)
|create|tek| wrote Excep
on 07-22-2005 2:17 PM
Dinis Cruz @ Owasp .Net Project wrote Potential Finally issue in System.Web.HttpServerUtility.Execute(string path, TextWriter writer, bool preserveForm)
on 01-25-2006 3:00 AM
(from Reflector) in the middle on the System.Web.HttpServerUtility.Execute(string path, TextWriter writer,...
João Pedro Martins wrote TechEd EMEA 2005 e Excepções
on 10-17-2006 7:50 AM
Uma das apresentações interessantes a que assisti foi do conhecido David Platt , " Exception Handling
The Sontek Way Of Life! wrote Exception Filtering
on 12-07-2006 12:01 AM
Exception Filtering

Add a Comment

(required)  
(optional)
(required)  
Remember Me?