Slashdot Mirror


Secure Programmer: Keep an Eye on Inputs

An anonymous reader writes "This article discusses various ways data gets into your program, emphasizing how to deal appropriately with them; you might not even know about them all! It first discusses how to design your program to limit the ways data can get into your program, and how your design influences what is an input. It then discusses various input channels and what to do about them, including environment variables, files, file descriptors, the command line, the graphical user interface (GUI), network data, and miscellaneous inputs."

18 of 157 comments (clear)

  1. And code reviews, code reviews, code reviews by Brahmastra · · Score: 5, Insightful

    I believe code reviews with a large enough group of people to be extremely useful. Yeah, it takes time and you get some irritating comments from a few people about how there is a space between something or comma between something, but when multiple eyes look at it, someone always catches something you didn't. A few hours of extra pain on the side of programmers can prevent pain for millions in the form of blaster viruses, etc.

  2. The more things change.... by billstewart · · Score: 5, Insightful
    One of the first lessons we learned in CS100 was to always validate the input, assuming that it might be bogus or actively malicious. I've been appalled over the last 25 years at the number of products, developers, and companies that don't understand that. Most of the internet security problems we've seen have been from inadequate handling of input data, typically the buffer overruns that are so easy to program in C if you're not paying attention.

    The article's worth reading, and really does justify it's "Level: Intermediate" label. Unlike when I was learning to program, there are lots of sources of input beyond your deck of punch cards (:-), and the author does a good job of explaining many of them, such as evil things that environment variables and file descriptors can be used for.

    --

    Bill Stewart
    New Fast-Compression-only CPR http://preview.tinyurl.com/dy575ks
    1. Re:The more things change.... by agslashdot · · Score: 3, Insightful

      While I agree with you from a theoretical standpoint, I'm sure you are aware why things like this get overlooked in day-to-day corporate IT programming tasks.
      eg. Manager says, write a UI that accepts username & account, and then spits out user transactions . During design phase, you invariably make the code hack-able so its easy to test. ie. I could put in "*" for account and it would spit out transactions of ALL users, regardless of the username. This is a useful backdoor, especially in development time when your UI has to interact with somebody else's data repository in some compplicated fashion.
      Ofcourse, its a given that the input validation logic must be modified and backdoor must be taken out when the UI is actually deployed. But corporate practices being what they are, someone else takes ownership of the code at that stage, and either doesn't understand the "star-feature" ( *) , or thinks its cool to have this in case of emergency debugging, so leaves it there. Soon, this stupid program that should have been running standalone on someone's box, gets a facelift and is shoved on the internet. Some cracker comes along and puts in a star for account & gets all the transactions, & pretty soon, register.co.uk gets wind of this and reports it on front page. by then, original programmer has moved on to some other task, requiring a new back-door :)

  3. perl -T says it all by DrJimbo · · Score: 3, Interesting

    The Perl language has built-in "taint-checking" enabled via the -T command line switch which causes Perl to automatically keep track of all information that possibly came from a user input and not allow any of it to do anything harmful (basically end up on a command line or in a file name).

    --
    We don't see the world as it is, we see it as we are.
    -- Anais Nin
    1. Re:perl -T says it all by Carnildo · · Score: 5, Informative

      The Perl language has built-in "taint-checking" enabled via the -T command line switch which causes Perl to automatically keep track of all information that possibly came from a user input and not allow any of it to do anything harmful (basically end up on a command line or in a file name).

      There are other harmful things that data can wind up doing that Perl can't check for. Things like being used as SQL queries, or the classic "pass the price as a CGI parameter" mistake. Taint checking is more useful as a reminder that you need to validate input than a way of keeping potentially bad input isolated.

      --
      "They redundantly repeated themselves over and over again incessantly without end ad infinitum" -- ibid.
  4. Re:Windows & Belkin by AuMatar · · Score: 4, Insightful

    There are no controls on Windows inputs. Any process can send any message to any other process. Talk about insecure.

    You could probably majorly screw up a progoram by sending it random message numbers. It'd react as if you were sending random menu and other commands. Hmm, that sounds like a fun prank to play...

    --
    I still have more fans than freaks. WTF is wrong with you people?
  5. Murphy's Law strikes again. by Dr.+Bent · · Score: 5, Insightful

    It is a widely accepted engineering maxim that systems should be designed so that it is difficult to use them improperly. This is why (for example) a 110 volt plug will not fit in a 220 volt outlet. Developers who are concerned about the quality of the software they make would do well to follow this rule, and not just for security reasons. You should verify input data as early and as rigorously as possible wherever you can. Take advantage of things like XML validation and text box constraints to make it hard for users to enter bad data. And always follow the Fail-Fast principle...if something goes wrong: Complain! Loudly!. Don't let the user continue working if something has gone wrong. It's better to crash than to produce an erronous result.

    Just a little advice from a developer who's made enough mistakes to know better.

    1. Re:Murphy's Law strikes again. by Rich0 · · Score: 3, Insightful

      Keep in mind that the 110 and 220 plugs are designed to defeat accidental mixups. Computer input validation is generally designed to do the same. Hardening software against an attack is more analagous to giving your engineer the task of designing a plug and outlet such that it is physically impossible to plug anything but that one particular plug into the outlet, with the understanding that somebody with a good knowledge of engineering will try to defeat the design.

      Software is required to do a lot more than any physical security measure in existance. Your webserver could come under attack by any electronic measures that you could conceive of by a host of trained software engineers in another country. Chances are that the most a bank vault is designed to handle is a dozen guys with small arms, rudimentary safe-cracking gear, and some small explosives. If the US Army showed up with an M1 tank and 1000 tons of C4, the safe wouldn't last long. However, such a large-scale intrusion is unlikely to escape the watch of the police for long. On the other hand, a remote attack against a webserver can run for months without much being done to the attackers if they're in a rogue nation.

  6. Perl's taint checking by Eryq · · Score: 5, Informative

    Perl programmers interested in writing secure scripts should *definitely* know about the -T (taint checking flag).

    From the FAQ:

    As we've seen, one of the most frequent security problems in CGI scripts is inadvertently passing unchecked user variables to the shell. Perl provides a "taint" checking mechanism that prevents you from doing this. Any variable that is set using data from outside the program (including data from the environment, from standard input, and from the command line) is considered tainted and cannot be used to affect anything else outside your program. The taint can spread. If you use a tainted variable to set the value of another variable, the second variable also becomes tainted. Tainted variables cannot be used in eval(), system(), exec() or piped open() calls. If you try to do so, Perl exits with a warning message. Perl will also exit if you attempt to call an external program without explicitly setting the PATH environment variable.

    --
    I'm a bloodsucking fiend! Look at my outfit!
  7. Dividing by chrootstrap · · Score: 3, Interesting

    The recommendations on dividing the program into unsecure and secure binaries to handle setuid access in GUI's can very properly be extrapolated to non-graphical programs. This is a very good strategy for allowing relatively wild programs access to important facilities and can involve many types of IPC including memory-mapped files (with proper protection) and sockets. To really secure a client program that needs access to criticals, put it in a chroot jail and have it communicate with an outside process through (e.g.) a socket. Separating programs into safe and unsafe sections and applying different security techinques to each is far more effective, imo, than trying to secure a single, large application. It can also provide many other benefits of encapsulation, etc. The security onus shifts to handling client requests in the secure section which is usually much more easy to do.

    --
    Hacking articles at http://www.geocities.com/chroo
  8. Re:If you input ever displays as HTML by borkus · · Score: 5, Insightful

    A big issue for many web programmers is failure to realize that forms and web interfaces that you provide the user aren't the only way to interact with your application. A lot of them pay attention to JavaScript validation and maxlength attributes rather than check the data on the server.

    New developers working on applications open to the internet often aren't used to developing in an evironment where programmers that don't work for their employer can access their app. All it takes for one dishonet person who knows slightly more than you to hack your app.

  9. Re:If you input ever displays as HTML by mcrbids · · Score: 4, Informative

    forms and web interfaces that you provide the user aren't the only way to interact with your application.

    So true, so true. For example (in PHP)

    <?
    if ($login='Admin' && $pass='19ak129')
    $secure=true;
    if ($secure)
    { // do something very important.
    }
    ?>

    In many cases this script's security could be bypassed by adding "&secure=true" at the end of the URL!

    I prefer to generate or define a set of values that are acceptable and check with in_array().

    EG:

    <?
    $acceptable=array('a', 'b','na');
    if (!in_array($acceptable, $_REQUEST[check]))
    die ('Sorry. Input in field "check" is invalid');
    ?>

    Or by using a regex. Assume that the input must be a number:

    <?
    $match="/[0-9]+/";
    if (preg_replace($match, '', $_REQUEST[number]))
    die ('You must put in a number');
    if (strlen($_REQUEST[number]>5))
    die ('Number you have entered is out of range');
    ?>

    You can oftentimes functionalize these so that it's as simple as:

    <?
    if ($error=Valid_Integer($_REQUEST[number]))
    die($error);
    ?>

    Simple methods that can greatly enhance security!

    --
    I have no problem with your religion until you decide it's reason to deprive others of the truth.
  10. Watch the USER! by anubi · · Score: 3, Interesting
    As long as we have no control over what the user tries to install and run in his machine, we are always going to be vulnerable to trojans.

    The proliferation of proprietary formats we are seeing that all do basically the same thing, like send sound files over the net, or view video clips, are encouraging mass downloads of programs from third party providers. These programs may well do what they said they would do, but with all this DMCA crap going on, its getting harder and harder to see if they are doing a little extra that wasn't in the bargain, like doing zombie work on the side to assist in little capers the originating author needs to pull off.

    What firewall or systems programming can stop a deliberately malicious program installed by an ignorant user? Say the program "demands" access to the internet for "verification/auto-update", then you have to set the firewall to allow this program access to the net. Now what happens? Its like giving car keys to a valet parking agent. You only have to trust he's only going to do what he says he will do. To add insult to injury, consider you generally have signed any recourse you have when you click that "I agree" button that confirms you have read and understood the EULA.

    What irritates me so about these "plug-ins", "macros", and "scripts" is that they are indeed executable. Nothing says the malicious person coding these things is gonna follow the rules. He is free to code some really nasties in assembler if he so desires. The state of music file distribution I find really disturbing. We have an MP3 format which is generally well understood, yet it seems everybody jumping on the bandwagon wants to use proprietary formats which are not generally understood, leaving us all open to the risks resulting from ignorance.

    As a public, we aren't helping much. We agree to any damn thing they print in the EULA. As a public, we should INSIST that if we are to be kept ignorant by law how something works, if that something does something malicious, then its maker should have full responsibility for the problems it generated.

    Basically I am proposing a trade. If you want the protection of law to keep the public ignorant, then you waive indemnity.

    We have a patent system and copyright system in place. Both were implemented on the concept that the work was to be in the open. Why aren't encrypted work also known as "trade secret" and not afforded protection by copyright or patent? Basically, any work encrypted would be considered a "trade secret", not in the open, hence not eligible for protection by the patent or copyright system at all? But to make this happen, its gonna take the will of a lot of people to pressure the legislators to enact this. Pressure as in "if you do not do this, start polishing your resume.".

    --
    "Prove all things; hold fast that which is good." [KJV: I Thessalonians 5:21]

  11. Perl security article in SysAdmin magazine by merlyn · · Score: 4, Informative

    I wrote a similar article recently for SysAdmin magazine, although the focus is more about Perl.

  12. This was well documented in the 1970's by pcause · · Score: 3, Insightful

    The Kernighan & Plauger book "Elements of Programming Style" dated 1979 talked extensively about the need to validate all inputs to subroutines and from the user. This is *not* new, it is just that few programmers have the discipline to follow the rules.

    The issue is making *no* assumptions about anything. The programmer *thinks* the file will be written be another piece of code that a team member is writing. But that program has a bug. or three years from now, other programs are creating the file and don't know abut some verbal discussion about field data. It takes great dligence and paranoia and management that allows you the time in the schedule to do this.

  13. environment variables by MellowTigger · · Score: 3, Funny

    The article is interesting, and they are right to point out the many dangers of relying on environment variables. Where I work (unidentified to protect the incompetent), programmers are not allowed access to the unix command line. Instead, all user exits are trapped, and programmers are forced to navigate through a homegrown menu system.

    This menu system relies on an environment variable ${WHATCANIDO} to store a list of permissions available to that user. Of course, I changed my .profile to add my own extension to the permission list. I even nicely dated, initialed, and described my change. ;)

    export WHATCANIDO=world_domination:$WHATCANIDO # 2000/10/31 tw Too easy

    So now when I get frustrated with the absurdity of this arrangement, I just take echo the environment variable to remind myself why I'm right and they're wrong.

    > echo $WHATCANIDO
    world_domination: [deleted]

  14. Re:If you input ever displays as HTML by Admiral+Burrito · · Score: 3, Informative
    BTW, anyone know of some magical code to block SQL injection vulnerabilities?

    Use placeholders. PEAR DB supports them, as do other database abstraction layers. As long as you _always_ use placeholders you will be safe against SQL injection.

    If you can't depend on PEAR DB (or similar) to be installed / at the correct version, you could quickly build yourself a function that takes a variable number of arguments: a SQL statement containing '%s' (for strings) or %d (for numerics) followed by potentially hostile arguments. Run each of the arguments through mysql_escape_string (or equivalent for your DB) then build your SQL statement using sprintf. Note: I haven't tested that approach; use with caution.

  15. Re:Problem: Hacker Languages by BattleTroll · · Score: 4, Insightful
    "But almost nothing else should be written in C/C++"

    What world are you living in? Blaming poor technique on the tool used is moronic. There are ample examples of poorly written, poorly secured Java code the invalidate all of the premises in this rant. I've seen hard coded passwords baked into java source that were visible through a 'strings' call. Someone forgets to obfuscate his or her classes, and the entire structure of the program is available through a reverse compiler. Sure, the JVM protects one from buffer overruns and the like but don't for one minute think that programming in Java prevents stupid errors from exposing you to vulnerabilities.

    Not to mention there are areas where java is not the silver-bullet you describe. If you need precise control over your memory allocation, java is not the tool to use. If your application requires precise timing, java is not the tool to use. Need to control over the placement of allocated memory? Writing your own transport layer? Need hooks into the kernel?

    The prime directive still holds true - use the correct tool for the job at hand. Follow the lemmings of "this tool is the only one you need" at your peril.