Delusive security of the web development

Security in the web

Security in the web development offers some different challenges comparing to desktop application security.

The most important fact is, in the web development, we do not control the client – the web browser.

 

The task was simple – add a delete button

Imagine a simplified CRM (Customer Relationship Management) web platform in a beta stage. Few companies are using it, one manager and a few regular employees for each company.

The system was designed by a junior developer alone . Newly hired developer was assigned to help due to the grow of new needed functionalities. Junior developer recently added a delete client button for managers and announced we are ready to publish the change.

 

Only for managers?

The code was this:

$(document).ready(function() {
  if(@IsManager == false) {
    $('button#delete').prop('disabled', true)
  }
});

function deleteSelectedClient() {
  //delete the client with selected ID
}

What does the code mean? When the page was loaded by someone else than a manager, the button got the disable attribute. The button was always available to press for managers, and disabled for regular users.

The new developer called junior one immediately after seeing this code and he:
-logged as a regular userdelusive-security-web-development
-used Inspect element feature (just pressing F12 in a browser)
-removed the disable attribute

Delete button changed its state to enabled. Regular employee now could delete the client! Something that should be allowed only for a manager.

 

Fix #1 – hide and obfuscate

To prevent regular employees from even knowing there is a delete feature, junior developer made the button hidden instead of disabled (using client side JS: display: none)

Hiding a feature is always a good idea in the terms of security, “What an eye can’t see a thief won’t steal”. The best security is when nobody even knows there is something they can hack into.

However, the code was still reachable. After some thought the developer obfuscated the code. Yet, it still could be figured out what it does.

 

Fix #1.1 – generate on the server-side

Newly hired programmer came to the rescue second time with an advice: generate role-specific code only for that role and on the server side.

Everything seemed to be fine at that moment. The button was visible in the HTML only for managers, as well as function calling controller to delete a client.

 

Fix #1.2 – validate requests

New developer thought for a while and found another problem. When being logged as manager A, having clients 1, 2 and 3, he changed HTML using Inspect Element again, and changed ID of a selected client to 4.
When the delete button was pressed, client from another company was deleted!

The solution couldn’t be simpler. Validate everything on the server side. Validate every request that sends out sensitive data.

Validation on a request returning all zip codes in your country is not required, but won’t hurt for consistency. Someone in the future may assume everything is secured and would add more data to be returned in that one, insecure action.

Validation on the server (model) side should happen for other reasons as well, e.g. when someone wants to update an order which already changed status. But we are not diving into concurrency issues in this post.

Now every request is properly validated by this simple question: “Is this user authorized to do this action, on this data?”

 

Fix #1.2 – URL actions too

After all these things were brought up, developers decided to review the security of the whole CRM web application.

When applying validation to various requests, they’ve spotted that most dangerous were requests returning data for clients. They could type http://greatcrm.com/client/104 and see details for that client, even if it was not their client.

Fortunately, not logged users couldn’t see the page.

 

Fix #2.0 – overlays and others

Similarly, developers spotted and had to fix other issues, like important content blocked only with a pop-up and overlay, easily removed via Inspect element tool again.

Minimal length for a password was only validated on the client-side.

Finally, some sensitive information and TODOs were left out in Javascript comments.

 

Summary for a security of the web development

The situation above never happened but remember what they say: “There is a grain of truth in every story”.

I’ve ever wondered why this important aspect of a web development is often simplified to “validate on the model, not the view” or “make proper permissions”, without emphasizing how disastrous would be doing otherwise.
It is fairly easier to “hack” vulnerabilities described in this post than do a SQL Injection / XSS / CSRF, and those are always mentioned.

Again, it’s important to have the “is there a way to access this data for intruders” attitude to at least close most obvious security holes.

Security of the web development should be looked at different angles than executable applications.

Wrapping up:

  • hide power actions,
  • obfuscate code,
  • generate code on the server-side,
  • validate all requests,
  • everyone can see your client-side code

 

These topics were covered nicely by Troy Hunt on Pluralsight in his course AngularJS Security Fundamentals, which touches whole web security on the example of AngularJS.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *