Specific Rules for Specific Programming Languages

This section gives some rules for specific programming languages.

Rules for Perl

  1. Use Perl’s tainting features for all CGI programs. These features are invoked by placing the “-T” option at the beginning of your Perl script.

    Perl’s tainting features make it more suited than C to CGI programming. When enabled, tainting marks all variables that are supplied by users as “tainted.” Variables whose values are dependent on tainted variables are themselves tainted as well. Tainted values cannot be used to open files or for system calls. Untainted information can only be extracted from a tainted variable by the use of Perl’s string match operations.

    The tainting feature also requires that you set the PATH environment variable to a known “safe value” before allowing your program to invoke the system( ) call.

  2. Remember that Perl ignores tainting for filenames that are opened read-only. Nevertheless, be sure that you untaint all filenames, and not simply filenames that are used for writing.

  3. Consider using Perl’s emulation mode for handling SUID scripts safely if you are running an older version of UNIX.

  4. Always set your program’s PATH environment variable, even if you are not running SUID or under UNIX.

  5. Be sure that the Perl interpreter and all of its libraries are installed so that they cannot be modified by anyone other than the administrator. Otherwise, a person who can modify your Perl libraries can affect the behavior of any Perl program that calls them.

Rules for C

It is substantially harder to write secure programs in C than it is in the Perl programming language; Perl has automatic memory management whereas C does not. Furthermore, because of the lack of facilities for dealing with large programs, Perl program sources tend to be smaller and more modular than their C counterparts.

There remains, nevertheless, one very important reason to write CGI programs in C: speed. Each time a CGI program is run, the program must be loaded into memory and executed. If your CGI program is written in Perl, the entire Perl interpreter must be loaded and the Perl program must be compiled before the CGI program can run. Often, the overhead from these two operations dwarfs the time required by the CGI program itself.

The overhead of loading Perl can be eliminated by using the Apache Perl module. Future versions of Microsoft’s Internet Information Server are likely to support Perl natively as well. Nevertheless, if you insist on using C, here are some suggestions:

  1. Use routines that check buffer boundaries when manipulating strings of arbitrary length.

    In the C programming language particularly, note the following:

    Avoid

    Use Instead

    gets ( )

    fget ( )

    strcpy ( )

    strncpy ( )

    strcat ( )

    strncat ( )

    Use the following library calls with great care—they can overflow either a destination buffer or an internal, static buffer on some systems: sprintf( ), fscanf( ), scanf( ), sscanf( ), vsprintf( ), realpath( ), getopt( ), getpass( ), streadd( ), strecpy( ), and strtrns( ). Check to make sure that you have the version of the syslog( ) library that checks the length of its arguments.

    There may be other routines in libraries on your system of which you should be somewhat cautious. Note carefully if a copy or transformation is performed into a string argument without benefit of a length parameter to delimit it. Also note if the documentation for a function says that the routine returns a pointer to a result in static storage. If an attacker can provide the necessary input to overflow these buffers, you may have a major problem.

  2. Make good use of available tools.

    If you have an ANSI C compiler available, use it, and use prototypes for calls.

  3. Instruct your compiler to generate as many warnings as possible. If you are using the GNU C compiler, you can do this easily by specifying the -Wall option. If your compiler cannot generate warnings, use the lint program to check for common mistakes.

  4. If you are expecting to create a new file with the open call, then use the O_EXCL | O_CREAT flags to cause the routine to fail if the file exists.

    If you expect the file to exist, be sure to omit the O_CREAT flag so that the routine will fail if the file is not there.[89]

  5. If you need to create a temporary file, use the tmpfile( ) or mkstemp( ) function.

    This step will create a temporary file, open the file, delete the file, and return a file handle. The open file can be passed to a subprocess created with fork( ) and exec( ), but the contents of the file cannot be read by any other program on the system. The space associated with the file will automatically be returned to the operating system when your program exits. If possible, create the temporary file in a closed directory, such as /tmp/root/.

Warning

The mktemp ( ) library call is not safe to use in a program that is running with extra privilege. The code as provided on most versions of UNIX has a race condition between a file test and a file open. This condition is a well-known problem and is relatively easy to exploit. Avoid the standard mktemp ( ) call. On Solaris, for instance, use tmpfile ( ) instead.

Rules for the UNIX Shell

Don’t write CGI scripts with the UNIX shells (sh, csh, ksh, bash, or tcsh) for anything but the most trivial script. It’s too easy to make a mistake, and there are many lurking security problems with these languages.



[89] Note that on some systems, if the pathname in the open call refers to a symbolic link that names a file that does not exist, the call may not behave as you expect. This scenario should be tested on your system so you know what to expect.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.62.103