6

Lets say there is an AJAX application where the user can submit items - buy them.

And there was a code

IF ($_POST[items] > 20) {
   echo 'error';
}
else {
   do_buy($_POST[items]);
   echo 'success'
}

Here, there is a check if items is not more than 20. On client side, it should not be possible to choose more than 20 items.

The system would work without problems even if 21 (or more) items were submitted (the user would simply pay for each item). While I realize you must want to yell don't trust the client, is there any harm in doing so if there are no consequences, as is the case here?

One could make the argument that overloading the cart might cause instability in the system but it seems as though the worst case would be that some script times out. If errors are disable, the user will just not get back any response.

In general: Does it make sense to code protections for an attack which violates an invariant of your system?

Update:

$_POST['items'] I meant that is array, not an integer. And each item how own properties - id and quantity, which are checked later before completing the buy operation.

About sql injection - I usually use frameworks, and they take care of injection protection.

Update

One more reason why I ask this is I want as much clean code as possible and also when someone reads it - will think why the hell this is needed, this programmer does not know what he is programming and why. So for all code I want to have clear reason why that piece of code exists and so if not in comment, then at least myself that I would have clear understanding why I make this check so I could explain if another programmer asks.

  • 1
    You should also consider that by adding arbitrary 'protections' into your code which you think is protecting it could actually be another means of exploiting it. Don't assume that just because you have a lock on something that someone out there doesn't already have multiple ways of unlocking it. – l'L'l Jul 13 '14 at 7:29
  • Can you explain how to protect from an SQL injection, in precise terms? If you can't then I'm afraid you might not be so well protected from mistakes... – Steve Dodier-Lazaro Jul 13 '14 at 15:37
  • No, I cannot do that in premice terms, unless I use some tutorial for help. But I know that if I use frameworks like laravel or codeigniter, and use their methods to run queries, like codeigniter query bindings, the queries are escaped and so cannot do something bad. – Darius.V Jul 15 '14 at 6:52
5

Yes, you should add protections, but they need to be appropriate for the situation.

All user input must be validated. The fundamental principle is that you do not define what "bad" input is, you define what "good" input is and reject everything else. To take your example, you've defined "items > 20" as bad. But what if "items" is -1? What if it's the quantity );DROP TABLE Orders;--?

The basic technique is that you look at each user input field and define what a "good" value looks like, taking into account both your software's capabilities and your business rules. For example, "items" might be "an integer, greater than 0, less than 20, and less than or equal to the amount in stock" -- this rejects too-large orders, too-small orders, and exotic inputs such as SQL injection, without needing to worry about what an attacker might be trying to do or how your software might react.

This must be done server-side. Client-side validation is there to help the honest user; a dishonest user can only be stopped server-side, since they control the client.

To use your house analogy, all user input is part of the door.

  • I mean items is array, (updated the question) so if user posts anything other than array, script will simply get error, so for that reason I could check if it is_array() before continuing, but thats is what I know and when I know how it is hackable, I add anyway protections. – Darius.V Jul 13 '14 at 10:09
1

You can't always know how things really can go bad. In your current example the attacker can send a very large value causing an arithmetic- or stack overflow or an unhandled exception causing the server to shut down and lead to an availibility problem.

So always do the checks, always consider the worst can happen and think of the attacker as someone who is capable of doing "anything". Always make white lists, not black lists. At list consider the standard attack methods (XSS, CSRF, Injection, etc) and check the ranges.

Seal the doors and windows as tight as you can and always review your design, your code AND your environment.

  • If we assume that system will crash, should we not make a test for this instead. So after test we really know and could add the comment near the code explaining why this is needed. And if test shows that this is not needed, we have more clean code - no unnecessary code. Also we could add comment why the check is not needed, so after some time reading - we will know that this case has been tested. – Darius.V Jul 13 '14 at 7:43
  • The problem is you can never test all the scenarios. You can never know all types of attacks. So at least apply the standard counter-attacks like range-checking. – Alireza Jul 13 '14 at 8:06
  • Better safe than sorry. If there is no need for the user to enter more than say 50 items, why let them? It's that simple – Alireza Jul 13 '14 at 8:08
  • Alireza - I was just thinking, that I want as much clean code as possible and also when someone reads it - will think why the hell this is needed, this programmers does not know what he is programming and why. So for all code I want to have clear reason why that piece of code exists. – Darius.V Jul 17 '14 at 8:50
  • You can always put comments to explain why some code is written and if anyone can't understand the importance of security in a web application, that's their problem not yours. You should always focus on making your application secure and reliable, and never think of bypassing security standards for the sake some people ignorant of the these issues. – Alireza Jul 17 '14 at 9:02
1

Short answer: no, and take a crash course on security urgently if you're making a sales website!

You should not add arbitrary restrictions and checks and "protections" just because you don't know what's going on. If you do that you're more likely to add problems and leave security vulnerabilities open than anything. Obviously, the reason why there are security professionals is because they're trained to identify the needed protections.

Start by defining the assets in your system, both yours and your clients'. You need to know what's valuable because this is what hackers will come for. It includes personal data, data of a financial value (bank account information, etc.), the goods you sell, your clients' computers (which can be used in a botnet in case of e.g. cross-site scripting attacks) and also your own server, database, and Web server.

Once you know what's there to protect, you need to define what needs to happen to it for your system to function properly. Essentially you need to list what you allow your clients to do on your website. For instance this arbitrary 20 items limit is completely unjustified.

The second step will be to understand who your adversaries could be and what they can do. Be creative but stay realistic. You're less likely to interest the NSA than a lone financially-interested hacker for a sales website. This process is called threat modelling. You must:

  • define your adversaries for each asset
  • define their capabilities (which requires a lot of security knowledge)
  • define the threats to your assets (what can those capabilities allow an attacker to do to you)

Now that you know what could happen to you, you need to define the Security Properties that must hold on your assets, and you must then choose the mechanisms that guarantee those properties. Those mechanisms, in turn, become critical assets of your system that must equally be protected. This is referred to as a Trusted Computing Base.

When you're there you can start about thinking moving to beta. You'll have to evaluate your security, through penetration testing usually done by a third-party company. But that should already keep you busy ;)

Edit: please do spend some time reading up the most common software programs that turn into vulnerabilities. Allowing users to purchase more than 20 items isn't one of them.

  • Your answer is interesting, and it differs from other answers. Since I am the one who asks, I cannot know now which one is the correct answer, because I dont know how to check correctness, like in lets say other questions where you get code, paste it, if it works, its correct :) So I now will not do anything I guess, maybe site admins could do that. Btw additional question - can you show an exmaple how can I introduce vulnerability by trying to protect? – Darius.V Jul 14 '14 at 13:33
  • in yur link it also writes: "When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules." cwe.mitre.org/top25/index.html#CWE-89 - according to this I should check if it is more than 20 if is not possible to buy 21 item on client side, kind of range check. Another quete: "For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side" – Darius.V Jul 14 '14 at 13:41
  • Just complexifying your app with additional code creates extra opportunities for bugs. Bugs can then be exploited in various ways. We all make mistakes and write bugs, unavoidably, so shorter/simpler software is often better. If you don't know what your code should do and should not do how can you evaluate its quality and keep it as simple as it should be? – Steve Dodier-Lazaro Jul 14 '14 at 14:21
  • Another classical example is the false sense of security that arises from applying unneeded protections. You'll lull yourself into thinking your site is secure because you did do something about security, but if that thing was uninformed and did not match your actual threats, it'll provide no security at all. Typically forcing users to have complex credentials when you log them in without encryption or when you store their passwords poorly. Also, doing checks on item count when attackers would actually steal someone else's credentials or session and pay with their stored credit card. – Steve Dodier-Lazaro Jul 14 '14 at 14:23
  • Wrt. insecure interaction, all the checks must be done on the server side -- that is the side that you trust. Insecure interaction occurs because you cannot trust a remote end, so you must keep the integrity of the purchase on the server side. – Steve Dodier-Lazaro Jul 14 '14 at 14:24
1

If some malware on the user side makes the client buy 2 millions of items on your site, and your site performs the transaction without raising any alert, then some people, in particular the defrauded customer, may complain quite loudly and assert that your server is a bit lax. It could be argued (in court !) that you would be at fault for not making some "sensible" checks. There may even be some applicable regulations that mandate doing some server-side verifications (at least banks make checks for "abnormal activity" on credit cards and block transactions which look particularly weird).

In the general case, adding extra checks for abnormal situations is sane programming practice. You know that the client side should not allow for more than 20 items. If some bug on the client side interface allows a client to put 21 items, then it should be fixed, and it will be easier if you are warned about it as soon as possible, e.g. with a server-side check.

(There is a dark side to it, though: if you add the check on the server side, then later on decide to raise the limit to 25, you have to modify the client and the server. This should, however, be easily detected during pre-deployment tests, so don't refrain from adding sanity tests.)

  • 1
    Do you have examples of such court arguments? Off the top of my head I can't find which legislation would require a service provider to ensure that third-parties behave expectedly, that seems actually very implausible! However surely service providers must in most systems allow users to make rectifications, and trades laws also apply and sometimes allow for a purchase to be cancelled. – Steve Dodier-Lazaro Jul 13 '14 at 15:42
  • If I were presented with such a scenario (based on French law) I would first look into proving that the purchase has been contracted without the informed consent of the user (purchases are informal contracts after all), and so it is void and must be cancelled. I'm not sure how the service provider could be held accountable for that though, including arguing that the client did buy 2 million items until a court says "well, nope". – Steve Dodier-Lazaro Jul 13 '14 at 15:44
  • 1
    there is no problem about adjusting limits on both sides - client and server - just use some config value in database - so the server reads it, also when drawing client view, that config value is passed from same place in database, so they are equal – Darius.V Jul 14 '14 at 12:05
1

Only addressing the first question, which is essentially "Is it okay to code client-side validation?".

Yes its a good user experience, immediate feedback is nice. Client-side validation isn't actually security however, its more of a convenience. Its purpose is to speed up the process, to put the form in a state that will pass validation.

As you probably know, client-side validation should always be secondary to server-side validation. If the client-side and server-side validation mismatch, the server is ultimately the source of truth. If the server doesn't validate it, then it isn't really being validated.

Anyways, yes, client-side validation is perfectly legit and is a big improvement in UX.

And for sql injection protections, it sounds like you're already treating user input as hazardous materials there and scrubbing it with a tried and trusted framework, so you're good to go there. Just be wary of anything derived of user input, not just when saving/updating. Even other variables/logic can be manipulated by user input if they have intimate knowledge of your system.

  • 2
    I have no idea why not to use some framework, if there is such people still. Unless its super old project where you need some minimal upgrades and you dont want to move it to the framework. But making fresh project, even if its small one, I use framework, cause - why do if something has been done for you and done professionally when talking about security. – Darius.V Jul 17 '14 at 8:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.