Security is one of the big problem of the modern web, business moved to web application and security become an important part of application development. One side of the problem is adding standard and proved procedure to avoid risk of basic attacks like SQL or NO SQL injection, but big part of security was programmed at application level.
If you are using SPA with some client framework like Angular and have business logic exposed with API, (Ex ASP NET Web API), you cannot trust the client, thus you need to validate every server call for authorization and authentication.
When API layer is exposed to a web application it is one of the preferred attack surfaces for your application. Never ever trust your UI logic to protect from malicious calls
One of the most typical attack is forging calls to your API layer, a task that can be automated with tools like BURP Suite or WAPT and it is a major source of problem. As an example, if you have some administrative page where you grant or deny claim to users, it is imperative that every call should be accepted only if the authenticated user is an administrator of the system. Application logic can become complicated, as an example you can have access to a document because it is linked to an offer made in France and you are the Area Manager for France. The more security logic is complex the more you should test it, but you probably cannot cover 100% of the situations.
In such scenario it is imperative that every unauthorized access is logged and visible to administrators, because if you see that there is a spike in forged requests you should immediately investigate, because probably your system is under attack.
Proactive security is a better approach, you should immediately be warned if something suspicious is happening in your application.
Once you determine that there was a problem in your app you can raise a SecurityAlertLog but then the question is: Where this log should be stored? How can I visualize all SecurityAlerts generated by the system? One of the possible solution is using Azure Application Insights to collect all alerts and use it to monitor trend and status of security logs.
As an example, in our web application, when the application logic determines that the request has security problem (ex, user trying to access resource he as no access to), a typical HTTP Response Code 403 (Forbidden) is returned. Angular application usually prevent such invalid calls, so whenever we found a 403 it could be a UI Bug (Angular application incorrectly request a resource current user has no access to) or it could be some malicious tentative of accessing a resource. Both of the situation is quite problematic from a security perspective, so we want to be able to log them separately from application log.
Security problems should not be simply logged with the standard log infrastructure, but should generate some more visible and centralized alert.
With Web API a possible solution is creating an ActionFilterAttribute that is capable of intercepting every Web API Call, it depends on a list of ISecurityAlertLogService, a custom interface that represent some component capable of logging a security alert. With such configuration we can let our Inversion of Control mechanism to scan all implementation of ISecurityAlertLog service available to the system. As an example we log security Exception in a specialized collection in Mongo Database and on Azure Application Insights.
Figure 1: Declaration of a Web API Filter capable of intercepting every call and send security logs to a list of providers.
An Action Filter Attribut is a simple class that is capable of inspecting every WebApi call. In this scenario I’m interested in inspecting what happened when the request ends
Figure 2: Filter is capable of inspecting each call upon completion and can verify if the return value is 403,
Thanks to the filter we can simply verify if the return code is 403 or if the call generates an exception and that exception is a SecurityException; if the check is positive someone is tampering with requests or the UI has a security bug, a SecurityLogAlert is generated and it is passed to every ISecurityAlertLogService
Thanks to Azure Application Insoghts we can track the alert with very few lines of code.
Figure 3: Traking to AI is really a few lines of codes.
We are actually issuing two distinct telemetry events, the first one is a custom event, it contains very few data: most important is name, equal to string SecurityProblem concatenated with property type of our AlertMessage. That property contains the area of the problem, like ApiCall or CommandCall, etc. We also add three custom properties. Of the three “Type” property is important because it helps us to separate SecurityAlertMessages events from all other events that were generated by the system; user and ip address can be used to further filter security alerts. The reason why we are using very few information is that an Event is a telemetry object that cannot contain much data, it is meant to simply track something that happened in the system.
Then we add a Trace telemetry event, because a trace can contain much more information; basically we are tracing the same information of the Event, but the message is the serialization of the entire AlertMessage object, that can contain lots of information thus is not suited for a Custom event (if the custom event is too big it will be discarded)
With this technique we are sure that no SecurityAlert Custom Event will be discarded due to length (we are tracing minimum information) but we have also full information with TrackTrace. If a trace is too big to be logged we will miss it, but we will never miss an event.
Figure 4: Telemetry information as seen from the Visual Studio Application Insight Query window.
As you can see, I can filter for Type : SecurityAlertMessage to inspect only events and tracing related to security, I have my events and I can immediately see the user that generates the events.
Centralizing the log of multiple installation is a key point in security, the more log location source you need to monitor, the more is the probability that you miss some important information.
An interesting aspect is that when the software initialize TelemetryClient it adds the name of the customer/installation, so we can have a single point where all the logs of every customer is saved. From the telemetry we can filter for customer or immediately understand where the log was generated.
Figure 5: Customer properties allow us to send all telemetry events to a single Application Insight instance from multiple installation.
With a few lines of code we now have a centralized place where we can check security alert of our installations.
Gian Maria Ricci