Proteção de manipulação de exceção
No Visual C++ e Visual Basic, uma expressão de filtro mais acima na pilha é executado antes de qualquer Por fim demonstrativo.The catch bloco associado a esse filtro é executado após o Por fim demonstrativo.Para obter mais informações, consulte Usando exceções filtrados por usuário.Esta seção examina as implicações de segurança desta ordem.Considere o seguinte pseudocódigo exemplo que ilustra a ordem na qual filtro instruções e Por fim instruções executadas.
void Main()
{
try
{
Sub();
}
except (Filter())
{
Console.WriteLine("catch");
}
}
bool Filter () {
Console.WriteLine("filter");
return true;
}
void Sub()
{
try
{
Console.WriteLine("throw");
throw new Exception();
}
finally
{
Console.WriteLine("finally");
}
}
Esse código imprime a seguir.
Throw
Filter
Finally
Catch
O filtro é executado antes do Por fim demonstrativo, para que questões de segurança podem ser introduzidos por qualquer coisa que torna um estado onde a execução de Outros código pode tirar proveito de alterar.Por exemplo:
try
{
Alter_Security_State();
// This means changing anything (state variables,
// switching unmanaged context, impersonation, and
// so on) that could be exploited if malicious
// code ran before state is restored.
Do_some_work();
}
finally
{
Restore_Security_State();
// This simply restores the state change above.
}
Este pseudocódigo permite que um filtro de nível superior da pilha para executar código arbitrário.Outros exemplos de operações que têm um efeito semelhante são temporária representação da identidade de outra, definindo um marcador interno que ignora algumas verificação de segurança, ou alterar a cultura associada ao thread.A solução recomendada é apresentar um manipulador de exceção para isolar as alterações do código thread estado dos blocos de filtro dos chamadores.No entanto, é importante que o manipulador de exceção ser introduzidas corretamente ou não será corrigido o problema.O exemplo a seguir alterna a cultura da interface do usuário, mas qualquer tipo de alterar de estado do segmento pode estar exposto da mesma forma.
YourObject.YourMethod()
{
CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture;
try {
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
// Do something that throws an exception.
}
finally {
Thread.CurrentThread.CurrentUICulture = saveCulture;
}
}
Public Class UserCode
Public Shared Sub Main()
Try
Dim obj As YourObject = new YourObject
obj.YourMethod()
Catch e As Exception When FilterFunc
Console.WriteLine("An error occurred: '{0}'", e)
Console.WriteLine("Current Culture: {0}",
Thread.CurrentThread.CurrentUICulture)
End Try
End Sub
Public Function FilterFunc As Boolean
Console.WriteLine("Current Culture: {0}", Thread.CurrentThread.CurrentUICulture)
Return True
End Sub
End Class
A correção correta nesse caso, é encapsular o existente Tente/Por fim bloco um Tente/catch bloco.Simplesmente apresentando um catch throw cláusula para o existenteTente/Por fim bloco não corrige o problema, conforme mostrado no exemplo a seguir.
YourObject.YourMethod()
{
CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture;
try
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
// Do something that throws an exception.
}
catch { throw; }
finally
{
Thread.CurrentThread.CurrentUICulture = saveCulture;
}
}
Isso não corrigir o problema porque o Por fim demonstrativo não foi executado antes do FilterFunc obtém controle.
O exemplo a seguir corrige o problema, garantindo que o Por fim cláusula foi executada antes de oferecer uma exceção de blocos de filtro de exceção os chamadores.
YourObject.YourMethod()
{
CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture;
try
{
try
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
// Do something that throws an exception.
}
finally
{
Thread.CurrentThread.CurrentUICulture = saveCulture;
}
}
catch { throw; }
}