Loops - Computer and Information Sciences at Towson University

advertisement
Input Validation – “All input is evil”
(loops)
CS1
Background
Summary: Any program input– such as a user typing at a keyboard or a network connection
– can potentially be the source of security vulnerabilities. All input should be treated as
potentially dangerous.
Description: Most software packages rely upon external input. Although information typed at
a computer might be the most familiar, networks and external devices can also send data to a
program. Generally, this data is of a specific type: for example, a user interface that requests
a person’s name might be written to expect a series of alphabetic characters. If the correct
type and form of data is provided, the program might work fine. However, if programs are not
carefully written, attackers can construct inputs that can cause malicious code to be executed.
Risk – How can it happen? Any data that can enter your program from an external source
can be a potential source of problems. If external data is not checked to verify that it has the
right type of information, the right amount of information, and the right structure of information,
it can cause problems. Any program that processes data from external sources without
adequate validation can be susceptible to security vulnerabilities.
Example of Occurrence: A Norwegian woman mistyped her account number on an internet
banking system. Instead of typing her 11-digit account number, she accidentally typed an
extra digit, for a total of 12 numbers. The system discarded the extra digit, and transferred
$100,000 to the (incorrect) account given by the 11 remaining numbers. A simple dialog box
informing her that she had typed too many digits would have gone a long way towards
avoiding this expensive error.
Olsen, Kai. “The $100,000 Keying error” IEEE Computer, August 2008
How can I avoid input validation problems? The while loop is useful for input validation.
The following sample loop shows input validation for a test score:
cin >> testScore;
while ((testScore < 0) || (testScore > 100))
{
cout << "Enter valid test score between 0 and 100" << endl;
cin >> testScore;
}
Example in Code: This program asks the user to type in an even number. It then prints all of
the even numbers that are greater than or equal to zero and less than the number typed:
int main(void)
{
int x;
cout << "Please type an even number: ";
cin >> x;
for (int i = 0; i != x; i += 2) {
cout << i << endl;
}
return 0;
}
This code has two input validation problems. The first involves the use of the cin to get an
integer as typed by the user. If the user types an integer, this will work without any problems.
However, if a floating point value (such as “3.2”) or a string (such as “Hello”) are typed, your
program may not run correctly. Floating-point values might be truncated (3.2 becomes 3), but
responses to strings may be unpredictable. A robust program would catch this error, provide
a clear and appropriate error message, and ask the person to re-enter their input.
The second problem involves the lack of validation of the requirement that the integer be
even. If the user types an even number, this program will run perfectly well. However, if an
odd number is provided, there will be trouble: as the counter i starts from zero and increases
by two with each iteration, it will never be equal to an odd number, and the loop will not
terminate.
As a careful developer, you should use a two-part strategy to avoid this second problem. In
the first part, you should verify that the number provided by the user is indeed even. If it is not,
your program should return an error message and repeat the request, not proceeding until an
even number is provided.
The second approach involves revising the loop. The loop above will continue as long as the
loop counter i is not equal to the x, the value provided. A more robust solution would be to
continue the loop as long as i is less than x. Thus, even if there was a problem with your
input validation, the loop would still stop.
Recover Appropriately: A robust program will respond to invalid input in a manner that is
appropriate, correct, and secure. When your program runs across invalid input, it should
recover as much as possible, and then repeat the request, or otherwise continue on. Arbitrary
decisions such as truncating or otherwise reformatting data to “make it fit” should be avoided.
Laboratory/Homework Assignment:
1.
2.
3.
4.
5.
Modify each problem from the previous lab to work as a loop.
Write an input validation loop that asks the user to enter a body temperature.
Write an input validation loop that asks the user to enter a body weight.
Write an input validation loop that asks the user to enter a height, in feet and inches.
Write a calculator program that displays a menu of operations and allows the user to
display simple calculations
6. Complete the following checklist for each program. Add any additional input validation
to your program.
Security Checklist:
Security Checklist
Vulnerability
Improper Input Validation
Task – Check each line of code
Course
CS1
Completed
1. Mark with a V each variable that is input.
For each input variable, which of the following is applicable: Yes N/A
1. Check length
2. Check range (reasonableness?)
3. Check all options
4. Check type
Shaded areas indicate vulnerabilities
Discussion Questions:
1. Refer back to the lab on integer errors. Can improper input validation lead to integer
errors?
2. Checking for division by zero is pretty straightforward. Checking for a possible integer
overflow as a result of an operation can be difficult. Why?
3. Overflow can also when the dividend is equal to the minimum (negative) value for the
signed integer type and the divisor is equal to — 1. Demonstrate this with your
calculator problem.
4. Filenames are particularly vulnerable to security vulnerabilities. Research to find out
why.
5. Why is a while loop usually a more effective way to perform input validation than an
if..else?
Download