Rapid development often opens up nasty vulnerabilities

Real security vulnerabilities always always speak louder.

As a pentester, I enjoy working with platforms designed with rapid development frameworks, such as Ruby-on-Rails, Django, AdonisJs, Express, etc. They facilitate the development process by distributing Data Models to all architectural layers, including the client browser. Ideally ViewModels requires to control client input and output, however, it is an additional work to transform ViewModels to DataModel and back. Developers using RAPID frameworks often skip the layer of ViewModels, develop only DataModels that is exposed automatically on client side using generated REST services. Undoubtedly, the development speed increases rapidly.

I don't want to say those frameworks are inefficient or there's something wrong with them. Those frameworks are quite secure but provoke more bugs than others.

For example, once I worked on a ASP.NET MVC project where developers put the system under danger by using approach with lack of ViewModels layer.

Vulnerability

Due to the weak validation of DataModels from input traffic, sometimes it is possible to inject additional fields that is not supposed to be used by logic.

For example, the system has a server method that allows by changing only a user name field and returns the whole user profile object. Attacker can copy returned data, change attributes and send it back to this method. Some additional fields (password, user roles) in a Data Model may changed in a database bypassing standard workflows.

Below I shared real examples from projects we pentested. All found vulnerabilities are already fixed, in any case, any confidential data on screenshots is hidden.

System 1.

By default, the system allows changing user name only. Due to the weak fields validation, we managed to add an email field and changed the user login. More to that, all invitations are sending to other users from an unvalidated email.

System 2.

In this case, an ordinary user could escalate his privileges to an admin role (with broader rights obviously), by adding an extra field roles. By putting in the URL field "/admin" he easily got access to the admin profile that contained financial transactions, user data, reports, etc.

System 3.

In this case, a pentester was able to extend a free subscription for an unspecified period of time. Obviously, it has to ask for payments.

The above-mentioned method allowed only to change a branding color of the workspace. In return, it returned the whole dump of StripeCustomer object that contained a payment fields. We copied the StripeCustomer object and updated the payment field as if it's already paid. In the same way, we could copy the payment data of any other user and inserted it at our other workspaces.

System 4.

Last but not least. This system has had a similar security issue: intruders could change a password and an access key without being caught by a set workflow. Additionally, the system lacked a defense against CSRF and had a long TTL period for authentication cookies. It increased seriously a calculated business risk for this vulnerability. A malicious user could make a payload (change password post request) on another popular web site. Anyone who access this public web site will lose access to target system for sure.

Server code metadata contained "hide" attribute for the ‘password’ field. It allowed to exclude this field in a returning DataModel, although at the same time the input data processed the field undoubtedly.

Tips

Never trust to any user input data

Control output data

Be careful with systems that do not separate ViewModel and Model.

Learn thoroughly security measures provided by your framework.

The article is provided for training and educational purposes only. Presented examples illustrate mistakes that should be avoided in your work.

Denis Koloshko, Penetration Tester, CISSP