Threat Agents | Attack Vectors | Security Weakness | Technical Impacts | Business Impacts | |
---|---|---|---|---|---|
______ | Exploitability EASY |
Prevalence COMMON |
Detectability EASY |
Impact MODERATE |
______ |
Consider the types of users of your system. Do any users have only partial access to certain types of system data? | Attacker, who is an authorized system user, simply changes a parameter value that directly refers to a system object to another object the user isn't authorized for. Is access granted? | Applications frequently use the actual name or key of an object when generating web pages. Applications don't always verify the user is authorized for the target object. This results in an insecure direct object reference flaw. Testers can easily manipulate parameter values to detect such flaws and code analysis quickly shows whether authorization is properly verified. | Such flaws can compromise all the data that can be referenced by the parameter. Unless the name space is sparse, it's easy for an attacker to access all available data of that type. | Consider the business value of the exposed data. Also consider the business impact of public exposure of the vulnerability. |
A single page web application - and especially those built using backbone.js - tend to have be composed of a single base HTML page (this single page), a set of javascript models, routers and views, a set of templates for the views and a set of server side services providing data. The service side services will typically be REST based and deliver JSON.
If both the client side and server side is implemented using JavaScript, we can imagine having the same data representation on both the server side and client side. It will be the same data object, serialized as JSON when being transferred between browser and server. On the client side, a framework like backbone.js will wrap the data object inside a model augmenting it with functionality. The same thing may or may not be done on the server side.
If the server side is also using a document oriented NoSQL-database, we can even imagine having the same data model stored in the data store. No need for grumpy old ORM-frameworks to transfer data back and forth from one model to the other.
While having the same model in every part of the application has obvious positive sides like simplification and consistency, it also introduces problems, especially if we don't take care how we implement our server side services.
Consider an application for Call for Papers for a conference. The application accepts suggestions from registered users, and organizers (admins) can approve talks. In fact I created such a system for demonstrating the kind of problem I'm about to explain and you can find it on Github. A typical talk suggestion could look something like this:
{
"id" : 1,
"title" : "funnybone.vbs",
"description" : "A backbone.js implementation in vbscript"
}
The classic problem occurs because the server side fails to check the users access to the object he/she is editing. So in the Call for Papers app, what happens if on speaker tries to alter another speakers talk? While this may not be possible to due to access control checks in the client side javascript, there is nothing stopping a determined attacker from simply changing the code from the javascript console in order to have his/her way. So while having these controls in place is a good thing from a usability perspective, we also need to implement access control on the server side. These kinds of attack have earlier been performed on photo sites (I think there was even one in Facebook) and even online backing applications where one user could access other user's accounts. The most famous of the recent ones, is probably Patrick Webster's disclosure to First State Super Annuation where he demonstrated a problem in their website allowing him to download other peoples' documents.
We forgot about something in the model above. If admins should be allowed to approve talks, we probably need some fields for that too. So lets go ahead and add that:
{
"id" : 1,
"title" : "funnybone.vbs",
"description" : "A backbone.js implementation in vbscript",
"approved" : false
}
While having this field on the client side is good as it allows us to display which talks have been approved and not, it also creates a potential security issue. If a speaker is able to update a talk, what will stop that speaker from also updating the approved
field. A malicious speaker could do this even if this fields has no corresponding UI element. He could simply add that element in firebug, or modify the JSON using an interception proxy (like OWASP Zap) on its way back to the client. The attacker could even add fields that are not present in the JSON, but which the attacker assumes are available in the database. He could try to add a role
field when creating or updating his user account. Or modifying timestamps like Egor Homakov demonstrated on Github(see image on the right). This is often referred to as mass assignment or overposting, and is not only a problem in javascript based application. It's a weakness in how data is mapped to objects on the server side.
It's obvious that in order to stop the above mentioned speaker from approving his own talk, we can not use client side code. This needs to be fixed on the server side. The server needs to know which fields it should support updates for given the current user role.
There is another problem that can also occur if the server side does not filter the incoming JSON. If the JSON is simply converted to a client side object containing exact same fields, and then those fields are dumped into a document database or key value store, what happens if the attacker add 1000 new fields? Or 1 million new fields? Now we suddenly have a simple object for a talk, taking several MBs or even GBs of disk space/memory. As the name implies this problem might as well have been mentioned under A1 - Injection, but seemed a better fit here.