- 01 Oct 2021
- 7 Minutes to read
- Print
- DarkLight
Securing Decisions and Web Application Firewalls (Azure)
- Updated on 01 Oct 2021
- 7 Minutes to read
- Print
- DarkLight
Overview
Decisions as a company and product have a commitment to security and security standards. There are regulatory controls around our Software Development practices and lifecycle as well as controls around our data center and hosting operations for our customers. These controls ensure that the product, once delivered, can be used in environments that have high standards for data and operational security. We strongly recommend best practices and standards for our customers because the application allows the customer to configure processes over which we have no control. Customers installing Decisions to MS Azure may choose to use a Web Application Firewall which adds a layer of security that enforces industry-standard web application security rules. This document will help you understand the MS Azure WAF and Decisions.
Configuration Changes Required for Decisions
We maintain a hardening guide per SOC and PCI obligations that we or our customers have. Reading this document is recommended for any installation that is going to deal with sensitive or public data.
Configuration and Rules in the WAF
Decisions can perform without issue behind the Azure OWASP Rule-based WAF with the following configuration changes made to ensure functional integrity.
Impact on the Product
If the configuration changes listed above are not made, Decisions can still function and most things that people would use day to day will work well. This does depend heavily on the customer's use case. For example, a case management process that requires people to upload documents as evidence would not work well if Rule 920420 is left enabled blocking all file uploads.
It is impossible for us as a company to determine exactly what aspects of implementation will or will not be impacted by using the WAF due to the fact that Decisions allows you, as a customer, to configure your processes and rules to behave in ways and with data that is at your discretion.
Inspect Request Body
Body inspection adds additional security by interrogating the data sent to an application server behind the WAF. Body inspection is useful in creating a more secure environment, but many systems may send data that because of the nature of the application contains special or suspicious characters that will be blocked by the WAF.
A simple example of this is email content. In Decisions, you can configure an email message to be sent to a user. This email, to be user-friendly, would need style elements, links to work the task, maybe an image. In order to configure this email step, Decisions needs to send those elements to the backend to be stored for future use. This content could easily trigger an error on the WAF and cause the request to fail.
If the request body inspection is turned off, WAF does not evaluate the contents of the HTTP message body. In such cases, WAF continues to enforce WAF rules on headers, cookies, and URI providing security for the most common attack vectors.
See a sample configuration from the Azure Portal below:
If SSL is terminating, then the ForceBaseURI line will need to be added to the web.config file, located at C:\Program Files\Decisions\Decisions Web Host\web.config.
This change will require that the following line is added to the keys section under appSettings in the web.config file, as shown in the screenshot below.
<add key="ForceBaseURI" value="[YourHTTPSAddress]"/>
The 128 KB Limit
In MS Azure, using Inspect Request Body forces a limit on all traffic to the backend to 128 KB. This is also difficult because in Decisions you can create rules and flows that very easily and quickly exceed this size in design mode. Enabling this feature makes it very hard to save and test flows reliably, but there’s no clear way to know when this threshold may be exceeded.
Enabling This Setting
With this setting enabled any request over 128 KB will simply be rejected. This impacts the following features and functions. Features and Functions that WILL BE IMPACTED:
- Large Reports or Dashboards
- Flows with many steps
- Rules with many conditions
- Testing sessions that deal with a lot of data.
For more details on exploratory testing and activities within the product that tends to exceed this message size, you may request access to our WAF testing spreadsheet and examine our current results.
Disabling This Setting
Disabling this setting allows Decisions to work normally. This is, for certain, less secure than running with the setting on because the Azure WAF will not be inspecting the bodies of the web requests before sending them to the backend. It is very important to consider that the WAF will still be running against every request and looking for anything that violates the OWASP rules with URIs, Cookies, IP addresses, and Headers. This means that there’s still a level of security being provided by the WAF for the application.
When any request is sent to the Decisions application server the request must:
- Be authenticated
- Be deserialized
Even though we use REST-based web services, the original implementation of Decisions used 100% SOAP services and a SOAP / WCF Service Layer. This is a very important note because it means that the services are based on structured types and type-safe messages. Arbitrary data sent to Decisions simply cannot be processed. This historical baseline means that there is little risk in SQL injection, cross-site scripting, cross-site forgery, or other attack vectors being leveraged when calling a Decisions-based service on the backend without body inspection turned on.
The Decisions Rule and Workflow Engine Web Application communicates with the application server exclusively through this service layer. There are no other entry points to the application server code which control the database, persistence, and user security aspects of the application. These architectural aspects of Decisions limit the need for the WAF to inspect message bodies to provide security; However, we understand that some customers will still want to enforce this additional layer of security.
In order to help you better understand the nature of the calls to the Decisions services on the backend, the following common requests were recorded using web tools.
The following entries are web service calls made from the Decisions web application to the Decisions workflow application server from the client browser. This sequence was taken from the common path of working a task, reassigning a task, and browsing the portal to get to a particular dashboard. Each of the following requests is followed by a “Notes” section which indicates why Decisions as a company does not believe that inspecting the post body of the request itself would provide any real security above and beyond the deserialization and validation of the data request by the Decisions workflow and rule engine.
- https://{ServerName}/decisions/Primary/API/ClientEventsService/js/RemoveFolderRegistration?rand=85{"userContext":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"clientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","folderID":"43abb0fe-aa60-11e8-949f-00155d172301"}Notes: The data sent to Decisions from the web application here is a folder id that needs to be removed. The user context that is indicated by the session must be a valid and registered user session, and the user MUST have permission to delete this folder. Changing the data completely would be discarded, and changing the folder id would require permissions.
- https://{ServerName}/decisions/Primary/API/ClientEventsService/js/WaitForEvents?rand=90{"userContext":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"clientEventsSessionID":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","eventID":"32311c60-9114-11e8-bded-00155d172301"}Notes: Waiting for events requires a valid Client Event Session-Id, tied correctly to a valid Session-Id registered on the server. If the structure is modified, or either session is invalid - then the message is ignored.
- https://{ServerName}/decisions/Primary/API/Assignment/js/GetAllForAssigneesList?rand=64{"context":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"param":7}Notes: Getting all assignees requires access to the user list with a “Can Use” permission on the application server.
- https://{ServerName}/decisions/Primary/API/Assignment/js/ChangeAssignment?rand=65{"context":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"assignmentId":"238506b0-9874-4045-833f-c65d1dd342ee","changeDto":{"AccountIDs":["863c18c7-cadd-434c-923d-88de35f444e6"],"GroupIDs":["681f6b25-a3fa-11e7-9431-00155d0afd03"],"Permissions":[],"Roles":[],"Priority":1,"NotificationMessage":"","NotifyOnlyNewAssignees":false}}Notes: This web service call can only deal with assignments. The Assignment Id and the assignees indicated must be accurate ids of objects in the Decisions environment for which the user has the appropriate access. If the body of this service call were compromised it may be possible that an attacker could cause the specific workflow task to be assigned to another valid user in the system by account id.
- GET https://{ServerName}/decisions/HUI/API/Script/GroupService?rand=47Notes: This request is a GET and only provides data about the GroupsService. Most simple queries are done via GET and there would not be subjected to body inspection in any way.
- https://{ServerName}/decisions/Primary/API/ClientEventsService/js/RemoveFolderRegistration?rand=7{"userContext":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"clientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","folderID":"11c1fb54-419e-11e8-b3e8-00155d172301"}Notes: This service call removes a “notification subscription” from the client. If an attacker were able to inject another folder id into this request they may be able to prevent in-browser pop-up notifications to a user about tasks that were being actively assigned.
- https://{ServerName}/decisions/Primary/API/ClientEventsService/js/PingWithFolders?rand=27 {"userContext":{"__type":"SessionUserContext:#DecisionsFramework.ServiceLayer.Utilities","SessionValue":"e8c70024-06cd-4af0-913d-f51aa676807d","ClientEventSessionId":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","DisplayType":"2","StudioPortal":true,"BrowserUserAgent":null},"clientEventsSessionID":"2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","folderIds":[null,"TASK_QUEUES_FOLDER"],"clientEvents":["UINotificationQueue","HomePageChangedEvent","ConfigurationStorageBus","InvokeActionEvent","ReportContextEvent","ReportRefreshEvent","FolderEntitiesChangedMessage","DataTypeChanged","DataTypeRemoved","PortalSettings.Save","DesignerSettings.Saved","FavoriteEntityEventId","ThemeChangedEvent","TAGS_EVENT_ID","ENTITY_TAGS_CHANGED_EVENT","ShowMessageBoxEvent","FolderCountChange","2e53c6b0-ffa0-4a2d-a14f-d24525959bb7","ClearAllFolderViewDataCache","FolderChangedMessage","FolderAddedMessage","FolderRemovedMessage","ActionsEventId","FolderChangedEvent","PortalNavigationEvent","StudioNavigationEvent","RunFlowEvent","ServiceCatalogEvent","CD59EA1A-7E04-4F79-A3CF-A65C73D85665","DateRange_PC_efe84a63-e92e-4426-b03f-923414bdf19e","RecentPickedEntityServiceEvent","DateRange_PC_ada13087-b645-41dd-afb8-1d6ddcab7660","DateRange_PC_735e075c-0b98-455f-b19a-d191effe5271","7b31c97d-986d-4fa0-8757-1d3ab3061f6c","161923ff-7eb2-48b3-a318-b30a83ee1a85","TASK_QUEUES_FOLDER"]}Notes: this request by Decisions is made from the web application client in the user’s browser to the backend periodically to register the folders and areas of the product for which the client is currently interested in receiving events. Changing or adding folder ids to this request would potentially disrupt the ‘live update’ experience of a user until the next refresh.
Overall
In any of the above circumstances or cases that move far beyond these situations, it is very difficult to see how body inspection provides any real security to a company using Decisions. Every one of these calls to Decisions must be authenticated and that authenticated call MUST originate from the IP address of the logged-in user. If the user can log in, and has appropriate permission, then that user could do far more damage much more quickly by simply logging into the application and using the app itself to mutate data. Since every call must conform to a contract that is type-safe and atomic, Decisions as a company does not believe that body inspection of POST calls to the application server back-end provides any real additional security to the customer.