If you or your team is writing web applications, one of the most powerful defense tools at your disposal is good application logging. Writing code to generate logs used to be one of my least favorite programming “chores''. As I’ve grown in my career I’ve learned the importance of proper logging and its role in the success of an application. Proper logging helps not only from a debugging standpoint, but it can help you catch an attacker and I’ll describe one example of how you can implement this in your application.
Let’s imagine you have a simple application with an employee or user management page with typical endpoints such as:
GET, POST /employees and GET,PUT, DELETE /employee/{employeeId}
These endpoints would allow for CRUD (Create, Read, Update, Delete) and would absolutely be targeted by an attacker or pen tester conducting a web application assessment. One of the first things the attacker would do is fuzz the ID and place either a different ID or a bad ID to see if your application would either produce an error message, or get you the different user based on the ID they changed. Either of these use cases are ones that a traditional user should never encounter and as such they’re cases we can code for on the back-end.
When a traditional user is using the manage users functionality, they should always be updating valid IDs for users they have access too, and so long as this is done through your user interface, we should never see IDs in the URLs that don’t exist or aren’t valid IDs. Under this assumption, we can log anytime this isn’t the case. For instance if an ID is supplied that either isn’t a valid ID, or isn’t a valid ID for a user, both of these cases can be logged.
For example, if your IDs are simple numbers (1,2,3,4,5) and ‘; is placed in the employeeID, well then you know this ID will never be valid and can log this. Or if you’re using UUIDs and anything is supplied that isn’t a UUID.
When the attacker inserts a bad value in the ID, we can log this event and log as much information as we can obtain the user. This could be their IP, User Agent, and even user information, if they are an authenticated user. We can also use descriptive event types specific to security. See the sample JSON event below.
{
"level": "INFO",
"time": 1617114005449.35,
"caller": "server/users.go:115",
"message": "Potential tamper",
"program": "acme-web",
"version": 0.1,
"eventType": "security",
"eventSubcategory": "tamper",
"username": "malicious.user@test.com",
"sourceIP": "127.0.0.1",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko"
}
These events can then be fed into a SIEM solution and allow for alerting on a spike in any security event count.
While this does create overhead from a development standpoint, I believe the tradeoff is worth it. Investing time into building proper logging into your applications will provide you with the capability to catch an attacker and have a better understanding of how your applications are actually operating in production.
Happy coding!