ASP.NET MVC and Angular based enterprise web application is hosted for external users access. We encountered a scenario like an user can manipulate the values shown in the disabled fields and submit so using the browser developer tool. e.g. (1) Input field of Vehicle Name, description etc. is disabled in the edit mode, but user can set the read-only field property to editable using dev tool and manipulate the actual value to something else.
similarly, e.g. (2) Customer details are fetched by ID from Cust db and shown on the screen. The customer details are expected to be saved in another db with a few more inputted details, but user edits the read-only customer fields using dev tool and submits.
As a solution, introducing a server side validation between retrieved and sent back values on every submission does not seem to be a right approach.
So, how to protect the read-only or static values from manipulating with browser or other dev tools?
As a solution, introducing a server side validation between retrieved and sent back values on every submission does not seem to be a right approach.
Contrary to what you appear to believe, that is the solution.
You cannot prevent the user from crafting their own HTTP request. You cannot prevent the user from hitting F12 and sending you garbage. It is up to you to validate whether the user is allowed to update the data they send you, and whether they are allowed to read the data they request.
Client-side validation is being nice for your users; server-side validation is an absolute necessity.
Related
I have completed the source code scan (ASP) using the Fortify source code scanner.
Many hidden fields shows as a vulnerability. Like this one:
<input type="hidden" name="ToSave" value="0" />
How do I fix this issue to receive a passing test?
Thanks in advance
Mahesh
If this is application state and is not modified by the user:
Passing application state thru the browser is always a bad idea and is one of the first things that the hacker will exploit.
If this is application state: use proper ASP session management and save the session state on the server when you send the page to the user, and look up the session state on the server when the request is returned. In ASP.NET with C# you might do something like this:
Session(“ToSave”) = false;
When you send the response to the browser (e.g. send the page). Then, when you get the request back, because you’re using ASPs session management, session will have the state that you set.
If this is not application state but is a hidden field that is calculated by JavaScript in the browser and is used on the server side:
Please look at the design of the application. I do a ton of these code reviews and usually find that the application is doing something in JavaScript that should only be done on the server side. One example would be calculating the score of a test on the form putting that score in a hidden field and accepting that field on the server. Another example would be calculating the ‘next’ page in a flow and putting a marker in a hidden field. If you want to provide something like a score on the browser for user convenience use that's fine but make the official calculation (and decision, if applicable) on the server.
An attacker can easily see these values and create a request that would break your application, or worse, get the attacker something that he or she did not deserve.
In any case hidden fields are cached on the browser just as any pages are cached so it might not be wise to use hidden fields if they contain data you expect the user to not be able to see.
So, bottom line, I would agree that you shouldn't use hidden fields.
Here's the situation: I've got an application where you begin at a screen showing a list of countries. You choose a country, and this becomes the ambient country that the application uses until you change it. This ambient country is stored in the Session so the application doesn't have to pass around a CountryId in every single url. But I also want to support permalinks to country specific content, so I guess there needs to be a "Get Permalink" button, which creates a permalink that does contain the CountryId, because it obviously has to work independent of the current session.
Here's the question: My understanding is that because selecting a country changes the session state, one should only do it via POST. But then if the user comes in via GET with a permalink containing, e.g. CountryId=123, what should happen? Should the page update the Session with country 123? In this case, it would be breaking the rule that you can change the session ONLY via POST. But if it doesn't change the session, then all the code that relies on the session won't work, and I'd have to have code redundant ways to generate the page.
OR, should the page have some sort of mechanism for saying "use the session value, but override with any query string value if there is one (and don't modify the session at all)?
OR, am I misunderstanding the POST rule entirely?
The real issue here is the fact that you are using a Session. You cannot provide permalinks because the data that you have stored in the session might have expired when the user follows this links later. So you must somehow persist this data into a more durable datastore when someone requests you to generate a permalink. So when a user asks for a permalink you will go ahead and persist all those search criteria that were used to perform the search into your data store and obtain an unique id that will allow you to fetch them later. Then give the user the following permalink: /controller/search/id where the id represents the unique identifier tat will allow you to fetch the criteria from your data store, perform the search and reconstruct the page as it was.
We have been using asp.net mvc for development. Sometimes, we need to put some hidden fields on form that are shoved in the model by modelbinder (as expected). Nowadays, users can easily temper the form using firebug or other utilities. The purpose of hidden field is mostly to provide some information back to server on as is basis and they are not meant to be changed.
For example in my edit employee form I can put EmployeeID in hidden field but if user changes the employeeID in hidden field, wrong employee will be updated in the database. in this scenario how can we keep the integrity of hidden fields.
You need to enforce security to ensure that the person doing the modification has permission to do so. I'd also put the id in the URL typically rather than a hidden field, relying on the security to ensure that people don't modify things that they shouldn't be able to. If they do have permission to modify the item when changing the id manually, it shouldn't be a problem. The important thing is to make sure that a person can't change the id manually and get access to something they shouldn't. Enforcing server side permissions solves this problem. You can easily do this using Roles in conjunction with the AuthorizeAttribute.
if user changes the employeeID in
hidden field, wrong employee will be
updated in the database
This is a major security hole in your website. In everything you do with web development, no matter how clever someone's code might be or how much you think you'll be ok as long as users don't do something, remember one golden rule: Never implicitly trust data received from the client.
In order to modify anything in your website, the user must be logged in. (Right?) So in any attempt a user makes to post a form to the website (especially one which can modify data), double-check that the user submitting the form has permission perform the action being requested on the data being specified.
Ideally, every action which isn't completely public and unsecured should have a server-side permissions check. Never, ever trust what the client sends you.
One potential alternative would be to store that static, single-use information in TempData on the server and not pass it to the client where it could be tampered with. Keep in mind that by default TempData uses Session and has limitations of its own - but it could be an option.
My application (Asp.Net MVC) has great interaction with the user interface (jQuery/js). For example, setting various searches charts, moving the gadgets on the screen and more .. I of course want to keep all data for each user. So that data will be available from any page in the Dumaine and the user will accepts his preferences.
Now I keep all data in a cookie because it did not seem logical asynchronous access to the server each time the user changes something and thet happens a lot.When the user logout from the application I save the cookie to the database.
The Q is how to save the settings back to the db - from the client to the server.
because the are a lot of interactin that I want to record.
example scanrios: closing widget,moving widget,resizing menues, ordering columens..
I want to record that actions. if I will fire ajax saving rutine for each action
ןt will be too cumbersome. Maybe I have no choice..
Maybe I should run an asynchronous saving all of a certain interval seconds.
The problem is the cookie becomes very large. The thought that this huge cookie is attached to each server request makes me feel that my attitude is wrong.
Another problem cookies have size limit. It varies from your browser but I definitely have been close to the border - my cookie easily become 4kb
Is there another solution?
Without knowing your code, have you considered storing the users preferences in a/your database. A UserPreference table with columns for various settings is a possibility.
You could update it via AJAX/JSON if you had a 'Save Preferences' option, or just update it on postback.
EDIT 1: After thinking about it, I think having an explicit 'save preferences' button would be beneficial and practical.
Somewhere on your page, where the use edits the things that generate the cookie, put an button called save, then hook up a jQuery click handler. On click, build a CSV string or another method of storing the preferences for posting back to the server, then use $.post to send it back to an action method in a controller.
Once there, store it in the database somehow (up to you exactly how), then return a JSON array with a success attribute, to denote whether the preference storing was successful.
When the page is loading, get the preferences out of the database and perform you manipulation.
Another solution would be to store the user preferences into the session and write some server side logic (like action filter) that would write those preferences as JSON encoded string on each page (in a script tag towards the end of the markup) making them available to client scripts.
I have made a little app for signing up for an event. User input their data and click "sign me in".
Now sometimes people are double in the database, the exact same data that got inserted 2 times very quickly after each other. This can only mean someone clicked the button twice, which caused two posts to happen.
This is common web problem, as credit card apps and forum apps often say: "Clicking once is enough!".
I guess you could solve it by checking for the exact same data to see if the post is unique, but I wonder if there are other methods.
This ofcourse does not count for ASP.NET webforms, because POST doesn't matter as much.
While JavaScript solutions can disable the submit button after it has been clicked, this will have no effect on those people who have JavaScript disabled. You should always make things work correctly without JavaScript before adding it in, otherwise there's no point as users will still be able to bypass the checks by just disabling JavaScript.
If the page where the form appears is dynamically generated, you can add a hidden field which contains some sort of sequence number, a hash, or anything unique. Then you have some server-side validation that will check if a request with that unique value has already come in. When the user submits the form, the unique value is checked against a list of "used" values. If it exists in the list, it's a dupe request and can be discarded. If it doesn't exist, then add it to the list and process as normal. As long as you make sure the value is unique, this guarantees the same form cannot be submitted twice.
Of course, if the page the form is on is not dynamically generated, then you'll need to do it the hard way on the server-side to check that the same information has not already been submitted.
Most of the answers so far have been client-side. On the server-side, you can generate a hidden field with a GUID when you first produce the form, and then record that GUID as a submitted form when the post is received. Check it before doing any more processing.
Whenever a page is requested from the server , generate a unique requestToken , save it in server side,mark status as NOT Processed and pass it along with the current requested page. Now whenever a page submit happens , get the requestToken from the "POST"ed data and check the status and save the data or take alternate action.
Most of the banking applications use this technique to prevent double "POST"ing.So this is a time proven & reliable way of preventing double submissions.
A user-side solution is to disable the submission button via Javascript after the first click.
It has drawbacks, but I see it often used on e-commerce websites.
But, it won't never replace a real server-side validation.
Client side techniques are useful, but you may want to couple it with some server side techniques.
One way to do this is to include a unique token in the form (e.g. a GUID or similar), so that when you come to process the form you can check to see whether the token has already been used, preventing a double submission.
In your case, if you have a table with event visitors, you might include this token as a column.
A client-only solution won't be enough, as stated in many of the answers here. You need to go with a server-side fail-safe.
An often overlooked reason that disabling the submit button doesn't work is, the user can simply refresh the submit target (and click OK on the "are you sure you want to resubmit the POST data?" dialog). Or even, some browsers may implicitly reload the submitted page when you try to save the page to disk (for example, you're trying to save a hard-copy of an order confirmation).
Almost no one has js disabled.
Think about coding your e-commerce website for the 70 year old woman who double clicks every link and button.
All you want to do is add a javascript to prevent her clicking "Order Now" twice.
Yes - check this at the server side too "be defensive" - but don't code for that case. But for the sake of a better UI do it on the client side too.
Here are some scripts that I found:
//
// prevent double-click on submit
//
jQuery('input[type=submit]').click(function(){
if(jQuery.data(this, 'clicked')){
return false;
}
else{
jQuery.data(this, 'clicked', true);
return true;
}
});
and
// Find ALL <form> tags on your page
$('form').submit(function(){
// On submit disable its submit button
$('input[type=submit]', this).attr('disabled', 'disabled');
});
None of the solutions address a load-balance server.
If you have some load balancer, send a UUID (or any type of unique number) to the server to store and read again will not work well if the server is not aware of other servers, because each request could be processed by a different server in a stateless environment. These servers need to read/write to the same place.
If you have multiple servers you will need to have some shared cache (like a Redis) among the servers to read/write the unique value in the same place (what could be an over-engineering solution, but works).
Client side alteration is a common technique:
Disable submit button
Change the screen to a "please wait" screen
If the form was modal, changing the screen back to their usual process (this has the benefit of making things look really slick)
But it's not perfect. It all relies on JS being available and if that's not the case, without back-end duplication detection, you'll get duplicates still.
So my advice is to develop some sort of detection behind the scenes and then improve your form to stop people with JS being able to double-submit.
You can track the number of times the form's been submitted and compare it to the number of unique visits to the page with the form on it in the session.
Beside the many good techniques already mentioned, another simple server-side method, that has the drawback of requiring a session, is to have a session variable that is switched off on the first submit.