homepage Welcome to WebmasterWorld Guest from 54.145.183.169
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Top 25 Most Dangerous Programming Errors
Applicable to wide range of technologies
benevolent001

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4091322 posted 11:01 am on Mar 4, 2010 (gmt 0)

The 2009 CWE/SANS Top 25 Most Dangerous Programming Errors is a list of the most
significant programming errors that can lead to serious software vulnerabilities.


Since web is all about interaction of various different web components , a look at following list would be great for making safe web applications.

Some of errors are

    Improper Input Validation
    Improper Encoding or Escaping of Output
    Failure to Preserve SQL Query Structure ('SQL Injection')
    Failure to Preserve Web Page Structure ('Cross-site Scripting)
    Cross-Site Request Forgery (CSRF)
    Client-Side Enforcement of Server-Side Security
    Improper Access Control (Authorization)
    Hard-Coded Password
    Use of a Broken or Risky Cryptographic Algorithm

[cwe.mitre.org ]

 

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 1:52 pm on Mar 4, 2010 (gmt 0)

Very nice find. I figure that even though they propose the general solutions, most of which aren't actually geared towards web applications, that we could give the solutions right here in the thread as sort of a repository of security techniques used often when writing web applications in PHP.

I'll start...

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 1:58 pm on Mar 4, 2010 (gmt 0)

Improper Input Validation

It is essential to validate all input from an outside source. Most of the time this will be input you get from a web form, but this also includes URL variables, data from a database, flat-file system, FTP connection, et cetera, as there is no way to be sure that what you are expecting is what you are getting.

When checking for a specific type of input, you want to be as specific as possible and deny all of the ones that don't match your specification. So, for instance, if you want to make sure that a user inputs an integer, you check to see if the value is an integer, and if not, you prompt them -- however you choose -- to re-input the value in (or in the case that no user inputted directly, you create an error message). PHP example:

<?php

if(!preg_match("/^[0-9]+$/", $userInput))
 // prompt user to input again

?>

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 2:09 pm on Mar 4, 2010 (gmt 0)

Improper Encoding or Escaping of Output

This isn't as big of an issue IMO than some of the other ones in there (at least for web programming) but there are two ways to look at this one.

On the first hand there is output to the browser. Now as far as encoding goes using the wrong encoding might make some characters appear differently than what they should look like in the browser. Not that huge of an issue just the user may have trouble reading the output to the screen. I'm not going to talk about XSS in this part because there is a whole topic dedicated to that, so I'm just going to stick to encoding in general. So make sure that whatever you are using, you properly specific the character encoding, usually in the form of a meta tag in the head of your HTML document:


<meta http-equiv="Content-Type" content="text/html; charset=utf-8">


On the other hand there is encoding the output in places such as your database queries. Since MySQL, an other DBMS, allow you to specific the character encoding, you must make sure that the query you are generating abides by your encoding and that unexpected results do not occur. If they happen to occur, it may be possible for an injection to take place (the topic of another post!). Sometimes it helps with this to use stored procedures.

jdMorgan

WebmasterWorld Senior Member jdmorgan us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4091322 posted 2:31 pm on Mar 4, 2010 (gmt 0)

It's hard to tell exactly what they meant by "Improper Encoding or Escaping of Output," but as long as Web coders abide by the philosophy implied by your above post on input validation, then output encoding for input to a script or database should not be so much of a problem.

The basic philosophy for input validation must be, "specify what you are willing to accept, rather than trying to reject what you are not willing to accept."

While these two approaches may initially seem to be mirror-images of each other, the consequences can be quite different if you forget to include something in each method's "list" -- If you forget to include something in your "accept" list, then you'll find that problem early-on in the debug stage. If you forget to include something in your "reject" list, then you may not find that error until you're investigating a successful hack.

Jim

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 2:33 pm on Mar 4, 2010 (gmt 0)

Failure to Preserve SQL Query Structure

SQL injection is a problem that I see many new members have issues with simply because they do not know about it, or the ways to protect against it. If you do not know what SQL injection is, I suggest reading about it real quick before continuing: [en.wikipedia.org...]

There are really two ways of approaching the prevention of such attacks, so I will start with the easiest first, character escaping. In PHP this is now done with mysql_real_escape_string() (opposed to mysql_escape_string which does NOT account for the database character encoding). Simply put, you must escape your query parameters before you add them to the query. Example:

<?php

$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",
     mysql_real_escape_string($Username),
     mysql_real_escape_string($Password));
mysql_query($query);

?>
Taken from the wikipedia page because I'm lazy

You can see here that before the parameters are part of the query string, they are escapes of "bad characters" that could have potentially been used in a SQL injection, but most of the time it is common to have those characters in there and they are part of regular user input, but they still must be escaped to correctly work.


The second method to protect against this is to use parameterized or prepared statements. This is the act of binding query parameters to variables. This makes the query string static so that it cannot be injected. With PHP this is commonly done with the PDO database layer or the MySQLi extension. An example of the latter is here:

<?php

$db = new mysqli("localhost", "user", "pass", "database");
$stmt = $db -> prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();

?>
Taken from the wikipedia page because I'm lazy


As a note, this step should always be taken after validating the user input as in my first post. This is layered security here. The more passes at validation and escaping the variable goes through, the less chance that something dirty got through and will cause problems for you down the road.

[edited by: eelixduppy at 2:47 pm (utc) on Mar 4, 2010]

Brett_Tabke

WebmasterWorld Administrator brett_tabke us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4091322 posted 2:42 pm on Mar 4, 2010 (gmt 0)

First off - fascinating document - worth a read by every programmer and is not PHP specific.

> Improper Input Validation

Agreed, tainted variables are the single most important issue for programmers today. It is the number one way that servers get compromised. It is how 90% of all malware ends up on servers. That happens through any method that code can be injected into the system. The list is long, but the big offenders are; MYSQL injection and system level params being passed to ultimately launch shell processes. One famous forum recently suffered a major error because people were able to upload graphic files with arbitrary filenames. Those filenames were injected with system level commands and executed by the forum itself when saving the file.

> Improper Encoding or Escaping of Output
> This isn't as big of an issue IMO than some of the other ones in there

Oh, there are quite a few cross site scripting errors out there that exploit unescaped form values. Go read the full article. It talks about a couple encoding errors that lead to injection attacks.

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4091322 posted 8:01 pm on Mar 4, 2010 (gmt 0)



if(!preg_match("/^[0-9]+$/", $userInput))


Not picking on you, honest. :-) True this will match on an integer, but in a working scenario unless there's a possibility "$userInput" will be zero, just as easily validated by

if ((! $userInput > 0)) {

I think for PHP coders this one's pretty important, as well as rampant:

Error Message Information Leak

If you have error reporting on, the first thing that happens in an error condition is the server path gets revealed . . .

[You screwed up] at line 285 in /var/www/hosts/example.com/httpdocs/script.php

Second is this.

msql_query($select) or die(mysql_error());

Which can not only reveal server path info but also database structure. Both of these are very convenient but they are also very deadly.

// Change to 1 ONLY when debugging/developing
$show_err=0;
msql_query($select) or error_func("Cannot execute query at some marker", mysql_error(), $show_err);


// $report_flag determines whether or not to display
// mysql errors. A case where you would allow it,
function error_func($generic_err,$db_err,$report_flag) {
header("Content-type:text/html");
echo $generic_err;
if ($report_flag==1) { echo $db_err; }
exit;
}


The previous gives the legitimate user enough info to pass along to you so you can fix it, but not enough to snoop your system.

I had to LOL at . . .

The implications are obvious: all your code are belong to them.

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 9:38 pm on Mar 4, 2010 (gmt 0)

Failure to Preserve Web Page Structure

This is one directly related to cross-site scripting (XSS) attacks mostly. Just as it is important to verify your input data before you use it, it is equally as important to make sure that your output does not contain anything that could be potentially harmful.

When printing anything to the browser that may contain data from an outside source (as defined in my first post about validating input) you must make sure it is going to be printed as expected, and not taken as actual code as part of the webpage. This type of injection is probably the most prevalent on websites today, because most people do not sanitize their output.

But to properly sanitize data before you put it to the browser, you should at least do the following:
<?php

echo htmlentities($message, ENT_QUOTES, ’UTF-8);

?>

Where the htmlentities function even allows you to specify the character set you are working with to make sure that the characters that should be converted to their entity form actually do so.

More here: [php.net...]

fedem

5+ Year Member



 
Msg#: 4091322 posted 7:16 pm on Mar 8, 2010 (gmt 0)

@eelixduppy thanks for sharing this info. Bookmarking right now ...

eelixduppy

WebmasterWorld Senior Member eelixduppy us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 4091322 posted 9:00 pm on Mar 8, 2010 (gmt 0)

Hard-Coded Password

It is generally the case that if a password needs to be included in the script that it be stored ABOVE the web root directory meaning that it cannot be accessed publicly. This is usually the case when it comes to MySQL usernames and passwords. Also, when using a hard-coded password note that anyone who has access to the code also has access to the credentials that you are hiding from the outside world, so it is best to set up a user (if we're talking about databases) that has only very limited privileges, just to do what they need to do and nothing more. On most dynamic websites this is UPDATE and SELECT and rarely anything more.

joelgreen

5+ Year Member



 
Msg#: 4091322 posted 8:48 am on Mar 9, 2010 (gmt 0)

if ((! $userInput > 0)) {

not so safe as it will accept following

if (("123 abc \hackme" > 0)) echo "oops";

graeme_p

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4091322 posted 4:17 pm on Mar 10, 2010 (gmt 0)

It is generally the case that if a password needs to be included in the script that it be stored ABOVE the web root directory meaning that it cannot be accessed publicly. This is usually the case when it comes to MySQL usernames and passwords.


A LOT of PHP CMSs put the DB password within the web root by default.

Brett_Tabke

WebmasterWorld Administrator brett_tabke us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4091322 posted 4:43 pm on Mar 11, 2010 (gmt 0)

Here is a great thread on PHP security from 7 years ago:
[webmasterworld.com...]

Rune



 
Msg#: 4091322 posted 6:23 pm on Mar 14, 2010 (gmt 0)

The #1 error should be "not backing up a database".

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved