コード例 #1
0
ファイル: ErrorBased.cs プロジェクト: ramss22/Seringa
        public string GetSingleCustomQueryResultRow(int startingFrom)
        {
            string result = string.Empty;

            string generatedPayload = PayloadDetails.Payload;

            if (PayloadDetails.Params != null && PayloadDetails.Params.Count() > 0)
            {
                foreach (var param in PayloadDetails.Params)
                {
                    generatedPayload = generatedPayload.Replace("{" + param.Position + "}", PayloadHelpers.GetData(param.Name, this));
                }
            }

            if (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Multiple)
            {
                generatedPayload = string.Format(PayloadHelpers.GetSingleResultLimiter(PayloadDetails.Dbms),
                                                 generatedPayload, startingFrom);
            }

            string query    = QueryHelper.CreateQuery(Url, ExploitDetails.Exploit, generatedPayload);
            string pageHtml = QueryRunner.GetPageHtml(query, UseProxy ? ProxyDetails : null);

            result = HtmlHelpers.GetAnswerFromHtml(pageHtml, query, ExploitDetails, DetailedExceptions);
            //@TODO: strip scripts
            if (!string.IsNullOrEmpty(MappingFile) && !string.IsNullOrEmpty(result))
            {
                XmlHelpers.SaveToMappingFile(MappingFile, PayloadDetails, result, this,
                                             (this.ExploitDetails != null) ? this.ExploitDetails.Dbms : string.Empty);
            }

            return(result);
        }
コード例 #2
0
        private static object[] ConstructEventWithSource <T>(SourceSystem sourceSystem) where T : IMessage
        {
            var payload = PayloadHelpers.Construct <T>();

            PayloadHelpers.SetField(payload, "source_", sourceSystem); // the name of field is found with decompiler
            return(new object[] { payload });
        }
コード例 #3
0
        public void Should_not_process_payload_if_it_is_disabled()
        {
            var eventValidator = new Mock <IEventValidator>();

            eventValidator.Setup(m => m.IsEnabled(It.IsAny <PriceBandUpdated>())).Returns(false);
            var handler          = new PriceBandEventHandler(Mock.Of <IDatabaseCommands>(), eventValidator.Object, Mock.Of <IMessagingLogger>(), Mock.Of <IConfiguration>());
            var priceBandUpdated = PayloadHelpers.Construct <PriceBandUpdated>();

            var result = handler.HandleAsync(priceBandUpdated, Guid.Empty.ToString()).Result;

            Assert.Equal(MessageHandlerResult.Success, result);
            eventValidator.Verify(m => m.IsValidPayload(It.IsAny <PriceBandUpdated>()), Times.Never);
        }
コード例 #4
0
        public void Should_register_error_with_model()
        {
            // arrange
            var payload    = PayloadHelpers.Construct <AccountUpdated>();
            var dbCommands = new Mock <IDatabaseCommands>();
            var validator  = new Mock <IEventValidator>();

            validator.Setup(m => m.IsAllowedEvent(It.IsAny <object>())).Returns(true);
            validator.Setup(m => m.IsValidPayload(It.IsAny <object>())).Returns(false);
            var messagingLogger = new Mock <IMessagingLogger>();
            var handler         = new AccountUpdatedEventHandler(dbCommands.Object, validator.Object, messagingLogger.Object);

            // act
            var result = handler.HandleAsync(payload, "1").Result;

            // assert
            Assert.Equal(MessageHandlerResult.Fatal, result);
            messagingLogger.Verify(m => m.ReceivedInvalidModel(It.IsAny <string>(), It.IsAny <object>(), It.IsAny <string>()), Times.Once);
        }
コード例 #5
0
        public string GetSingleCustomQueryResultRow(int startingFrom)
        {
            string        results  = string.Empty;
            StringBuilder sbResult = new StringBuilder();

            string generatedPayload = PayloadDetails.Payload;

            if (PayloadDetails.Params != null && PayloadDetails.Params.Count() > 0)
            {
                foreach (var param in PayloadDetails.Params)
                {
                    generatedPayload = generatedPayload.Replace("{" + param.Position + "}", PayloadHelpers.GetData(param.Name, this));
                }
            }


            StringBuilder sbCurExploit = new StringBuilder();

            int    columnIndexCounter        = 0;
            string generatedPayloadWithLimit = string.Empty;

            for (int j = 0; j < _nrCols; j++)
            {
                if (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Multiple)
                {
                    generatedPayloadWithLimit = string.Format(PayloadHelpers.GetSingleResultLimiter(PayloadDetails.Dbms), generatedPayload, startingFrom + j);
                }

                if (_visibleColumnIndexes.Contains(j))
                {
                    /*
                     * sbCurExploit.AppendFormat(GeneralPayloads.UnionBasedSelectCountedResultWrapper, _visibleColumnIndexes[columnIndexCounter],
                     *  (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Multiple) ? generatedPayloadWithLimit : generatedPayload);
                     */

                    sbCurExploit.Append(GeneralPayloads.UnionBasedSelectCountedResultWrapperPart1);
                    sbCurExploit.Append(UrlHelpers.HexEncodeValue(string.Format(GeneralPayloads.UnionBasedSelectCountedResultWrapperPart2,
                                                                                _visibleColumnIndexes[columnIndexCounter])));
                    sbCurExploit.AppendFormat(GeneralPayloads.UnionBasedSelectCountedResultWrapperPart3,
                                              (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Multiple) ? generatedPayloadWithLimit : generatedPayload);

                    columnIndexCounter++;
                }
                else
                {
                    sbCurExploit.AppendFormat(j.ToString());
                }

                if (j < _nrCols - 1)
                {
                    sbCurExploit.Append(",");
                }
            }


            string         query        = QueryHelper.CreateQuery(Url, ExploitDetails.Exploit, sbCurExploit.ToString());
            string         pageHtml     = QueryRunner.GetPageHtml(query, UseProxy ? ProxyDetails : null);
            IList <string> resultsBatch = HtmlHelpers.GetMultipleAnswersFromHtml(pageHtml, query, ExploitDetails, DetailedExceptions);

            string      actualValue       = string.Empty;
            int         separatorIndex    = 0;
            int         columnIndex       = 0;
            string      columnIndexString = "";
            IList <int> columnsProcessed  = new List <int>();

            foreach (string singleResult in resultsBatch)
            {
                //@TODO: strip scripts
                separatorIndex = singleResult.IndexOf(GeneralPayloads.UnionBasedResultSeparator);
                if (separatorIndex != -1)
                {
                    columnIndexString = singleResult.Substring(0, separatorIndex);
                    if (!int.TryParse(columnIndexString, out columnIndex))
                    {
                        continue;
                    }

                    if (columnsProcessed.Contains(columnIndex))
                    {
                        continue;
                    }
                    else
                    {
                        columnsProcessed.Add(columnIndex);
                    }

                    actualValue = singleResult.Substring(separatorIndex + GeneralPayloads.UnionBasedResultSeparator.Length);

                    if (!string.IsNullOrEmpty(MappingFile))
                    {
                        XmlHelpers.SaveToMappingFile(MappingFile, PayloadDetails, actualValue, this,
                                                     (this.ExploitDetails != null) ? this.ExploitDetails.Dbms : string.Empty);
                    }

                    sbResult.Append(actualValue);
                    sbResult.Append(Environment.NewLine);
                }

                if (columnsProcessed.Count == _visibleColumnIndexes.Count)
                {
                    break;
                }
            }
            return(sbResult.ToString());
        }
コード例 #6
0
        public int GetTotalNoOfCustomQueryResultRows()
        {
            if (_nrCols == 0 || _nrVisibleCols == 0 || _visibleColumnIndexes.Count() == 0)
            {
                if (!TestIfVulnerable())
                {
                    throw new SqlInjException("Given script is not injectable using current injection strategy");
                }
            }

            int    count            = 0;
            string generatedpayload = string.Empty;

            if (PayloadDetails == null)
            {
                return(0);
            }

            if (string.IsNullOrEmpty(PayloadDetails.Payload))
            {
                return(0);
            }

            if (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Single)
            {
                return(1);
            }

            generatedpayload = PayloadDetails.Payload;

            if (PayloadDetails.Params != null && PayloadDetails.Params.Count() > 0)
            {
                foreach (var param in PayloadDetails.Params)
                {
                    generatedpayload = generatedpayload.Replace("{" + param.Position + "}", PayloadHelpers.GetData(param.Name, this));
                }
            }

            generatedpayload = string.Format(GeneralPayloads.QueryResultCount, generatedpayload);

            StringBuilder sbCurExploit = new StringBuilder();

            sbCurExploit.AppendFormat(GeneralPayloads.UnionBasedSelectResultWrapper, generatedpayload);

            if (_nrCols > 1)
            {
                sbCurExploit.Append(",");
            }

            for (int j = 1; j < _nrCols; j++)
            {
                sbCurExploit.Append(j.ToString());
                if (j < _nrCols - 1)
                {
                    sbCurExploit.Append(",");
                }
            }

            string query    = QueryHelper.CreateQuery(Url, ExploitDetails.Exploit, sbCurExploit.ToString());
            string pageHtml = QueryRunner.GetPageHtml(query, UseProxy ? ProxyDetails : null);

            var result = HtmlHelpers.GetAnswerFromHtml(pageHtml, query, ExploitDetails, DetailedExceptions);

            int.TryParse(result, out count);
            return(count);
        }
コード例 #7
0
ファイル: ErrorBased.cs プロジェクト: ramss22/Seringa
        public int GetTotalNoOfCustomQueryResultRows()
        {
            int    count            = 0;
            string generatedpayload = string.Empty;

            if (PayloadDetails == null)
            {
                return(0);
            }

            if (string.IsNullOrEmpty(PayloadDetails.Payload))
            {
                return(0);
            }

            if (PayloadDetails.ExpectedResultType == Enums.ExpectedResultType.Single)
            {
                return(1);
            }

            generatedpayload = PayloadDetails.Payload;

            if (PayloadDetails.Params != null && PayloadDetails.Params.Count() > 0)
            {
                foreach (var param in PayloadDetails.Params)
                {
                    generatedpayload = generatedpayload.Replace("{" + param.Position + "}", PayloadHelpers.GetData(param.Name, this));
                }
            }

            generatedpayload = /*UrlHelpers.HexEncodeValue(*/ string.Format(GeneralPayloads.QueryResultCount, generatedpayload);//);

            string query       = QueryHelper.CreateQuery(Url, ExploitDetails.Exploit, generatedpayload);
            string pageHtml    = QueryRunner.GetPageHtml(query, UseProxy ? ProxyDetails : null);
            string countString = HtmlHelpers.GetAnswerFromHtml(pageHtml, query, ExploitDetails, DetailedExceptions);

            int.TryParse(countString, out count);

            return(count);
        }
コード例 #8
0
        private static void ExecuteInternal(BrokeredMessage message, out BrokeredMessage response)
        {
            // We must set the out parameter no matter what, so do that first.
            response = new BrokeredMessage();

            // We'll create the app domain in the outer scope so we can unload it when we are finished (if it was created).
            AppDomain sandboxDomain = null;

            try
            {
                var requestId = (int)message.Properties["RequestId"];

                // Set correlation id of response message using the correlation ID of the request message.
                response.CorrelationId           = message.CorrelationId;
                response.Properties["RequestId"] = requestId;

                // The request will also load the associated route, so we'll use that feature
                // to reduce the number of SQL calls we make.
                var requestTask = TraceUtility.TraceTime("Get Load Request Task", () => Program.RequestRepository.GetRequestByIdAsync(requestId));
                TraceUtility.TraceTime("Load Request", () => requestTask.Wait());

                var request       = requestTask.Result;
                var route         = request.Route;
                var routeSettings = route.RouteSettings;

                // Trace the incoming request URI.
                Trace.TraceInformation("Trace 'Request Uri' - {0}", request.Uri);

                try
                {
                    var ev = new Evidence();
                    ev.AddHostEvidence(new Zone(SecurityZone.Internet));
                    var assemblyType         = typeof(ExecutionSandbox);
                    var assemblyPath         = Path.GetDirectoryName(assemblyType.Assembly.Location);
                    var sandboxPermissionSet = TraceUtility.TraceTime("Create Sandbox Permission Set", () => SecurityManager.GetStandardSandbox(ev));

                    // Exit with an error code if for some reason we can't get the sandbox permission set.
                    if (sandboxPermissionSet == null)
                    {
                        throw new EntryPointException("Unable to load the sandbox environment, please contact Subroute.io for help with this error.");
                    }

                    TraceUtility.TraceTime("Reconfigure Appropriate Permission Sets", () =>
                    {
                        // Remove access to UI components since we are in a headless environment.
                        sandboxPermissionSet.RemovePermission(typeof(UIPermission));

                        // Remove access to the File System Dialog since we are headless.
                        sandboxPermissionSet.RemovePermission(typeof(FileDialogPermission));

                        // Add the ability to use reflection for invocation and serialization.
                        sandboxPermissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));

                        // Add the ability to make web requests.
                        sandboxPermissionSet.AddPermission(new WebPermission(PermissionState.Unrestricted));

                        // Add the ability to use the XmlSerializer and the DataContractSerializer.
                        sandboxPermissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
                    });

                    // We'll create a new folder to hold an empty config file we create, and by
                    // doing this, it prevents the user from gaining access to our configuration
                    // file and the settings within, such as connection strings, infrastructure
                    // and other sensitive information we don't want them to have. Plus it will
                    // allow us to change any configuration settings that are specific to their
                    // application domain, such as default settings and other infrastructure.
                    // We must ensure that we have at least the root configuration XML tag in
                    // the configuration file we create or various dependencies will fail
                    // such as XmlSerializer and DataContractSerializer.
                    var tempDirectory       = Path.GetTempPath();
                    var userConfigDirectory = Path.Combine(tempDirectory, route.Uri);
                    var userConfigFilePath  = Path.Combine(userConfigDirectory, "app.config");
                    TraceUtility.TraceTime("Create Sandbox Directory", () => Directory.CreateDirectory(userConfigDirectory));

                    var configFile = TraceUtility.TraceTime("Generate App.Config File", () => routeSettings.Aggregate(@"<?xml version=""1.0"" encoding=""utf-8"" ?><configuration><appSettings>",
                                                                                                                      (current, setting) => current + $"<add key=\"{setting.Name}\" value=\"{setting.Value}\" />{Environment.NewLine}",
                                                                                                                      result => $"{result}</appSettings></configuration>"));

                    TraceUtility.TraceTime("Write App.Config to Disk", () => File.WriteAllText(userConfigFilePath, configFile));

                    // We'll add one last permission to allow the user access to their own private folder.
                    TraceUtility.TraceTime("Add Permission to Read App.Config File", () => sandboxPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, new[] { userConfigDirectory })));

                    TraceUtility.TraceTime("Create AppDomain", () =>
                    {
                        var appDomainSetup = new AppDomainSetup {
                            ApplicationBase = assemblyPath, ConfigurationFile = userConfigFilePath
                        };
                        sandboxDomain = AppDomain.CreateDomain("Sandboxed", ev, appDomainSetup, sandboxPermissionSet);
                    });

                    // The ExecutionSandbox is a MarshalByRef type that allows us to dynamically
                    // load their assemblies via a byte array and execute methods inside of
                    // their app domain from out full-trust app domain. It's the bridge that
                    // cross the app domain boundary.
                    var executionSandbox = TraceUtility.TraceTime("Create ExecutionSandbox Instance", () => (ExecutionSandbox)sandboxDomain.CreateInstance(
                                                                      assemblyType.Assembly.FullName,
                                                                      assemblyType.FullName,
                                                                      false,
                                                                      BindingFlags.Public | BindingFlags.Instance,
                                                                      null, null, null, null)
                                                                  .Unwrap());

                    // Build the ExecutionRequest object that represents the incoming request
                    // which holds the payload, headers, method, etc. The class is serialized
                    // so it can cross the app domain boundary. So it's serialized in our
                    // full-trust host app domain, and deserialized and reinstantiated in
                    // the sandbox app domain.
                    var uri = new Uri(request.Uri, UriKind.Absolute);
                    var executionRequest = TraceUtility.TraceTime("Create RouteRequest Instance", () => new RouteRequest(uri, request.Method)
                    {
                        IpAddress = request.IpAddress,
                        Headers   = HeaderHelpers.DeserializeHeaders(request.RequestHeaders),
                        Body      = request.RequestPayload
                    });

                    try
                    {
                        // The ExecutionSandbox we'll attempt to locate the best method to execute
                        // based on the incoming request method (GET, POST, DELETE, etc.) and
                        // will pass the ExecutionRequest we created above. In return, we receive
                        // an instance of ExecutionResponse that has been serialized like the request
                        // and deserialized in our full-trust host domain.
                        var executionResponse = TraceUtility.TraceTime("Load and Execute Route", () => executionSandbox.Execute(route.Assembly, executionRequest));

                        // We'll use the data that comes back from the response to fill out the
                        // remaineder of the database request record which will return the status
                        // code, message, payload, and headers. Then we update the database.
                        TraceUtility.TraceTime("Update Request Record", () =>
                        {
                            request.CompletedOn     = DateTimeOffset.UtcNow;
                            request.StatusCode      = (int)executionResponse.StatusCode;
                            request.StatusMessage   = executionResponse.StatusMessage;
                            request.ResponsePayload = executionResponse.Body;
                            request.ResponseHeaders = Common.RouteResponse.SerializeHeaders(executionResponse.Headers);

                            Program.RequestRepository.UpdateRequestAsync(request).Wait();
                        });

                        // We'll pass back a small bit of data indiciating to the subscribers of
                        // the response topic listening for our specific correlation ID that indicates
                        // the route code was executed successfully and to handle it as such.
                        response.Properties["Result"]  = (int)ExecutionResult.Success;
                        response.Properties["Message"] = "Completed Successfully";
                    }
                    catch (TargetInvocationException invokationException)
                    {
                        // These exceptions can occur when we encounter a permission exception where
                        // the user doesn't have permission to execute a particular block of code.
                        var securityException = invokationException.InnerException as SecurityException;
                        if (securityException != null)
                        {
                            throw new RoutePermissionException(GetPermissionErrorMessage(securityException), invokationException);
                        }

                        // Check for BadRequestException, we need to wrap it with the core exception.
                        // These exceptions can occur when query string parsing fails, and since the
                        // user's code doesn't have access to the core exceptions, we'll need to wrap
                        // it instead manually.
                        var badRequestException = invokationException.InnerException as Common.BadRequestException;
                        if (badRequestException != null)
                        {
                            throw new Core.Exceptions.BadRequestException(badRequestException.Message, badRequestException);
                        }

                        // Otherwise it is most likely a custom user exception.
                        throw new CodeException(invokationException.InnerException?.Message ?? "Route raised a custom exception.", invokationException.InnerException);
                    }
                    catch (EntryPointException entryPointException)
                    {
                        // These exceptions occur when an entry point could not be located.
                        // Since we don't have a reference to core in the common library.
                        // We'll instead wrap this exception in a core
                        // exception to apply a status code.
                        throw new RouteEntryPointException(entryPointException.Message, entryPointException);
                    }
                    catch (SecurityException securityException)
                    {
                        // These exceptions can occur when we encounter a permission exception where
                        // the user doesn't have permission to execute a particular block of code.
                        throw new RoutePermissionException(GetPermissionErrorMessage(securityException), securityException);
                    }
                    catch (Common.BadRequestException badRequestException)
                    {
                        // These exceptions can occur when query string parsing fails, and since the
                        // user's code doesn't have access to the core exceptions, we'll need to wrap
                        // it instead manually.
                        throw new Core.Exceptions.BadRequestException(badRequestException.Message, badRequestException);
                    }
                    catch (Exception routeException)
                    {
                        // These are all other exceptions that occur during the execution of
                        // a route. These exceptions are raised by the users code.
                        throw new RouteException(routeException.Message, routeException);
                    }
                }
                catch (Exception appDomainException)
                {
                    // This exception relates to exceptions configuring the AppDomain and we'll still notify the
                    // user, we just won't give them specific information that could reveal our infrastructure
                    // unless an IStatusCodeException was thrown, meaning it's a public exception.
                    var    statusCode          = 500;
                    var    statusMessage       = "An unexpected exception has occurred. Please contact Subroute.io regarding this error.";
                    var    statusCodeException = appDomainException as IStatusCodeException;
                    string stackTrace          = null;

                    if (statusCodeException != null)
                    {
                        statusCode    = (int)statusCodeException.StatusCode;
                        statusMessage = appDomainException.Message;

                        if (appDomainException is CodeException)
                        {
                            stackTrace = appDomainException.ToString();
                        }
                    }

                    request.CompletedOn     = DateTimeOffset.UtcNow;
                    request.StatusCode      = statusCode;
                    request.ResponsePayload = PayloadHelpers.CreateErrorPayload(statusMessage, stackTrace);
                    request.ResponseHeaders = HeaderHelpers.GetDefaultHeaders();

                    Program.RequestRepository.UpdateRequestAsync(request).Wait();

                    response.Properties["Result"]  = (int)ExecutionResult.Failed;
                    response.Properties["Message"] = appDomainException.Message;
                }
            }
            catch (Exception fatalException)
            {
                // These exceptions are absolutely fatal. We'll have to notify the waiting thread
                // via the service bus message, because we're unable to load a related request.
                response.Properties["Result"]  = (int)ExecutionResult.Fatal;
                response.Properties["Message"] = fatalException.Message;
            }
            finally
            {
                // Unload the users app domain to recover all memory used by it.
                if (sandboxDomain != null)
                {
                    TraceUtility.TraceTime("Unload AppDomain", () => AppDomain.Unload(sandboxDomain));
                }
            }
        }
コード例 #9
0
        private static async Task ExecuteInternalAsync(BrokeredMessage message, ICollector <BrokeredMessage> response)
        {
            // We'll always need a response message, so create it now and populate it below.
            var responseMessage = new BrokeredMessage();

            // We'll create the app domain in the outer scope so we can unload it when we are finished (if it was created).
            AppDomain sandboxDomain = null;

            try
            {
                var requestId = (int)message.Properties["RequestId"];

                // Set correlation id of response message using the correlation ID of the request message.
                responseMessage.CorrelationId           = message.CorrelationId;
                responseMessage.Properties["RequestId"] = requestId;

                // The request will also load the associated route, so we'll use that feature
                // to reduce the number of SQL calls we make.
                var request = await Program.RequestRepository.GetRequestByIdAsync(requestId).TraceTimeAsync("Load Request");

                var route         = request.Route;
                var routeSettings = route.RouteSettings.ToArray();
                var routePackages = route.RoutePackages.ToArray();

                // Trace the incoming request URI.
                Trace.TraceInformation("Trace 'Request Uri' - {0}", request.Uri);

                try
                {
                    var ev = new Evidence();
                    ev.AddHostEvidence(new Zone(SecurityZone.Internet));

                    var assemblyType         = typeof(ExecutionSandbox);
                    var assemblyPath         = Path.GetDirectoryName(assemblyType.Assembly.Location);
                    var sandboxPermissionSet = TraceUtility.TraceTime("Create Sandbox Permission Set",
                                                                      () => SecurityManager.GetStandardSandbox(ev));

                    // Exit with an error code if for some reason we can't get the sandbox permission set.
                    if (sandboxPermissionSet == null)
                    {
                        throw new EntryPointException("Unable to load the sandbox environment, please contact Subroute.io for help with this error.");
                    }

                    // We'll create a new folder to hold an empty config file we create, and by
                    // doing this, it prevents the user from gaining access to our configuration
                    // file and the settings within, such as connection strings, infrastructure
                    // and other sensitive information we don't want them to have. Plus it will
                    // allow us to change any configuration settings that are specific to their
                    // application domain, such as default settings and other infrastructure.
                    // We must ensure that we have at least the root configuration XML tag in
                    // the configuration file we create or various dependencies will fail
                    // such as XmlSerializer and DataContractSerializer.
                    var directories = TraceUtility.TraceTime("Setup Filesystem",
                                                             () => SetupFilesystem(route, routeSettings));

                    TraceUtility.TraceTime("Reconfigure Appropriate Permission Sets", () =>
                    {
                        // Remove access to UI components since we are in a headless environment.
                        sandboxPermissionSet.RemovePermission(typeof(UIPermission));

                        // Remove access to the File System Dialog since we are headless.
                        sandboxPermissionSet.RemovePermission(typeof(FileDialogPermission));

                        // Add the ability to use reflection for invocation and serialization.
                        sandboxPermissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));

                        // Add the ability to make web requests.
                        sandboxPermissionSet.AddPermission(new WebPermission(PermissionState.Unrestricted));

                        // Add the ability to use the XmlSerializer and the DataContractSerializer.
                        // Also allows unmanaged code to be executed for drawing operations such as image resize and formatting.
                        sandboxPermissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode));

                        // Add permission to access the nuget package directory so that assemblies can be loaded.
                        sandboxPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, Settings.NugetPackageDirectory));

                        // Add permission to read execution temp directory.
                        sandboxPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, new[] { directories.RootDirectory, @"D:\GitHub\subroute.io\Subroute.Container\App_code\" }));
                    });

                    TraceUtility.TraceTime("Create AppDomain", () =>
                    {
                        var appDomainSetup = new AppDomainSetup {
                            ApplicationBase = assemblyPath, ConfigurationFile = directories.ConfigFile
                        };
                        sandboxDomain = AppDomain.CreateDomain("Sandboxed", ev, appDomainSetup, sandboxPermissionSet);
                    });

                    // The ExecutionSandbox is a MarshalByRef type that allows us to dynamically
                    // load their assemblies via a byte array and execute methods inside of
                    // their app domain from our full-trust app domain. It's the bridge that
                    // crosses the app domain boundary.
                    var executionSandbox = TraceUtility.TraceTime("Create ExecutionSandbox Instance",
                                                                  () => (ExecutionSandbox)sandboxDomain.CreateInstance(
                                                                      assemblyType.Assembly.FullName,
                                                                      assemblyType.FullName,
                                                                      false,
                                                                      BindingFlags.Public | BindingFlags.Instance,
                                                                      null, null, null, null)
                                                                  .Unwrap());

                    // Prepare packages by locating the proper assemblies for the current framework and ensure
                    // they have been downloaded to the packages folder and return their paths.
                    executionSandbox.SetReferences(await PreparePackagesAsync(routePackages).TraceTimeAsync("Prepare Packages"));

                    // To properly load assemblies into the dynamic partial trust assembly, we have to override
                    // the AssemblyResolve method which is only called when an assembly load attempt is made
                    // and fails. We can't use a closure here because to do that, the entire class ExecutionMethods
                    // would have to be serailized across the app domain boundry. So we'll add a string array property
                    // to the ExecutionSandbox class so we can access the references from in the app domain boundry.
                    // Just remember this event is executed inside the partial trust domain.
                    sandboxDomain.AssemblyResolve += (sender, args) =>
                    {
                        var name = new AssemblyName(args.Name);
                        var path = ExecutionSandbox.References.FirstOrDefault(r => Path.GetFileNameWithoutExtension(r) == name.Name);

                        return(path == null ? null : Assembly.LoadFrom(path));
                    };

                    // Build the ExecutionRequest object that represents the incoming request
                    // which holds the payload, headers, method, etc. The class is serialized
                    // so it can cross the app domain boundary. So it's serialized in our
                    // full-trust host app domain, and deserialized and reinstantiated in
                    // the sandbox app domain.
                    var uri = new Uri(request.Uri, UriKind.Absolute);
                    var executionRequest = TraceUtility.TraceTime("Create RouteRequest Instance",
                                                                  () => new RouteRequest(uri, request.Method)
                    {
                        IpAddress = request.IpAddress,
                        Headers   = HeaderHelpers.DeserializeHeaders(request.RequestHeaders),
                        Body      = request.RequestPayload
                    });

                    try
                    {
                        // The ExecutionSandbox we'll attempt to locate the best method to execute
                        // based on the incoming request method (GET, POST, DELETE, etc.) and
                        // will pass the ExecutionRequest we created above. In return, we receive
                        // an instance of ExecutionResponse that has been serialized like the request
                        // and deserialized in our full-trust host domain.
                        var executionResponse = TraceUtility.TraceTime("Load and Execute Request",
                                                                       () => executionSandbox.Execute(route.Assembly, executionRequest));

                        // We'll use the data that comes back from the response to fill out the
                        // remainder of the database request record which will return the status
                        // code, message, payload, and headers. Then we update the database.
                        request.CompletedOn     = DateTimeOffset.UtcNow;
                        request.StatusCode      = (int)executionResponse.StatusCode;
                        request.StatusMessage   = executionResponse.StatusMessage;
                        request.ResponsePayload = executionResponse.Body;
                        request.ResponseHeaders = RouteResponse.SerializeHeaders(executionResponse.Headers);

                        await Program.RequestRepository.UpdateRequestAsync(request).TraceTimeAsync("Update Request Record");

                        // We'll pass back a small bit of data indiciating to the subscribers of
                        // the response topic listening for our specific correlation ID that indicates
                        // the route code was executed successfully and to handle it as such.
                        responseMessage.Properties["Result"]  = (int)ExecutionResult.Success;
                        responseMessage.Properties["Message"] = "Completed Successfully";

                        // Create the response message and send it on its way.
                        response.Add(responseMessage);
                    }
                    catch (TargetInvocationException invokationException)
                    {
                        // These exceptions can occur when we encounter a permission exception where
                        // the user doesn't have permission to execute a particular block of code.
                        if (invokationException.InnerException is SecurityException securityException)
                        {
                            throw new RoutePermissionException(GetPermissionErrorMessage(securityException), invokationException);
                        }

                        // Check for BadRequestException, we need to wrap it with the core exception.
                        // These exceptions can occur when query string parsing fails, and since the
                        // user's code doesn't have access to the core exceptions, we'll need to wrap
                        // it instead manually.
                        if (invokationException.InnerException is BadRequestException badRequestException)
                        {
                            throw new Core.Exceptions.BadRequestException(badRequestException.Message, badRequestException);
                        }

                        // Otherwise it is most likely a custom user exception.
                        throw new CodeException(invokationException.InnerException?.Message ?? "Route raised a custom exception.", invokationException.InnerException);
                    }
                    catch (EntryPointException entryPointException)
                    {
                        // These exceptions occur when an entry point could not be located.
                        // Since we don't have a reference to core in the common library.
                        // We'll instead wrap this exception in a core
                        // exception to apply a status code.
                        throw new RouteEntryPointException(entryPointException.Message, entryPointException);
                    }
                    catch (SecurityException securityException)
                    {
                        // These exceptions can occur when we encounter a permission exception where
                        // the user doesn't have permission to execute a particular block of code.
                        throw new RoutePermissionException(GetPermissionErrorMessage(securityException), securityException);
                    }
                    catch (BadRequestException badRequestException)
                    {
                        // These exceptions can occur when query string parsing fails, and since the
                        // user's code doesn't have access to the core exceptions, we'll need to wrap
                        // it instead manually.
                        throw new Core.Exceptions.BadRequestException(badRequestException.Message, badRequestException);
                    }
                    catch (AggregateException asyncException) // Captures async and task exceptions.
                    {
                        // These exceptions occur when an entry point could not be located.
                        // Since we don't have a reference to core in the common library.
                        // We'll instead wrap this exception in a core
                        // exception to apply a status code.
                        if (asyncException.InnerException is EntryPointException entryPointException)
                        {
                            throw new RouteEntryPointException(entryPointException.Message, entryPointException);
                        }

                        // These exceptions can occur when we encounter a permission exception where
                        // the user doesn't have permission to execute a particular block of code.
                        if (asyncException.InnerException is SecurityException securityException)
                        {
                            throw new RoutePermissionException(GetPermissionErrorMessage(securityException), securityException);
                        }

                        // These exceptions can occur when query string parsing fails, and since the
                        // user's code doesn't have access to the core exceptions, we'll need to wrap
                        // it instead manually.
                        if (asyncException.InnerException is SecurityException badRequestException)
                        {
                            throw new Core.Exceptions.BadRequestException(badRequestException.Message, badRequestException);
                        }

                        // These are all other exceptions that occur during the execution of
                        // a route. These exceptions are raised by the users code.
                        throw new RouteException(asyncException.InnerException?.Message ?? asyncException.Message, asyncException.InnerException);
                    }
                    catch (Exception routeException)
                    {
                        // These are all other exceptions that occur during the execution of
                        // a route. These exceptions are raised by the users code.
                        throw new RouteException(routeException.Message, routeException);
                    }
                }
                catch (Exception appDomainException)
                {
                    // This exception relates to exceptions configuring the AppDomain and we'll still notify the
                    // user, we just won't give them specific information that could reveal our infrastructure
                    // unless an IStatusCodeException was thrown, meaning it's a public exception.
                    var    statusCode          = 500;
                    var    statusMessage       = "An unexpected exception has occurred. Please contact Subroute.io regarding this error.";
                    var    statusCodeException = appDomainException as IStatusCodeException;
                    string stackTrace          = null;

                    if (statusCodeException != null)
                    {
                        statusCode    = (int)statusCodeException.StatusCode;
                        statusMessage = appDomainException.Message;

                        if (appDomainException is CodeException)
                        {
                            stackTrace = appDomainException.ToString();
                        }
                    }

                    request.CompletedOn     = DateTimeOffset.UtcNow;
                    request.StatusCode      = statusCode;
                    request.ResponsePayload = PayloadHelpers.CreateErrorPayload(statusMessage, stackTrace);
                    request.ResponseHeaders = HeaderHelpers.GetDefaultHeaders();

                    await Program.RequestRepository.UpdateRequestAsync(request).TraceTimeAsync("Update Request Record (Error)");

                    responseMessage.Properties["Result"]  = (int)ExecutionResult.Failed;
                    responseMessage.Properties["Message"] = appDomainException.Message;

                    // Create the response message and send it on its way.
                    response.Add(responseMessage);
                }
            }
            catch (Exception fatalException)
            {
                // These exceptions are absolutely fatal. We'll have to notify the waiting thread
                // via the service bus message, because we're unable to load a related request.
                responseMessage.Properties["Result"]  = (int)ExecutionResult.Fatal;
                responseMessage.Properties["Message"] = fatalException.Message;

                // Create the response message and send it on its way.
                response.Add(responseMessage);
            }
            finally
            {
                // Unload the users app domain to recover all memory used by it.
                if (sandboxDomain != null)
                {
                    TraceUtility.TraceTime("Unload AppDomain",
                                           () => AppDomain.Unload(sandboxDomain));
                }
            }
        }