Software Design Using C++Professional Programming: Issues and ToolsIntroductionAre we writing professional programs yet? Unfortunately, the answer is probably no, even if you have worked through all of the Software Design in C++ web pages! This is partly because there is so much to learn. Most people learn how to write good quality, professional programs through years of experience. The help of a mentor and working with others on teams all help to expand one's ability to write good software. Courses in software engineering, systems analysis and design, user interface design, etc. are also quite useful. Another reason that we are not yet writing professional programs is that these web pages usually took the easiest approach since the main goal was to teach programming to beginners. Even when these web pages got into more difficult material, an attempt was made to present it in as clear a manner as possible. The easiest method of doing something is often the best, but that is not always the case. In the following material we will look at some issues that have been largely overlooked in these web pages so far (such as security concerns) and will mention some of the tools used by professional programmers to make their jobs easier. Security IssuesSecurity is probably not an issue with a small program that you write for your own use and which is not even accessible by others. Consider, in contrast, software that is run on a company server each time that someone on the Internet clicks on a particular link on a company web page. If that software has a security flaw, it may then be possible for malicious users to do things on this server that they should not be able to do. For example, they might be able to read data that is confidential (such as credit card numbers), they might be able to change data on the server, they might be able to crash the server, and they might even be able to gain administrative (root) access to the server, thus giving themselves complete access to everything on this server! There are many types of common security flaws in software. We primarily discuss one well-known type, buffer overflow, below. Example Security IssuesBefore looking at the main example, buffer overflow, let's have a brief look at several other security concerns. One is how to protect confidential data such as passwords and credit card numbers. This is commonly done with some form of encryption. A related issue is how to authenticate users, that is, how to verify that they really are who they say they are. This, too, uses encryption. The study of encryption is beyond what can be done in these web pages. The references below provide some further information. Detailed books and courses entirely on encryption are now becoming available as well. The short answer for the programmer who needs to use encryption is generally to use some encryption technology that is already well-tested. (This might involve licensing the technology. Note that Microsoft has provided a cryptography API into many of its products. To use it, you start by including the wincrypt.h header. See Microsoft's documentation for further details.) Encryption is difficult to do well. Too many folks have tried to throw together their own encryption scheme only to have huge flaws discovered in it after it was put into use. As of this writing, for example, there is a fair amount of concern about the security holes in a particular form of wireless networking. Obviously the creators of this software did not intend it to have such flaws. Security and encryption are simply hard to do well.
Another source of bugs and potential security flaws is failing to check if a system call or a call
to some similar function generates an error. Many system calls return a value that indicates
that an error happened. In object-oriented C++ an exception might be thrown instead.
Other ways of indicating an error condition are also sometimes used. The programmer should
check to see if function calls fail in some way and design the program to handle this. Sure, most
system calls work fine nearly all of the time, but it could be that rare failure that leads to
a difficult to find bug or security flaw. As an example, consider the use of
new
to dynamically create an array, an object, or whatever. Always check to see if the There are many other security issues that a programmer should consider when creating professional software. These include the filtering of bad input (hackers love to supply bad input to your programs to try to get a result that you did not intend), setting permissions on files so that the least amount of access necessary is given, etc. Filtering all but acceptable characters is especially important in a web application that receives data from the user. This filtering must be done on the server end, as the potential attacker has complete control over what happens at the client end. (Thus using JavaScript to filter the data at the user's browser is not the way to handle this.) Only accept the characters that you wish to allow and limit the length of the data to what your program can reasonably handle. Another issue that often occurs is where to place a temporary data file. Don't place it in a "world-writable" location as an attacker may be able to replace the temporary file with something else and thus get your application to do something that you never intended. See the references below for further information. As Jay Heiser said in the March 2002 issue of Information Security: "The only way to avoid costly mistakes is first to assume that there may be important things you need to learn, and then have your work repeatedly tested by security experts. One thing mature programmers know is that they don't know everything." Next, let's look at our main example. Buffer OverflowThis typically involves the misuse of the run-time stack. Suppose that the software in question is the software mentioned above that is run each time an Internet user clicks a particular link on the company web page. This web page contains a form where the user supplies some data. When the user clicks the submit button this data is processed by your software on the server. The malicious hacker, of course, submits some rather unorthodox data. Suppose further that a function in your software has a local variable, a character array named buffer , that is used to hold a copy of some or all of the data that the user submits.
The hacker's data is deliberately longer than will fit in your buffer variable so that
it overflows and overwrites the rest of the stack frame for your function. In particular, it overwrites
the return address used when the function ends. The hacker tries to arrange it so that the new
return address sends the computer to a location in the stack that was just overwritten, a location
that contains code that the hacker desires to run on your server. The hacker's code might create a
backdoor that allows that person easy access to your server! Your server has just been taken over.
It might sound difficult to arrange things so that the fake return address points
to the desired piece of hacker code, but a bunch of NO-OPs in front of the code make the attack
more likely to work. (A NO-OP is an instruction that does nothing. Control simply proceeds to
the next line of code.) As long as the fake return address points to one of the NO-OPs or the
first line of hacker code, the system will end up executing the hacker code that installs
the backdoor. Here is a picture of the run-time stack, both before and after the hacker's data has
overflowed the local variable
What aspect of coding makes buffer overflow possible? The usual culprit is
The above method will truncate the data if it does not all fit into
Thus the basic solution (assuming dynamic allocation of buffers is not used)
is to avoid the use of Perhaps the best solution to the problem of how to copy strings without allowing buffer overflows is to use an object of the STL string class, using assignment with the = operator (or a copy constructor) to copy the string objects. This is said to have no potential for buffer overflow problems. However, you still may be able to increment an iterator so that it is off the end of the string. If you use some other string class, be sure to check that the function or operator used to copy such strings does not allow buffer overflow to occur. For the character array type of string, if you need to use that scheme, you can write your own string copy function. The following is an example of this approach.
If you write your own string copy function, be very sure that it works correctly in all possible
cases. Note that the above
There is a lot more information available about buffer overflow problems. See the first two
books in the references below for more on this topic.
Note that running off the end of any array is problematic, even in cases that don't
open your software up to a buffer overflow attack. If you write data beyond either
end of the array you may overwrite something important. This can lead to software
that sometimes crashes or produces incorrect results. Because of this problem, the STL's
vector class is often used instead of arrays.
If you use the If you program for the Windows platform, you should consider using Microsoft's strsafe.lib and strsafe.h. These provide a library of safe string-handling functions. This library is provided as part of Visual C++ .NET 2003 and can also be obtained by downloading the Windows Core SDK from the SDK update site. For more information on these functions, go to MSDN and click on Library, User Interface Design and Development, Windows Management, Windows User Interface, Resources, Strings, String Overviews, Using the Strsafe.h Functions. Also refer to the article by Richard Grimes mentioned below in the references section. Privacy IssuesThere are many places where privacy issues can be of concern in software development. The ACM's Professional Standards (currently consisting of the General ACM Code of Ethics and Professional Conduct as well as the Software Engineering Code of Ethics and Professional Practice) provide helpful guidelines on this. These documents talk of the responsibility of computing professionals to protect the privacy and integrity of data about people. This data should be accurate, should be subject to correction by the individuals affected, and should be retained only for a reasonable period of time. Data should not be used for purposes beyond those for which it was collected, unless the permission of the affected individuals is obtained. Read these ACM documents for further details about privacy issues and other ethical concerns. Memory LeaksEven professionals sometimes have problems with memory leaks. A memory leak occurs when a program dynamically allocates memory space for an object, array, or variable of some other type, but fails to free up the space before the program completes. Some commercial software has suffered from this problem. The result for users is that they have less free memory after running the software than before (at least until they reboot their computer). The main way to prevent this problem is to discipline oneself to check that every time space is allocated it is always deallocated appropriately. Typically this involves the use of the delete operation.
ThreadsMany modern programs are written using threads. A thread is a portion of a program that can be scheduled separately to run on the CPU. Suppose that a program needs to carry out two main tasks at a certain point. Each task could be carried out by a different thread. If one thread gets held up (perhaps waiting for some data to be read in from disk), the other thread might still be able to go forward. In a server environment, software that serves multiple users might use a different thread to handle each user. Threaded programming is known to be rather difficult. Consult a good reference book or search the Internet for online materials. Currently, the ThreadMentor home page and Iona Technologies' JThreads/C++ are sources of information and software for this topic. You can also search the MSDN library for information on threads. ToolsThe following is by no means a complete list of tools used by professional programmers. Rather, this partial list is intended to give some indication of the types of tools that are used. Good tools can be used to improve both the quantity and quality of work, whether that work is done by an individual or by a team. No particular endorsement of tools mentioned by name is implied.
References
Related Items
|