As a web developer, I often take on projects involving feature enhancements or bug fixes for existing applications. A recurring theme in these projects is the heavy reliance on pre-built applications from platforms like Codecanyon. In fact, around 80% of the projects I've worked on stem from there. While these ready-made solutions offer a quick and efficient way to deploy applications, they often come with hidden pitfalls that developers overlook. One of the most common and dangerous pitfalls is poor handling of permissions and security validation, especially when relying too much on client-side attributes.
Mistake 1: Handling Permissions with “hidden” or “disabled” Attributes
One of the most frequent mistakes I encounter is developers depending entirely on frontend attributes like hidden
or disabled
to control permissions. Here’s a typical example:
<button class="btn btn-primary" data-toggle="modal"
data-target="#add_user_modal"
@if(!auth()->user()->can('add.user')) disabled @endif>
</button>
<div id="add_user_modal" class="modal-dialog modal-md modal-dialog-centered"
@if(!auth()->user()->can('add.user')) hidden @endif>
</div>
In this example, the intention is to prevent users without the add.user
permission from accessing the button and modal. However, this method opens the door for unauthorized users to exploit the application by simply inspecting the page and using a little JavaScript to remove the disabled
and hidden
attributes:
let button = document.querySelector('.btn.btn-primary[data-toggle="modal"]');
let modal = document.querySelector('#add_user_modal');
// Enable the button
if (button.hasAttribute('disabled')) {
button.removeAttribute('disabled');
}
// Show the hidden modal
if (modal.hasAttribute('hidden')) {
modal.removeAttribute('hidden');
}
By running the above code, even a user who isn’t authorized to add a user can bypass the frontend restrictions, gaining access to the functionality. Relying solely on these client-side restrictions is insecure and should never replace proper server-side validation.
Mistake 2: Using "readonly" or "hidden" Fields for Critical Values
Another similar mistake I often encounter is the use of readonly
or hidden
input fields for critical data such as total amounts in e-commerce platforms. For instance, developers may make the "Total" field read-only or hide it entirely, assuming users can't tamper with it:
<input type="number" name="total" value="100" readonly>
The problem arises if the backend fails to revalidate this field before saving the data. An attacker can inspect the field in their browser, modify its value, and submit an altered form:
document.querySelector('input[name="total"]').value = "1";
This kind of manipulation can lead to unauthorized changes to key data, such as lowering the total order amount in a shopping cart. As a developer, it's essential to perform all critical calculations and checks server-side to ensure the integrity of the data.
The Importance of Server-Side Validation
Both of the above examples underscore the critical need for server-side validation. While frontend attributes like hidden
, disabled
, and readonly
can enhance user experience by hiding or disabling unauthorized elements, they must not be relied upon as security mechanisms. Client-side code can be easily manipulated by anyone with access to the browser's developer tools.
To safeguard your application, always ensure that proper permission and data validation is performed on the backend. This guarantees that even if a user attempts to bypass frontend restrictions, they won’t be able to access or alter sensitive functionalities or data.
Other Common Client-Side Security Mistakes in Pre-Built Apps
Storing sensitive information in JavaScript:
Developers sometimes store API keys, session tokens, or other sensitive data in the JavaScript code. Since this code is sent to the user's browser, it's easily accessible to anyone who inspects the code. These should always be handled on the server-side.Relying on client-side form validation:
While using HTML5 attributes likerequired
orpattern
for form validation is convenient, never trust them for critical validation. Users can easily bypass this by disabling JavaScript or manually submitting a request. Always validate inputs on the server.Insecure AJAX requests:
AJAX requests often expose endpoint URLs that may allow unauthorized actions if not properly secured. Ensure that each request is authenticated and authorized server-side.
Thank you for taking the time to read this article! If you'd like to see more content like this, feel free to follow me. If you need assistance with Mpesa or any other API integrations, don't hesitate to reach out via Email or connect with me on LinkedIn. I'm also building ThulaZone, a collection of free, ad-free tools designed to simplify your day-to-day tasks - things you might usually pay for elsewhere. Be sure to check it out and see what I've created for you.
Keep striving, stay inspired. Until next time - Adios!
Top comments (0)