Slashdot Mirror


PHP and SQL Security

An anonymous reader writes "PHP and SQL Security are being proven more weak every day. Uberhacker.Com is running a PHP and SQL security research project to raise awareness of secure scripting. The site hosts guides to secure PHP programming, forums, and scripting challenges to see who can create the most secure scripts."

28 of 305 comments (clear)

  1. A bad workman blames his tools by dorward · · Score: 5, Insightful

    Looks more like "Scripts people write using PHP and SQL without understanding security issues are being proven more weak every day." to me.

    1. Re:A bad workman blames his tools by quigonn · · Score: 5, Insightful

      Well, sometimes you can simply blame the tools. Or would you blame the workman who cuts off his arm with the buzz saw's totally unprotected blade?

      The same is valid for programming languages, with some it's just easier to shoot yourself in the foot when you make a mistake. One example are buffer overflows and C: it's so easy to mistakenly write code that produces one, while in other languages like Ada or Perl it's virtually impossible.

      The same goes for PHP and SQL, which is shown everyday on the usual mailing lists like Bugtraq or full-disclosure.

      --
      A monkey is doing the real work for me.
  2. No. by mfh · · Score: 5, Insightful

    PHP and MySQL are not weak; faux programmers are weak. Purification of incoming data is essential, and often ignored by novice script-writers, and that's the problem. SQL injections are common among novice coders, and they can slip past even competent coders, but a strict design engine for passing SQL vars using $_REQUEST, and turning off register_globals, will result in better results.

    Essentially, the problem is with those making insecure scripts, not the whole PHP and SQL system.

    --
    The dangers of knowledge trigger emotional distress in human beings.
    1. Re:No. by leandrod · · Score: 5, Insightful
      > Object oriented programming should prevent this

      Security comes from simplicity, not complexity. And security should start at the DBMS level, not be left to applications.

      --
      Leandro Guimarães Faria Corcete DUTRA
      DA, DBA, SysAdmin, Data Modeller
      GNU Project, Debian GNU/Lin
    2. Re:No. by Anonymous Coward · · Score: 4, Informative
      I regard myself as a fairly competent PHP programmer, and while I wouldn't be surprised if there are security holes in some of the stuff I've written, I've made every effort to stop them from happening.

      I've got a couple of rules I try to abide by - can anyone confirm if they're good programming practice? If they are, then they might prove useful to other people. :-)
      • Always check user input as much as is possible. Probably at least two-thirds of my programming is input data verification.
      • Always escape text which is going into an SQL query, or do an (integer )$number if it's supposed to be an integer. Do this in a very obvious place (eg when setting the $query string itself) so you don't forget. SQL injections are horrid. Test any functions which generate SQL until you're absolutely sure they aren't doing the wrong thing.
      • Use htmlspecialchars() on any text that's being output, to stop users putting rogue HTML, Javascript or anything into the output - even if it'll only end up in an error message or similar.
      • Put database usernames, passwords, pathnames and other similarly important but site-specific data in a define(), where once set it cannot be redefined.
      • Never include() or require() something that isn't a hard-coded string. Use readfile() or fpassthru() or similar if you need to output an HTML template or whatever.
      • Be hugely careful with any file operations. Don't use any user-supplied filenames, etc, unless they're thoroughly checked.
      • Initialise variables, and forcibly set the type of incoming data with an (integer ), (string ) or whatever.
      • Always use $_GET, $_POST etc to get submitted variables and not register_globals, and put anything that's not dealing with getting such data into a function - page_blah( (integer )$_GET['id'], text_unescape( $_GET['moo'] ) ); and so on, in a place neatly out of the scope of any register_globals crap.
      • Never rely on automatic escaping of input variables - I've got a bunch of functions for automatically unescaping arrays and strings which have been mangled by the magic_quotes_gpc rubbish. I'd switch the feature off, but hosts often have it switched on - and my functions check if it is and respond accordingly.
      • Be paranoid. Always assume the user is out to get you. If there's a function which does something restricted but is called by an apparently safe function, double-check the user's credentials.
    3. Re:No. by Lumpy · · Score: 4, Informative

      not only purification but treat all incoming data as hostile.

      every thing that comes from the user needs to be scrubbed, bleached, hammered and then finally used when you know it is 100% safe. and it must be used in a safe manner.

      what blows my mind is those that use the DB column name in a webform to be passed.. Oh nice. select from that drop down item_number and simply change it to start playing corrupt the database games.

      Nothing that is ever given to the user, or recieved from the user should be trusted... EVER. that is the first rule and needs to be pounded into everyone in every book about any programming language for the first 5 chapters.

      start there and you will heve very little security issues.

      --
      Do not look at laser with remaining good eye.
    4. Re:No. by mfh · · Score: 5, Informative
      > Always check user input as much as is possible. Probably at least two-thirds of my programming is input data verification.

      Good. You are off to the right start, but with better function programming, you will find yourself writing more feature code than purification code.

      Things to look for:
      • Push 99% of all expected/selectable data into tables with a record_id, so you can easily purify the incoming data:

        function npurify(&$text){
        if(!is_numeric($text)) $text = 1;
        }

        Protects against SELECT SQL injection attacks.

      • Snuff out > and < chars so that they can't contain the Script HTML tag when purifying data. Replacing these characters with their html entities usually works; ie:
        > becomes &gt;
        < becomes &lt;
      • Convert data in your database to base_64 and gzdeflate it:
        $data = base64_encode(gzdeflate($data));
        This will prevent the problems with escaping quotes and apostrophes for SQL, and it will kill any SQL injections in your data.
      • Use better logic for testing incoming data;
        if($this) {perform action}... will limit your chances of having to cope with scipt injections because you are only testing for the existence of a condition, and not the value of the data.
      • Run bitchecking against acceptable alphabets for purification of character values. Gauge to have good CPU usage of this sort of thing.

        // blanks out unaccepted characters
        $alphabet = '`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz01234567890~!@#$%^&*()_+=-,.<>?/|;:\'"'.chr(92 ).chr(10);
        $sizestr = strlen($text);
        $sizestr--;
        for($i = 0; $i <= $sizestr; $i++) {
        if(strstr($alphabet, $text[$i])) {
        continue;
        }else{
        $text[$i] = ' ';
        }
        }

      • Code a good link converter, so you don't have to accept HTML in posts, and you don't need to accept any HTML.
      • There are likely more, but these are the big ones.

      > Always escape text which is going into an SQL query

      I prefer to write my own SQL text, based on input values. That way you are never using data submitted for the SQL query. The only time they would really submit values would be when they are sending in a username and password, but in that case, you should be extremely stringent in purification by only accepting alphanumeric usernames and passwords (ie: run the alphabet function above, but erase all non-alphanumeric chars from the $ALPHABET var).

      > Use htmlspecialchars() on any text that's being output, to stop users putting rogue HTML

      htmlspecialchars() doesn't always work. I prefer using the example above, by limiting the characters allowed and disallowing HTML in the form of post body/subject data. Converting everything to base64 will make it nearly impossible to script attack the database, too.

      > Put database usernames, passwords, pathnames and other similarly important but site-specific data in a define()

      I disagree, because I use the $_SESSION array instead, which can not be changed by a user if the session cookie is server-side. Sessions can be scooped by sniffers, but that can be managed by your host's security, to prevent it. Certainly change the locale for session data from /tmp/, because that narrows down hack attempts, making it all the more harder to compromise the system.

      > Never include() or require() something that isn't a hard-coded string

      To me, this isn't totally required if you have suitable purification, but that extra bit of paranoia is welcomed, because it shows true fear and that is acceptable in any kind of programming. That sort of humility is welcomed because it demonstrates a compassion for the task at hand.

      > Be hugely care

      --
      The dangers of knowledge trigger emotional distress in human beings.
    5. Re:No. by Frizzle+Fry · · Score: 4, Insightful
      Constructors should parse special characters that could lead to injection.

      No! No, no, no. You don't look for characters that "could lead to injection" and block (or escape) them, you look for input patterns that you know to be safe (ones that can't lead to injection) and only allow those. Trying to guess every possible input that can cause problems is not a good security practice. Please reread Writing Secure Code.
      --
      I'd rather be lucky than good.
  3. Ease of introduction by holzp · · Score: 5, Insightful

    I think a lot of the blame for this can be traced to the ease of getting started with PHP/MySQL. Result: more people learning how to program with php will of course result in less thought about security. Add the ability to have input arguments via the http request be automagically available to the running code shares a lot of the blame too. Put them togeather and thats a disaster.

  4. "more weak"? by Junks+Jerzey · · Score: 5, Funny

    How about "weaker" :P

  5. Should I submit this one? by blcamp · · Score: 5, Funny

    This one is pretty secure...

    <?php

    // Try to break into this script!
    echo "Hello World!";

    ?>

    --
    The problem with socialism is that they always run out of other people's money. - Margaret Thatcher
    1. Re:Should I submit this one? by horza · · Score: 4, Funny

      You sound like a security expert. I'm told one of my scripts might be insecure, do you think you could tighten up the following:

      <a href="$PHP_SELF?command=date">Click here to see the date</a>
      <?php // Try to break into this script!
      if ($command) echo system($command);
      ?>

      Thanks,

      Phillip.

  6. magic_quotes by ftzdomino · · Score: 5, Funny

    You could also enable magic_quotes in your php.ini. However, if you\'re too dumb to know the basics of sql, chances are your program won\'t work quite right.

  7. I can't take a security sight seriously that... by bbzzdd · · Score: 5, Funny

    uses MS Comic font for their articles. Sorry.

    1. Re:I can't take a security sight seriously that... by daeley · · Score: 5, Funny

      Never mind that, they're using a tag to achieve it! The horror! ;)

      --
      I watched C-beams glitter in the dark near the Tannhauser gate.
  8. PHP is as secure as you make it by kyndig · · Score: 4, Insightful

    Your scripts are only as secured as you make them. What this "UBERHACK" website is simply doing is sending a flock of young script junkies out to locate sites which have not implemented a good code structure.

    PHP documentation clearly states the pitfalls of using variables in a global scope. It is for this reason that PHP changed its GLOBAL array structure to read $_POST and $_GET methods, as well as default setting register_globals to off.

    I find it a poor use of a developers time to attempt to see whose site they can deface. It is imoral and shows a lack of respect for those whom put countless hours into their site development.

    I would challenge "UBERHACKER" to spend more time developing their website which is showing to be in poor syntatical use of HTML, slow loading and poor in URL design. Why run a php scritp in a /cgi-bin/ do you feel more secure by doing so? The ScriptAlias which you most probably have set for this directory will in no way prevent malicious intent from remote connections if your php is not properly configured for base_directories, register_globals, and safe_mode.

    http://uberhacker.com/cgi-bin/index.php?page=fla b
    Pick up any book on programming and learn proper developmental tactics ( Throw / Catch ) before promoting the attack of others because your 'Uber' site thinks it can't be Hax0r3d.

    End Rant.

    --
    My Thoughts, Kyndig
  9. C'mon, Drop the FUD by da3dAlus · · Score: 4, Insightful

    There is no trully unsecure language, only programmers that practice building unsecure sites. Bugs and security holes can always be patched, but if the site is crap to begin with, then that's just asking for trouble. You should always check user input, esp if you plan to use said input as part of a SQL query or entry. Duh.

    --

    Sometimes I doubt your commitment to Sparkle Motion.
  10. Guides to Secure Programming? by JumboMessiah · · Score: 5, Informative

    Other than the scripting challenge, what's on this site? I've read the guides to hacking, but it's all a bunch of kindergarden material. Seems if you follow the guides you'll certainly have insecure PHP scripts with all kinds of SQL injection. How about posting some real articles on secure PHP scripting...

    1. Re:Guides to Secure Programming? by shiflett · · Score: 4, Informative

      I have a few articles on my Web site that might be informative: http://shiflett.org/articles

      I'm also writing a monthly PHP security column in php|architect, and these articles will be available for free six months after publication.

      Lastly, I am writing PHP Security for O'Reilly, which is due out in the fall.

  11. Re: cutting off an arm by sczimme · · Score: 5, Interesting


    Or would you blame the workman who cuts off his arm with the buzz saw's totally unprotected blade?

    Yes, I would: he was obviously doing something with the saw that was inappropriate; what saw-oriented task [when done correctly] involves waving it at one's own arm?* The fact that the blade was unprotected is irrelevant since he should have known it was unprotected and therefore dangerous. All tools can be used stupidly, and oddly enough the results really can be the fault of the operator. It is also possible for fault to lie in more than one area.

    Yes, I know the traditional definition of 'hacking' includes making $ITEM do something it was not intended to do, but there are limits.

    * I'm guessing that 'buzz-saw' == 'circular saw'.

    --
    I want to drag this out as long as possible. Bring me my protractor.
  12. 404d! by michael+path · · Score: 5, Funny

    Maybe someone can write a PHP script to take care of the 404 error that occurs when you click on the "home" link on Uberhacker.com.

    Bad Design Überalles.

  13. SQL injection 101 ... by zonix · · Score: 4, Funny

    People! Remember the quotes! Do:

    delete from table where id = '$var'

    Not:

    delete from table where id = $var

    Try for $var = "10 and id = 11 and id = 12 ...".

    z
    --
    What would an EWOULDBLOCK block, if an EWOULDBLOCK could block would? -- me
  14. SQL Injection in PHP by uss_valiant · · Score: 5, Informative

    AFAIK SQL injection can be prevented by binding the parameters to the SQL statement and not putting them within SQL.
    An example:
    It's easy to inject some malicious SQL when using the following PHP code:
    mysql_query("INSERT INTO FOO('Bar') VALUES('$some_post_param');");
    But if you prepare the SQL statement with parameters and bind the variable $some_post_param to the statement, it will be secure.
    see mysql manual for mysqli_stmt_bind_param() aka bind_param
    $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); $stmt->bind_param('sssd', $code, $language, $official, $percent);

    I know this concept from Perl DBI, but in PHP I haven't seen anyone (phpBB, ...) using bind_param. Why is this? Performance? Keeping the code short and simple?

    As for general webserver security: use PHP and perl as cgi, use suEXEC, run the webserver as nobody/www, put the users into chroot jails, but by all means, don't use PHP safe_mode On.

  15. Secure Programming HOWTO by dwheeler · · Score: 4, Informative
    For guidelines on how to develop secure programs, see my Secure Programming for Linux and Unix HOWTO. This Free book provides a set of design and implementation guidelines for writing secure programs for Linux and Unix systems. That includes application programs used as viewers of remote data, web applications (including CGI scripts), network servers, and setuid/setgid programs. The book includes specific guidance for a number of languages, including C, C++, Java, Perl, Python, PHP, and Ada95.

    --
    - David A. Wheeler (see my Secure Programming HOWTO)
  16. Nope by kuzb · · Score: 5, Insightful

    This is not an issue dealing with PHP and MySQL, this is an issue with weak programmers writing bad code, and I'm sorry to say, you find it in every language. As a regular in #php on freenode, we are constantly correcting bad coding practices.

    In fact, it's not uncommon to find people using GET and POST variables straight out of the box without any kind of validation whatsoever. Many people do not learn the de-facto first rule of web programming: the user can not, and should never be trusted.

    To make matters worse, applications like PHP-Nuke spring up which are notorious for sloppy coding practices, and people tend to see them as reflect on the PHP community as a whole. That's like blaming the C language because someone, one day, wrote some bad code in it that got someone else hacked. This happens all the time, but we don't make claims like "C security is weak". Instead, we worry about the truth of it, that the programmer in question did a bad job, or just flat out missed something.

    One of the key points that seems to trip most novices up (and granted, this is one of the stupider moves presented by the PHP Core Development team) was a thing called magic_quotes_gpc, which attempts to auto-escape incoming GET, POST and COOKIE variables in an attempt to sanitize user input. This is usually a double-edge sword because newbies are typicly not aware if it is, or isn't on. In later versions, this is on by default, and does prevent many SQL injections from occuring. However, for the more experienced user, having your input auto-munged can be something of a pain. Unfortunatly, to write truely portable code one must test this value and normalize data accordingly.

    The issues don't stop there though. I've seen many a more serious faux pas committed by the newbie. Another more serious flaw that I see happen on a regular basis is the use of user data within include statements without proper path checking. This is probably one of the more disasterous errors I see occuring because it typicly exposes sensitive data. There has been more than one occasion where i've shown a user their own passwd file in a browser to make my point.

    Anyhow, to the newbies: we, the more experienced people of PHP are on our own quest to educate people, many times in a one-on-one basis on Freenode. If you're not sure about a particular issue, grab an IRC client and ASK US (irc://irc.freenode.net). We're there to help!

    --
    BeauHD. Worst editor since kdawson.
  17. Not sure if this is news by l0ungeb0y · · Score: 4, Interesting

    Sh!t PHP coding is as old as the hills.
    Some of my favorite things I see _ALL_ the time:

    Something bad happens while executing the code?
    Let's <? die("here's my database connection info in case you wanted it"); ?>

    Then there was the client who's previous developer was some moron who stored the database connection info into a .inc file under htdocs!

    The web "design" group who's MySQL database was wide open without authorizing with a password.

    The arsehole developers who built themselves little backdoor webpages during development to exec shell commands and upload/exec files ... not so much as an HTTP_AUTH to secure it with and would handily chmod 777 all uploaded files and put them under htdocs for ease in execution.

    I've seen about 3 websites store credit card numbers unencrypted into a MySQL database.

    I could go on and on and on, being a development gun for hire since 98, I've seen some things that defy all logic and explanation. In fact, I still wonder why they call it Computer Science. Now, Computational Arts I could buy into.

  18. "fuzzy developing" by mabu · · Score: 4, Insightful

    Interesting topic, but I don't think the problem lies with PHP or MySQL. You can create insecure apps in any development environment. Yes, some are more problem-prone than others, but I'd rank Perl much higher than PHP/MySQL in terms of being conducive to allowing vulnerabilities.

    I attribute much of this problem to something I call "fuzzy developing". It's the latest trend. The crux of this problem involves Web designers, who know very little about programming who are deploying more and more complicated applications in a cut-and-paste manner. These fuzzy developers have no concept of proper programming skills. Many of them can't program at all, but they can snarf someone else's "free" code online, change a few config parameters, whine to an admin for access, and compromise entire servers.

    This new breed of developer relies on existing code, following the fallacy that if it's on the net, it must work. They use sites like experts-exchange to get other people to code for them when they get in a snag, and don't contemplate the priorities involved when you put something on a public system.

  19. Re: cutting off an arm by kpharmer · · Score: 4, Insightful

    >>Or would you blame the workman who cuts off his arm with the buzz saw's totally unprotected blade?

    > Yes, I would: he was obviously doing something with the saw that was inappropriate

    Yeah, that's pretty much the line of the discredited 19th century factory-owners. They all insisted that worker injureries were due to carelessness on the part of the worker. Then people began to noticed that eventually almost all workers became completely disabled. About that time folks began to realize that a tool that requires you to be perfect 100% of the time is a flawed tool. Or a self-mutilation device, you pick.

    And the same arguement keeps resurfacing, btw. Not just among factory owners trying to preserve maximum profitability. But also amoung techies trying to defend crappy products:
    - RTFM
    - can't get a printer to work with cups? must be a newbie
    blah, blah, blah

    Then in the late 90s Usability and Information Architecture really took off. These guys saw a a few patterns:
    - the jack-assed argument that difficulty with a tool was the user's fault - resulted in lost users, lost sales, lost revenue. Those who insisted on blaming the workman rather than the tool - thankfully went out of business.
    - usability challenges also caused security vulnerabilities - when users couldn't figure out how to secure a device it became a liability to everyone. So, in this case the tool harmed the entire community not just one workman.

    The only interesting thing in the above comment is that you actually got modded-up for repeating a completely discredited notion. Sigh, probably just a clever troll and I fell for it...