【问题标题】:Transient System.Security.Cryptography.CryptographicException in TwilioRequestValidatorTwilioRequestValidator 中的瞬态 System.Security.Cryptography.CryptographicException
【发布时间】:2019-02-14 21:26:58
【问题描述】:

所以我们设置了 Twilio 回调来验证传入的请求,通过记录在 here 的 TwilioRequestValidator。

但是,我们看到的是,生产服务器将运行数周而没有问题,然后突然开始出现 CryptographicException 失败。这会导致所有传入的 Twilio 请求失败。

我们有一个调用堆栈(感谢 Azure Application Insights):

    System.Security.Cryptography.CryptographicException:
   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Security.Cryptography.Utils.HashData (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Security.Cryptography.SHA1CryptoServiceProvider.HashCore (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Security.Cryptography.HashAlgorithm.TransformBlock (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Security.Cryptography.HMAC.HashCore (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Security.Cryptography.HashAlgorithm.ComputeHash (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at Twilio.Security.RequestValidator.GetValidationSignature (Twilio, Version=5.14.1.0, Culture=neutral, PublicKeyToken=null)
   at Misc.TwilioRequestValidator.ValidateTwilioRequestAttribute.IsValidRequest (RCHHRATool, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
   at Misc.TwilioRequestValidator.ValidateTwilioRequestAttribute.OnActionExecuting (RCHHRATool, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__31 (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeActionMethodWithFilters (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__19 (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1c (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1.CallBeginDelegate (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Controller.BeginExecuteCore (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Controller.BeginExecute (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4 (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1.CallBeginDelegate (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.HttpApplication+<>c__DisplayClass285_0.<ExecuteStepImpl>b__0 (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.HttpApplication.ExecuteStepImpl (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.HttpApplication.ExecuteStep (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)

我们有一些应用程序代码,在这里:

[AttributeUsage(AttributeTargets.Method)]
public class ValidateTwilioRequestAttribute : ActionFilterAttribute
{
    private readonly RequestValidator _requestValidator;

    public ValidateTwilioRequestAttribute()
    {
        var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
        _requestValidator = new RequestValidator(authToken);
    }

    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var context = actionContext.HttpContext;
        if (!IsValidRequest(context.Request))
        {
            actionContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
        }

        base.OnActionExecuting(actionContext);
    }

    private bool IsValidRequest(HttpRequestBase request)
    {
        var signature = request.Headers["X-Twilio-Signature"];
        Debug.WriteLine(request.Headers["X-Twilio-Signature"]);
        //var requestUrl = request.RawUrl;
        var requestUrl = rewriteUri(request.Url.AbsoluteUri);
        Debug.WriteLine("URI is: " + rewriteUri(request.Url.AbsoluteUri));

        return _requestValidator.Validate(requestUrl, request.Form, signature);
    }

    private string rewriteUri(string absoluteUri)
    {
        //check to make sure we're not replacing 'https' with 'httpss'
        if (!absoluteUri.Contains("https"))
        {
            return Regex.Replace(absoluteUri, @"http", "https");
        }
        return absoluteUri;
    }
}

关于可能导致此问题的任何想法?理想情况下,我想处理这种异常状态,但不知道原因是什么,我不确定如何处理异常。

编辑:当我深入了解应用程序洞察中的异常时,我收到此错误消息:

“哈希在指定状态下无效。”

编辑 #2:快速搜索该错误消息会发现 this 关于 Cryptography 对象的线程安全性的有趣讨论。

【问题讨论】:

    标签: c# asp.net-mvc-5 twilio twilio-api


    【解决方案1】:

    看起来这是 Twilio-csharp 库中的一个错误。我相信他们正在以非线程安全的方式使用他们的 Sha1 成员。

    我已经破解了一个解决方案,以便在发生 CryptographicException 时重新初始化该类。由于服务器重启正在解决问题,我认为需要强制重新初始化该类。

        try
        {
            return _requestValidator.Validate(requestUrl, request.Form, signature);
        }
        catch (CryptographicException e)
        {
            //if the request fails, re-init the class and try again
            var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
            _requestValidator = new RequestValidator(authToken);
            return IsValidRequest(request);
        }
    

    编辑:值得注意的是,此修复会导致与使用库的非线程安全方式相关的连锁问题。

    【讨论】:

    • 你怎么样 new RequestValidator(authtoken).Validate 那里?我认为它适用于高负载下的新实例。
    • 没有办法对人们做出这样的回应,伙计。顺便说一句,它对我有用。
    猜你喜欢
    • 2012-09-20
    • 2019-09-22
    • 2011-03-07
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多