Wow, Writing Secure Code is Subtle

I'm hanging out at TechEd this week, and attended a session on best practices for exception handling.  The presenter discussed the rare but evil “Exception Filtering” exploit, which goes as follows.  Untrusted code UC calls our trusted code TC, which ends up throwing an exception.  Exception handling in the CLR is a 2-step process:

  1. walk the stack looking to see which catch block will be executed, then
  2. go back and walk the stack again, executing finally blocks and popping stack frames until we reach the appropriate catch block.

Note that (1) will end up walking into UC if necessary...  Now, VB has the following feature (also available in IL if you prefer to write your code that way), which allows you to filter your exception handling:

Try
       << ask TedP to insert something funny here >>
Catch ex As Exception When HandleIfThisMethodCallReturnsTrue(ex)
       . . .
End Catch

The problem?  The filter methods are called by the CLR during step (1) of exception processing, which means that it's possible for untrusted code in UC to execute.  Since the stack has not yet been cleaned up (the CLR is still trying to figure out what catch block to execute), a UC filter method can walk the stack, look at trusted state, etc.  I'm not sure (hey Keith?), but it may also be that UC will execute with the permission set of our trusted code, which could be very bad. 

So what's the solution?  While .NET 2.0 will contain a “clean up the stack please” method (sorry, didn't take notes on the exact details), the solution that works in all versions of .NET is to make sure we catch all exception types in our trusted code, and then (if appropriate) re-throw the exception with “Throw Ex”.  This will prevent UC filters from executing before the stack is cleaned up, while retaining the semantics of what we're after --- telling the client about the exception.

In the bigger scheme of things, I wonder how the heck we're supposed to learn / teach writing secure code.  This exploit is subtle, and depends on implementation details of the CLR which very few know.  Right now the approach is all very reactive, dealing with exploit X and exploit Y.  We're still in the very early stages of figuring this out, but eventually we're going to need some better theory.  Academics, start your grant writing engines :-)

Before I sign off, I'd like to thank my friends at pluralsight for letting me hang out here.  Thanks guys, it feels good to be back.  Cheers!


Posted Jun 09 2005, 11:49 AM by joe-hummel

Comments

David Stull wrote re: Wow, Writing Secure Code is Subtle
on 06-09-2005 3:00 PM
Glad to see you blogging here. Will you be teaching for Pluralsight as well?
drjoe wrote re: teaching for pluralsight
on 06-09-2005 7:23 PM
If pluralsight will have me :-) Actually, yes, that's the plan, I'll be helping pluralsight deliver some new curriculum. Stay tuned!
Keith Brown wrote re: Wow, Writing Secure Code is Subtle
on 06-10-2005 4:21 PM
Woohoo, welcome Joe :-)

The biggest issues I know of are a) unexpected reentrancy into the class if the class designer expected his finally block to restore a class invariant, and b) contextual side-effects like impersonation.

I talked about (a) here: http://pluralsight.com/blogs/keith/archive/2005/04/27/7803.aspx

Shawn Farkas talked about (b) here: http://blogs.msdn.com/shawnfa/archive/2005/03/22/400749.aspx

Most application devs won't need to worry about this - they probably aren't writing plumbing that will be used by untrusted code. Class library designers should be thinking about it though!
Georgeo Pulikkathara wrote re: Wow, Writing Secure Code is Subtle
on 06-12-2005 12:12 PM
Dr Hummel,

I'm glad to see you've finally started a blog. I'm sure readers will love to hear more about you and your work, especially after hosting these two MSDN Webcast series for us here at Microsoft.

Regards,
George, MSDN Webcasts


http://msdn.microsoft.com/vbasic/community/webcasts/modern/default.aspx

http://www.microsoft.com/events/series/modernsoftdev.mspx

Add a Comment

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