Quality code: data verification required
The discussion that arose in the comments on the post about -555 basins indicates that it is not obvious to everyone how to react to incorrect data received from the user.
Meanwhile, an example with a negative quantity of goods, as well as various XSS, SQL-injections are all special cases that require an approach known as “Secure programming”.
This topic is often and extensively discussed in specialized literature, for example, see “Perfect Code” by S. McConnell (Code Complete), Chapter 8 “Protective Programming”.
I will give a small quote from this book (if someone has not read it, I recommend it):
The verification mechanism can be different and depends on the type of data / language / libraries / framework, etc. These can be assertions, enum data types, properties, and so on. The main thing is that in the application architecture, validations are an indispensable element, logically separate from the data processing process.
Regarding the reaction to incorrect data received through the user interface, then, in my opinion - you need to be honest with the user. Trying to predict what the user wanted to get by indicating a non-existent zip code, a negative quantity of goods or incorrect text instead of his own e-mail would be self-deception. We will never know what the visitor really thought about when filling out the form. So, we can’t find out what meaning was really meant.
He was probably sealed up, maybe some kind of kulhacker checked how everything works here, and maybe it's just a mistake in the interface.
In any case, if an error occurs during data entry, it is logical to suspend the program and inform the user that the data entered is incorrect. (Naturally, we are talking about messages that are understandable to the user, for example, “there is no settlement with such an index” instead of “http / 500, UE throw ... incorrect zip ... at class N”).
It is believed that this will reduce the "friendliness" of the interface. This is not true. On the contrary, the software will become more understandable, predictable and safe - both for the user and for the developer. This is easy to verify in practice: it is enough to write such errors in the log, and subsequently analyze its contents.
The desire to ensure that the program continues to be executed at all costs, resetting incorrect values to defaults is dangerous, and most likely indicates that the developer does not quite understand what this price may turn out to be.
Meanwhile, an example with a negative quantity of goods, as well as various XSS, SQL-injections are all special cases that require an approach known as “Secure programming”.
This topic is often and extensively discussed in specialized literature, for example, see “Perfect Code” by S. McConnell (Code Complete), Chapter 8 “Protective Programming”.
I will give a small quote from this book (if someone has not read it, I recommend it):
Protective programming does not mean protecting your code with the words: “It works that way!” His idea coincides with the idea of careful driving, in which you are ready for any tricks of other drivers: you will not suffer, even if they commit something dangerous. You take responsibility for your own protection in cases where another driver is to blame.
In defensive programming, the main idea is that if incorrect data is transmitted to the method, then its operation will not be interrupted, even if this data is corrupted due to the fault of another program. Summarizing, we can say that there will always be problems in programs, programs will always be modified, and a reasonable programmer will always take this into account when developing code.
This chapter tells you how to protect yourself from the ruthless world of incorrect data, events that can never happen, and other programming errors. If you are an experienced programmer, you can skip the next section on processing input data and go to section 8.2, which will talk about the statements.8.1. Protecting the program from incorrect input data.
You may have heard the expression at school: “Garbage in, garbage out” (“Garbage in, garbage out”). This is a warning to the consumer from software developers: let the user beware.
For industrial software, the principle of “garbage in - garbage in” is not very suitable. A good program will never give out garbage no matter what it had in its input. Instead, it uses the principles: “garbage in the input - nothing in the output”, “garbage in the input - error message on the output” or “garbage in the input is not allowed”. By today's standards, “garbage in - garbage in” is a sign of careless, insecure code.
There are three main ways to process input junk data, listed below.
Check all data from external sources
After receiving data from a file, from a user, from a network, or from any other external interface, make sure that all values fall within the acceptable interval. Verify that the numeric data has valid values and that the strings are short enough to be processed. If the line should contain a certain set of values (say, a financial transaction identifier or something similar), check that this value is valid in this case, if not, reject it. If you are working on an application that requires security, be especially careful with data that can attack your system: buffer overflow attempts, embedded SQL commands, embedded HTML or XML code, integer overflows, data transferred to system calls, etc. P.
Check the value of all input parameters of the method
Checking the values of the input parameters of the method is almost the same as checking data from an external source, except that all data comes from another method, and not from the external interface. In section 8.5, you will learn how to determine which methods should check their input.
Decide how to handle the wrong input.
What if you find the wrong parameter? Depending on the situation, you can choose one of a dozen approaches described in detail in Section 8.3.
Protective programming is a useful addition to other ways to improve the quality of programs described in this book. The best way to securely encode is not to make mistakes initially. Iterative design, writing pseudo-code and tests before coding, and low-level verification of compliance with the project is all that helps to avoid adding defects. ...
The verification mechanism can be different and depends on the type of data / language / libraries / framework, etc. These can be assertions, enum data types, properties, and so on. The main thing is that in the application architecture, validations are an indispensable element, logically separate from the data processing process.
Regarding the reaction to incorrect data received through the user interface, then, in my opinion - you need to be honest with the user. Trying to predict what the user wanted to get by indicating a non-existent zip code, a negative quantity of goods or incorrect text instead of his own e-mail would be self-deception. We will never know what the visitor really thought about when filling out the form. So, we can’t find out what meaning was really meant.
He was probably sealed up, maybe some kind of kulhacker checked how everything works here, and maybe it's just a mistake in the interface.
In any case, if an error occurs during data entry, it is logical to suspend the program and inform the user that the data entered is incorrect. (Naturally, we are talking about messages that are understandable to the user, for example, “there is no settlement with such an index” instead of “http / 500, UE throw ... incorrect zip ... at class N”).
It is believed that this will reduce the "friendliness" of the interface. This is not true. On the contrary, the software will become more understandable, predictable and safe - both for the user and for the developer. This is easy to verify in practice: it is enough to write such errors in the log, and subsequently analyze its contents.
The desire to ensure that the program continues to be executed at all costs, resetting incorrect values to defaults is dangerous, and most likely indicates that the developer does not quite understand what this price may turn out to be.