Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
PHP Programming Software Apache IT Technology

PHP and SQL Security 305

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."
This discussion has been archived. No new comments can be posted.

PHP and SQL Security

Comments Filter:
  • by dorward ( 129628 ) on Tuesday April 27, 2004 @10:41AM (#8983898) Homepage Journal
    Looks more like "Scripts people write using PHP and SQL without understanding security issues are being proven more weak every day." to me.
    • "Scripts people write using PHP and SQL without understanding security issues are being proven more weak every day."

      That is stating the obvious, but none the less - it must be said. Nealry every language/backend is a potential threat when developers who don't have an understanding or awareness of security start coding.
    • by quigonn ( 80360 ) on Tuesday April 27, 2004 @10:48AM (#8983985) Homepage
      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.
      • 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?

        Yes, of course. A good workman would never willingly use such a dangerous tool!

        That being said, as far as SQL security goes, PHP fares far better than its competitor, ASP.

        Indeed, by default, PHP comes with gpc_magic_quotes enabled, which prevents the more obvious SQL injection attacks. Of course, nothing is 100% foolproof, but we're nowhere near the sieve that

        • by slamb ( 119285 ) * on Tuesday April 27, 2004 @12:23PM (#8985253) Homepage
          Indeed, by default, PHP comes with gpc_magic_quotes enabled, which prevents the more obvious SQL injection attacks. Of course, nothing is 100% foolproof, but we're nowhere near the sieve that ASP+Sequel Sewer is.

          No, no, no, no, no!

          magic_quotes_gpc is totally broken. For those unfamiliar, it escapes all HTTP GET and POST strings MySQL-style. But this is stupid. How you want your strings escaped (if you do at all!) depends on where you are sending them to, not where you are getting them from. Consider these things you might be doing with the strings:

          • using in a database statement (DML or query) with bind variables: no escaping. (This is the best way to use these in SQL!)
          • sending them out as character data in a HTML page: escape & to &amp;, escape < to &lt;, and (when in an attribute, harmless otherwise) escape " to &quot;
          • using in a MySQL or PostgreSQL literal: that way is actually correct
          • using in a MySQL or PostgreSQL identifier: that might also be correct? not sure. certainly " needs to be escaped, though.
          • using in a standard SQL literal: ' needs to be escaped to ''. \ should not be escaped.
          • using in a standard SQL identifier: " needs to be escaped to "". \ should not be escaped.

          PHP has a shiny red button that you never want to press. This is one of many reasons that I say PHP is a broken tool.

          • magic_quotes_gpc is totally broken. For those unfamiliar, it escapes all HTTP GET and POST strings MySQL-style. But this is stupid.

            No, you are missing the point. magic_quotes_gpc is a handy safe-guard for newbies, most of whom will be using MySQL. The downside is some errant slashes that may be annoying, but are far less dangerous.

            If you don't like it, THEN TURN IT OFF, but don't suggest that increasing PHP's out-of-the-box security for newbies makes the tool somehow 'broken'. This is hardly an inconve
            • No, you are missing the point. magic_quotes_gpc is a handy safe-guard for newbies, most of whom will be using MySQL. The downside is some errant slashes that may be annoying, but are far less dangerous.

              So you're saying it's a language feature aimed at helping newbies producing mediocre code.

              magic_quotes_gpc is dangerous, in that it confuses said newbies horribly about a critical issue. They may be producing mediocre code where they would have been producing bad code, but it will lengthen the time until

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

        I would if he ignored the instructions telling him to protect himself before using it after hearing the horror stories from the large collection of one armed men (watch out Dr Richard Kimble) in the building!

        • *clears throat* .. I'd like to take a minute to talk about shop safety. Be sure to read, understand, and follow, all the safety rules that come with your powertools. Knowing how to use your power tools properly will greatly reduce the risk of personal injury. And remember this, there is no more important safety rule than to wear these.. safety glasses.



          I wonder if anyone else watches Norm that reads /.

      • by sczimme ( 603413 ) on Tuesday April 27, 2004 @11:05AM (#8984208)

        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'.
        • by kpharmer ( 452893 ) * on Tuesday April 27, 2004 @05:55PM (#8990053)
          >>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...
      • If PHP installs by default with register_globals = off and developers turn them on can we really blame PHP?
    • Absolutely. It's not PHP's fault it has a lot of clueless and/or lazy users.

      And it isn't PERL's fault that people use it to write utterly incomprehensible code. Or is it...?
    • Languages which encourage the mixing of code and data make it extremely easy to write insecure code, and no programmer is immune to bugs. Yes, the coder is to blame, but so is the language.

      SQL is probably the most widespread example of this, closely followed by regular expressions in Perl. I am often amazed that more people aren't working towards programatic ways to express SQL queries and/or regular expressions (attempts exist for both, but rarely make much progress).

      • I am often amazed that more people aren't working towards programatic ways to express SQL queries and/or regular expressions

        They're called stored procedures. They've existed for at least 20 years.
        • They're called stored procedures. They've existed for at least 20 years.
          No they aren't. Stored procedures still require SQL code to be embedded in the client code - and therefore still requires the mixing of code and data.
          • Stored procedures still require SQL code to be embedded in the client code - and therefore still requires the mixing of code and data.


            Have you ever used a stored procedure? You call the name of it, and that's it. You give the web server permission to call the stored procs.
  • No. (Score:5, Insightful)

    by mfh ( 56 ) on Tuesday April 27, 2004 @10:42AM (#8983916) Homepage Journal
    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.
    • Re:No. (Score:3, Insightful)

      Seriously, I agree. Object oriented programming should prevent this, too. Develop object models then take the request variables and insert them into the objects before inserting them into SQL. Constructors should parse special characters that could lead to injection. Also, it is easier to implement business rules using OOP. Seriously, even interpreted languages do OO now, its time we all used them.
      • Re:No. (Score:5, Insightful)

        by leandrod ( 17766 ) <l@dutras . o rg> on Tuesday April 27, 2004 @10:54AM (#8984054) Homepage Journal
        >
        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.

        • Bind variables (Score:3, Insightful)

          Actually, bind variables help much more than object oriented programming.

          Writing al=execute_query("SELECT access_level FROM user WHERE user=? AND password=?", user, password) is naturally so much more secure than al=execute_query("SELECT access_level FROM user WHERE user='"+user+"' AND password='"+password+"'");

          Nowadays, most database products worth their salt (Oracle, Postgresql, and even my Mysql!) support bind variables. And even if you have an old version of Mysql (which doesn't support them), Perl D

          • If you were using SQL Server, you'd use ADO instead of SQL strings. That really is one thing I miss about mySQL and it's ilk.
          • Re:Bind variables (Score:3, Informative)

            by fungus ( 37425 )
            Not only bind variables are more secure, but they also increase database performance where it counts.

            Bind variables permit databases to match a query with cached queries even if parameters are different. It will then be able to fetch the appropriate execution plan instead of making a new one for each similar request.
        • Security does not belong in the database because it removes context of action. The correct level of security is to place it in between the database and the interface through a well-defined, simple interface that keeps the context of the action secured from the interface. By treating each element in the table as an object, the object is loaded with the security of the entity at the time of instantiation; thus, even if the interface is highjacked and the object is commanded to alter information, the user do
          • treating each element in the table as an object, the object is loaded with the security of the entity at the time of instantiation

            This adds, and duplicates an enormous amount of complexity and overhead. I've seen two large scale projects programmed this way fail because performance and time to develop were so incredibly poor. In one case, a company folded because the team leads went with this boneheaded architecture instead of my suggestions. Security belongs in a database. A good RDBMS is moer secure
          • theory vs practice (Score:3, Interesting)

            by kpharmer ( 452893 ) *
            > Security does not belong in the database because it removes context of action.

            aha

            Well, rather than debate whether or not the data should be persisted in the context of its rules and actions (which doesn't work in reporting, btw), lets get down to what simply works.

            You need to plan on including security awareness within each layer and component of your architecture. Since we've moved beyond client-server we seldom now authenticate & authorize individual users in the database. That's fine, but
      • Re:No. (Score:5, Insightful)

        by Frizzle Fry ( 149026 ) on Tuesday April 27, 2004 @01:27PM (#8986150) Homepage
        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.
    • by Sanity ( 1431 ) *
      PHP and MySQL are not weak; faux programmers are weak.
      "Nuclear weapons are not dangerous, people with nuckear weapons are dangerous".

      Regardless of where the ultimate blame lies, the simple reality is that languages which encouraging the mixing of data and code encourage security-threatening bugs. SQL is a nasty example of this, Perl regular expressions are another.

    • Hoppity Hop (Score:3, Informative)

      by Tablizer ( 95088 )
      and turning off register_globals, will result in better results.

      One of the problems is that PHP has kept changing the way it handles session variables such that if you move your site you may encounter problems (it takes some sites a while to upgrade their PHP interpreter). One solution is to make your own set of session var functions (scalar only) to wrap the changes or per-site differences, or simply live with register_globals on.

      Maybe in a few years it will settle down, but the recent changes have gu
      • and turning off register_globals, will result in better results.

        I couldn't agree more. register_globals really should be off, but often can't be.

        In the developement of our PHP application suite we've run into a big problem with the persistance of object trees. Basically, if you put a tree of objects that contain references into the $_SESSION array without register_globals on, when you get them back in another execution cycle the references will be all jumbled up with copies of the objects to boot. For so
    • Liberal use of addslashes() +
      Surrounding data from clients with quotes in SQL =
      SQL injections? Where?
    • Re:No. (Score:4, Informative)

      by Anonymous Coward on Tuesday April 27, 2004 @11:27AM (#8984484)
      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.
      • Re:No. (Score:5, Informative)

        by mfh ( 56 ) on Tuesday April 27, 2004 @11:59AM (#8984916) Homepage Journal
        > 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

        • 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;

          I have found this one to be pretty reliable for completely nuking HTML, it is based on Larry Walls code and slashdots code:

          function cleanInput($in) {
          if ($in != '') {
          // strip out comments
          $in = preg_replace('/<!(.*?)(--.*?--\s*)+(.*?)>/', '', $in);

          // cleans up leftovers from neste

    • Re:No. (Score:5, Informative)

      by Lumpy ( 12016 ) on Tuesday April 27, 2004 @11:29AM (#8984505) Homepage
      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.
      • by mfh ( 56 )
        > what blows my mind is those that use the DB column name in a webform to be passed

        OMG how many times I've seen that!!! It makes me wonder what planet these people are on. It's like they have a big bullseye on their asses, really.

        Keeping table names secret is a good way to make it harder for script kiddies to attack. PHPBB allows for table names to have a prefix for this purpose, and sadly most people using it don't even bother.

        Since most attacks come from script kiddies, you limit the ability by obf
      • Re:No. (Score:4, Insightful)

        by noda132 ( 531521 ) on Tuesday April 27, 2004 @12:30PM (#8985343) Homepage

        what blows my mind is those that use the DB column name in a webform to be passed.

        Along the same vein: I cannot count the number of scripts I've seen which use <select> tags and simply assume in the processing script that the only possible values are those which were given in <option> tags. Ditto for text inputs with a maxlength.

        It all stems from a complete ignorance of the specs, or a bunch of reading-between-the-lines which is utterly stupid. Nowhere in the HTML spec does it say that the page referenced in a form action will always be requested with valid input.

        The other thing which irritates me is how so many people assume using mysql_ functions is the best way to talk with a database. The PEAR project has had a fully-functional, object-oriented database package for years which handles escaping all by itself. It also makes INSERT/UPDATE queries much easier to write with its auto-queries.

        In my opinion, this is the tutorials' fault. But it's kind of the same with any language, I suppose: everybody learns C with the standard library and with fixed-length char[] arrays, without learning all the pitfalls (i.e., buffer overflows) and other libraries (i.e., glib) which work around them.

        Proper layering and abstraction should be a primary focus of any intro-to-programming class or tutorial.

  • by holzp ( 87423 ) on Tuesday April 27, 2004 @10:42AM (#8983920)
    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.
    • Good point.
      PHP/MySQL will be considered secure once XAML and Avalon [ximian.com] are released to the world. That will be the new "insecure platform" on slashdot. Not be cause PHP is inherently insecure now and XAML and Avalon will be more insecure, but rather because PHP is the easiest entry into programming and XAML will lower the bar.
      -Jackson [jaxn.org]
    • I have to agree with you on this. I have run into a few systems that were running ASP and a SQL based database in the background that had absolutely no user input validation. I put one on my machine and was able to drop tables and hack my way in in about 10-15 minutes. This system was running at version 2.1 and noone had caught this up until that point. I reported it to the developers, but they didn't seem to keen on actually fixing the problem. Then again if you call the company you realize the VP is
    • It's just like with Windows. But then people don't blame the admin in those instances.
  • by Junks Jerzey ( 54586 ) on Tuesday April 27, 2004 @10:43AM (#8983925)
    How about "weaker" :P
  • by blcamp ( 211756 ) on Tuesday April 27, 2004 @10:45AM (#8983951) Homepage
    This one is pretty secure...

    <?php

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

    ?>
  • by ftzdomino ( 555670 ) on Tuesday April 27, 2004 @10:46AM (#8983970)
    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.

    • Re:magic_quotes (Score:3, Interesting)

      by drew ( 2081 )
      that might be a good solution if it was the right way to escape quotes in most databases. what databases use \' other than mysql? in my experience, the correct way to escape a ' on oracle, ms sql, sybase, postgresql, etc. is ''. this drives me crazy at work, because for some unknown reason, we actually have magic_quotes enabled, so i have to strip_slashes, _and_ properly escape my quotes. grr....

      at least with PEAR::DB now, i can finally do:
      $db->query(select * from foo where a = ?", $a)
      and not worry
  • by bbzzdd ( 769894 ) on Tuesday April 27, 2004 @10:50AM (#8984003)
    uses MS Comic font for their articles. Sorry.
  • by kyndig ( 579355 ) on Tuesday April 27, 2004 @10:54AM (#8984050) Homepage
    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.
  • by da3dAlus ( 20553 ) <dustin.grau@gm[ ].com ['ail' in gap]> on Tuesday April 27, 2004 @10:56AM (#8984066) Homepage Journal
    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.
  • MySQL is not SQL (Score:3, Insightful)

    by leandrod ( 17766 ) <l@dutras . o rg> on Tuesday April 27, 2004 @11:01AM (#8984149) Homepage Journal
    When will /. stop posting misinformation?

    SQL is a language, defined by ISO. MySQL is not SQL-compliant. Not even Oracle is. IBM DB2, PostgreSQL are SQL compliant, and a lot better than MySQL too. PostgreSQL is even faster and simpler.
  • by JumboMessiah ( 316083 ) on Tuesday April 27, 2004 @11:04AM (#8984188)
    Other than the scripting challenge, what's on this site? I've read the guides to hacking [uberhacker.com], 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...
  • <mode type="rant">

    The worst practice I ever saw was making the global variables local scope using the extract() function, in... every... single... file... especially the security login files - its almost like register_globals and v4.1 never happened.

    Then again this is the same person who insisted in using the $array[key] [php.net] array syntax which was never the correct way of doing to start with.

    And this was the supergenius hired to replace me. Fun city. Glad I don't work there anymore.

    </mode>

    Dam
  • 404d! (Score:5, Funny)

    by michael path ( 94586 ) * on Tuesday April 27, 2004 @11:07AM (#8984239) Homepage Journal
    Maybe someone can write a PHP script to take care of the 404 error that occurs when you click on the "home [uberhacker.com]" link on Uberhacker.com [uberhacker.com].

    Bad Design Überalles.
  • by zonix ( 592337 ) on Tuesday April 27, 2004 @11:11AM (#8984272) Journal

    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
    • by p3d0 ( 42270 )
      That's exactly the kind of crappy code that makes web sites insecure. If $var includes the right apostrophes, then an attacker can execute pretty much arbitrary SQL code.
    • One way to fix this:

      $var = (int) $var;

      when you know you want an integer only. if you really want

      if (!is_numeric($var)) die("Unsafe value");

      Security is easy, can be done in only an extra line of code. And it helps you debug!

  • SQL Injection in PHP (Score:5, Informative)

    by uss_valiant ( 760602 ) on Tuesday April 27, 2004 @11:12AM (#8984291) Homepage
    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 [php.net]
    $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.
    • 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?

      The reason is that the function you reference is only available in ext/mysqli [php.net], and this requires MySQL 4.1 or greater. There was previously no way to bind parameters like this using PHP and MySQL.

      Also, phpBB is not a good example to use with regard to secure programming practices. It is one of the applications that give people this silly notion th

    • The PEAR DB [php.net] package has a function called quoteSmart() [php.net] that does something like this. It's what I use (and PEAR DB is a great database abstraction tool, by the way.)

    • 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?


      Probably because mysqli (the improved mysql class) is fairly new, and not many people have it compiled into their php.
  • by Anonymous Coward
    It is an economic fact of life. People will always be learning in the job. We will never have a guaranteed level of expertise, let alone competence. Tools will have to start enforcing security. Humble coders have been dealing in overflows, SQL injection, and cross-site scripting forever. Tools that manage buffer/stack overflows are not just for junior programmers. Tools/frameworks that add taint checking and build-in automagic security (like ASP.Net's validaterequest). If we have to rely on all the programm
  • Crap site (Score:3, Interesting)

    by pommaq ( 527441 ) <straffaren@sPLAN ... minus physicist> on Tuesday April 27, 2004 @11:14AM (#8984323) Homepage
    Yes, that guide to secure scripting was very useful - a "hello world" program. Whoopee. To be frank, that site looked... well, less than professional, and with a name like "uberhacker" I expected their tips to be a little more advanced than "look, you can change the values in a query string but don't tell anyone!!!!11"

    That being said, I used to write a lot of PHP (I rarely do it anymore at work, but I still try to keep up with the language) and when I first started out I would have loved a comprehensive and easy-to-understand guide to common security holes. The world needs a simple "how to write security-conscious code" for beginners! The sooner you get to see stuff like SQL injection or XSS in action, the better.
  • Jeez... this is hosted on HappyHacker ..
    Won't that lady *ever go away*...

    How long has it been.. she calls the FBI constantly trying to say people who put up negative stuff about her are "hacking" her.

    Dis had to sue to get his face off the cover of her book. I was in the middle of a move and didn't get the email about getting my face off of there.. And I am still pissed about it.

    bah..
    don't give this retch any more publicity.. she is a bottom feeder.
  • by dwheeler ( 321049 ) on Tuesday April 27, 2004 @11:17AM (#8984361) Homepage Journal
    For guidelines on how to develop secure programs, see my Secure Programming for Linux and Unix HOWTO [dwheeler.com]. 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.

  • Input verification (Score:3, Interesting)

    by ZeroExistenZ ( 721849 ) on Tuesday April 27, 2004 @11:24AM (#8984447)
    Think it was just a "look at my cool site, try to slashdot that one!" kindof 'article'.


    So far the most "unsafe" aspect with PHP / SQL setups is poor input validation;

    If you allow direct writing to your SQL and don't do sufficient checks on the input, well.. you'll get in probs with that.

    Proof of concept;
    Hello.. enter your email for free porn: sucker@hotmail.com '; DROP TABLE 'emails';

    Or you have those pages who mess up or display info which can be abused (and / or shouldn't be on that particular page) after there's a "<blockquote>" injected and redisplayed without checking..
    Same with <input type=text>

    Then.. there's JS, and htmlentities, and, and..
    All caffeine intense, and headache inducing subjects you should keep in mind if you plan on bringing something on wire.

    "Nah.. you don't have to do that.. Who's going to know how to do that?"
    "Trust me.. You want me to put in that extra code.."
    "If you really say so.."

    You also have stupid defaults, and uninspired [google.com] coding which gets abused, ofcourse...

    I actually like the PHP / SQL combination and believe it to be safe enough for what I do with it.

    • This was modded up? (Score:3, Informative)

      by Backov ( 138944 )
      PHP hasn't executed more than one query per mysql_query() for quite some time. Your exploit example might have worked a few years ago, but not for some time.

      PHP/MySQL is not really that unsecure. If you don't do stupid things, you won't (generally) get hacked.
  • Nope (Score:5, Insightful)

    by kuzb ( 724081 ) on Tuesday April 27, 2004 @11:32AM (#8984544)

    This is not an issue dealing with PHP and MySQL, this is an issue with weak programmers writing bad code [phpnuke.org], and I'm sorry to say, you find it in every language. As a regular in #php [hashphp.org] on freenode [freenode.net], 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 [php.net], 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 [php.net] 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 [xchat.org] and ASK US (irc://irc.freenode.net). We're there to help!

  • by l0ungeb0y ( 442022 ) on Tuesday April 27, 2004 @11:37AM (#8984639) Homepage Journal
    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.
  • -Good- Sites (Score:2, Insightful)

    by Talian ( 746379 )
    Anyone have suggestions for a bit more uh, quality sites on the topics? Seen plenty of coding sites, but none particular to security of this combo.
  • ASP.NET data binding to SQL has built-in protections to avoid SQL injections and other common SQL security problems. In general, the .NET security model is quite effective and useful for web programming.
  • Security? (Score:2, Funny)

    by natefanaro ( 304646 )
    Why worry about security when your site's been slashdotted? No one can get to it so no one can hack it!!!
  • by slamb ( 119285 ) * on Tuesday April 27, 2004 @12:59PM (#8985737) Homepage
    Most people are attempting to solve cross-site scripting and SQL injection vulnerabilities (the #4 and #6 causes of web security problems, according to this article [lwn.net]) through brute force. Everywhere they use these, they use an escaped version. But this approach doesn't work! For several reasons:
    • it's hard to notice when something is not there.
    • people tend to push these farther and farther away from the actual usage, so they get confused about what has been escaped. It's hard to maintain clear contracts between functions about something like this.
    • even if you're diligent when writing the initial code, it's easy to slip when applying patches

    So I think a new approach is needed. One where you don't mix instructions and data so easily, or flag them more readily.

    With SQL, this has been around for a while: bind variables. Your SQL queries tend to be static with ? thrown in (or :foo for named bind variables). In Perl, it looks like:

    my $sth = $dbh->prepare('select * from mytable where foo = ?');
    $sth->execute($foo);

    Not everyone is using bind variables, and I don't know why. One reason may be that positional bind variables can be confusing: they require you to correlate two lists in your head to position the correct variables in the correct spots. Not all language/database combos support named bind variables. (JDBC doesn't!) But they can be emulated - that's one reason I made xmldb [slamb.org].

    For HTML, it's more rare to find something that does this. Apache Cocoon does, but it's grotesquely complex. I'm working on a simpler system [slamb.org], though it's not ready for production. Here's the idea: my files (XFP) are to a SAX ContentHandler [sun.com] as JSP is to a byte stream.

    I like SAX because it's a way of making XML that does things right. Instead of doing something like:

    out.println("<elem a=\"" + foo + "\" b="blah">Blah: " + bar + "</elem>");
    you write something like:
    AttributesImpl attribs = new AttributesImpl();
    a.add("a", foo);
    a.add("b", "blah");
    out.startElement("elem", a);
    out.characters("Blah: " + bar);
    out.endElement("elem");
    it's nice in that you don't do any of the escaping yourself - you just tell it how you're using each string, so it can do the escaping right. But that's six ugly lines instead of one, and it's worse with real SAX because you need extra arguments for namespaces and things. So I looked at JSP. It sticks Java code inside the text to produce. I stick Java code inside the XML to produce. I write something like this:
    <elem b="blah">
    <xfp:attribute name="a">foo</xfp:attribute>
    Blah: <xfp:expr>bar</xfp:expr>
    </elem>
    ...and it turns it into the code above when it makes a .java file. It still knows how to escape things from context. And whenever you stick in literal text, you can write it just like you'd normally write XML - less long-winded. I might change it to this:
    <elem a="{foo}" b="blah">Blah: {bar}</elem>
    which is shorter still.

    My code is all Java. But the concepts should apply to PHP, Perl, Python, anything.

    Anyone else working on a system to solve this problem? I'd be interested to share ideas.

  • "fuzzy developing" (Score:5, Insightful)

    by mabu ( 178417 ) on Tuesday April 27, 2004 @01:08PM (#8985879)
    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.
  • is that allowing globals is called insecure in PHP and gives no real explaination why except that users can give variables values. Well...that's the idea. It's no different than allowing user input in any other form. The only danger is when you don't assign values to variables before using them. In which case, where were you expecting to get the value?

    And PHP I think is pretty useless without being able to append variables and values to the URL. It's a necessary ability for users to be able to bookmar
  • PHP and SQL Security are being proven more weak every day.

    Where does this guy get his facts? Tell me, what exactly is insecure about SQL or PHP? If you know what you're doing and write your scripts to prevent any SQL injections and you set adequite permissions on the database, you're not going to have any problems (assuming there isn't some huge flaw in the database server, itself).

    By the way, I don't trust anyone who puts up a research project in Comic font. What is this guy, a 12 year old boy, or
  • by mabu ( 178417 ) on Tuesday April 27, 2004 @01:48PM (#8986416)
    Being a low-level programmer, and specifically working on advanced CGI, awhile back I bowed to pressure to offer some of my web clients scripting abilities on their servers. I went with PHP/MySQL and started the process of learning about the language and its caveats.

    The first thing that completely freaked me out was the register_globals setting in PHP. I invited a PHP programming friend to come hang out and give me a little intro-tutorial into how he developed so that I could understand where these guys were coming from when developing apps. He proceeded to show me this "neat feature" called register_globals that makes it super easy to access passed parameters from the outside world. Of course it also makes it super easy for anyone on the planet to overload internal variables that could be used just about anywhere in the scripts. I've never seen such a dangerous "feature" [in a non-Microsoft product].

    And this all ties into the number one rule of programming. When you're coming from C/C++, 80% of your job involves data/input validation, so it's second nature to cover your ass. I found myself very confused at first over the dozens of different functions available to escape, unescape, tokenize and otherwise mangle input from/to various forms. No wonder developers are confused.

    But above all, there are basic tenets that the server admin should enforce that have the most impact on security. First off, NOBODY should be enabling register_globals - it's just a crutch for crappy programmers IMO. Second, safe_mode is a must. If you have an app that needs safe_mode to be disabled, then you are better off isolating that app to its own private server. Third, every application should have its own private database work area. I am amazed at developers who run multiple applications in a single database space. Fourth, the configuration of the web server needs to be such that PHP code is properly protected, with .htaccess restrictions in code lib directories and careful consideration over other virtualhosts that might have php disabled in a higher-level directory.

    Safe_mode is a good tool. It also creates annoyances for the customers, especially those who are writing apps that create files in their work area... this requires the admin's intervention to set up the proper permissions (and gives them a chance to give the client code a once-over for glaring errors).

    One thing I haven't quite figured out, and maybe I just need the proper Apache mod, but when a PHP app creates a file, it's owned by the web process and not the script user process, so in safe_mode, to get things working you either have to change permissions or give liberal directory permissions in order for things to work with user-uploaded code.

    Ultimately, the server admin should bit the bullet and refuse to give users access to certain dangerous "features" such as register_globals or non-safe_mode. It's just too easy to open a Pandora's box.

Beware of Programmers who carry screwdrivers. -- Leonard Brandwein

Working...