Common Mistakes (AKA How to Not Get Your Shit Fucked Up)
38 replies, posted
[b]Due to the shitstorm caused by Hacksore below the OP, I'll just move anything relevant to the OP in order to maintain some form of order and coherence.[/b]
Due to laziness and a tight timeframe, this'll be updated as we go along, I'll throw two of the most important ones down now.
[b]SQL[/b]
First and foremost, [b]SQL Injection[/b]. About 50% of the code through the WebDev forums regarding SQL databases is injectable. The other 50% comes from people like nivek, KmartSqrl, [noparse]:awesome:[/noparse] and turb_ (RIP turb_ :v:).
Protips on defending against SQL Injection:
Let's say you're already connected to the DB, and you're wanting to insert variable $content into your custom comments database.
[code]
mysql_query("INSERT INTO comments (author, content) VALUES ('$author', '$content')");
[/code]
This code is injectable. I'm not going into what that means, you can use the power of Google for that. What you can do is fix it by simply adding some damn precautions:
[code]
$author = mysql_real_escape_string(htmlspecialchars($author));
$content = mysql_real_escape_string(htmlspecialchars($content));
mysql_query("INSERT INTO comments (author, content) VALUES ('$author', '$content')");
[/code]
Of course if you're writing OO, you'll be writing a slightly different syntax. But in reality if you're writing it that way, you wouldn't be making that mistake.
[b]XSS[/b]
Not only is SQL injection preventable that way, but if you're displaying stuff on a page, it can be useful too. The second function in the 'sanitization' of the author and content variables is htmlspecialchars(). This removes special HTML characters such as '<' and '>' (which are used for tags, obviously), lessening the possibility of [b]XSS (Cross-Site Scripting) Injection[/b]
[b]Cross Site Request Fraud[/b]
[url=http://www.facepunch.com/showthread.php?1013645-Common-Mistakes-(AKA-How-to-Not-Get-Your-Shit-Fucked-Up)&p=25415809&viewfull=1#post25415809]Post #18 (X'Trapolis)[/url]
This one seems rather innocuous at first, and not many people tend to consider it. However, it can be as dangerous as XSS.
A CSRF attack is where an attacker is able to make a user perform actions on another site by using techniques to forge a request.
An example would be Facepunch's ratings system (has since been fixed). An attacker could force anyone viewing a post to submit a rating for another post simply by img tagging the rate URL. This took advantage of two vulnerabilities: Firstly, a mutable action (one that mutates, or changes, state permanently) was able to be performed via GET. This allowed the img tag exploit, and violates the HTTP spec which stipulates that all GET requests should be idempotent. Secondly, the rating script did not require a one-time, unique security token to be sent along to authorize the rate. This would have foiled the img exploit as there would be no way for an attacker to craft a URL containing this randomly generated token.
CSRF is easily mitigated by a combination of the following:
Only allow GET requests to be idempotent. That means they should ONLY be used to retrieve content or data. Any action that modifies state should use the POST method.
Insert a randomly generated security token in forms that mutate data. This must be checked when the form is submitted to the server. If you're using a framework like ASP.NET or Rails, it'll do this for you if you ask it.
At the very least check the Referer header, although it isn't the most reliable source. Security tokens are preferred to this.
Again, more will be added as I go along. Feel free to contribute anything, but please [b]DO NOT ASK QUESTIONS IN HERE.[/b] This is a general reference for the newcomers.
[b]Edit:[/b]
[QUOTE]Dumb x 1
Erp[/QUOTE]
Surprise surprise.
I might also pitch in that using paramterized queries (ala. [url=http://php.net/manual/en/book.pdo.php]PDO[/url] in PHP) is better than escaping input in nearly every way.
It completely separates data from code, which make it virtually foolproof.
-snip-
[QUOTE=hacksore;25396160]I like this but you should explain what SQL injection is. So i will help you out xD. SQL injection is where you use htmlmarkup characters in conjunction with SQL query functions to modify the SQL query. I think since this thread is about making things secure, so i will show the most common method.
Ex:
[code]' OR ''='[/code]
This can modify a query for a login. This is possible because you can change what the query calls. Most cases you leave the username blank and use that injection i have shown for the password. If you do this it will basically say if the user name is blank and the password is nothing, then login. This will log you in as the first person in the SQL database.
Now do not expect to rush staight to Myspace or Facebook and try this method as almost every major website will not allow this. Mostly because they use javascript to check both fields or have implemented a full proof system that the OP was mentioning. Since injecting requires the ' symbol to work. Using the htmlspecialchars to replace them, the ' charecter becomes '''
I hope this will shed a bit more light on this for any beginners.[/QUOTE]
While I can see that your intentions are all well and good, you're horribly mistaken in what SQL injection is, and how to prevent it.
One of the [b]golden[/b] rules of web development is to [highlight]never trust the client[/highlight]. This means Javascript validation for anything other than convenience (in not having to make the user wait for a postback to the server to see they made a typo) goes right out the window.
Also, SQL injection means inserting SQL code into a query where input isn't being escaped, not HTML. HTML encoding isn't going to help here either. Ideally you want to be using parameterized queries, or failing that, encoding-aware escaping.
-snip-
[QUOTE=hacksore;25396350]Just because i did not word it the way you did does not mean it is wrong. Since that is essentially what you are doing. Also I'm referring to the set of characters found [url=http://php.net/manual/en/function.htmlspecialchars.php]here[/url].[/QUOTE]
I tried being polite, but you are dead wrong. SQL injection has absolutely NOTHING to do with HTML. At all. Not in the slightest.
htmlspecialchars() is not suitable for preventing against SQL injection.
-snip-
[code]mysql_query("INSERT INTO comments (author, content) VALUES ('$author', '$content')");[/code]
Alright, the only result on google gets me back here.
Why not just explain it?
[QUOTE=hacksore;25396431]I doubt you could prove it. If you were to use ' while using htmlspecialchars() it would produce an SQL error.[/QUOTE]
An SQL error is exactly what you don't want. That means that the attacker has successfully injected code into your query if MySQL throws a syntax error.
Besides, you don't need to use ' to pull off an SQL injection.
-snip-
Can we please not turn this thread into a shitstorm? I was trying to do something beneficial for the whole of the WebDev section. Shut the fuck up, all of you.
Hacksore, X'Trapolis actually makes decent websites. Better than I can, anyway. Get out.
Sir Whoopsalot, because if you had an IQ higher than your weight printout, you'd realise you're meant to Google "SQL Injection".
-snip-
[QUOTE=hacksore;25396540]By decent website do you mean this one?
[url]http://putmyfileshere.webs.com/pawsnclaws/index.html[/url][/QUOTE]
[QUOTE=supersnail11;25380601]I'm bored, so i'll try it...for non-profit(free)!
(Just don't count on a result)
[editline]13th October 2010[/editline]
Well, it's not the best out there, but (no offense) it's better than the last one:
[url]http://putmyfileshere.webs.com/pawsnclaws/index.html[/url][/QUOTE]
That's not his, what's wrong with you?
Shut up and get out of the thread, you're causing a shitstorm.
[QUOTE=Qombat;25396528]Can we please not turn this thread into a shitstorm?
Sir Whoopsalot, because if you had an IQ higher than your weight printout, you'd realise you're meant to Google "SQL Injection".[/QUOTE]
Hypocrite much? Excuse me for being a complete and utter newb to this and asking something.
But yeah, did some more searching. If I'm not mistaken, it allows you to add an entry to a database without the owner's permission?
[QUOTE=hacksore;25396540]By decent website do you mean this one?
[url]http://putmyfileshere.webs.com/pawsnclaws/index.html[/url][/QUOTE]
I suggest you [url="http://www.facepunch.com/showthread.php?1011080-30-Need-a-web-designer-for-non-profit&p=25380601#post25380601"]read the thread better[/url].
[editline]18:19[/editline]
Wait, you even posted in that thread. Anyway, let's keep this on topic. Thanks for the thread Qombat, this will be a good point of reference for people starting out.
Too bad that you can't really do any harm in PHP via MySQL injection unless you're capable enough to get someone's password.
[editline]14th October 2010[/editline]
(PHP only allows one query executed at a time.)
Awesome how hacksore snipped his posts.
Here's another one; [b]Cross Site Request Fraud[/b].
This one seems rather innocuous at first, and not many people tend to consider it. However, it can be as dangerous as XSS.
A CSRF attack is where an attacker is able to make a user perform actions on another site by using techniques to forge a request.
An example would be Facepunch's ratings system (has since been fixed). An attacker could force anyone viewing a post to submit a rating for another post simply by img tagging the rate URL. This took advantage of two vulnerabilities: Firstly, a mutable action (one that mutates, or changes, state permanently) was able to be performed via GET. This allowed the img tag exploit, and violates the HTTP spec which stipulates that all GET requests should be idempotent. Secondly, the rating script did not require a one-time, unique security token to be sent along to authorize the rate. This would have foiled the img exploit as there would be no way for an attacker to craft a URL containing this randomly generated token.
CSRF is easily mitigated by a combination of the following:
[list]
[*] Only allow GET requests to be idempotent. That means they should ONLY be used to retrieve content or data. Any action that modifies state should use the POST method.
[*] Insert a randomly generated security token in forms that mutate data. This must be checked when the form is submitted to the server. If you're using a framework like ASP.NET or Rails, it'll do this for you if you ask it.
[*] At the very least check the Referer header, although it isn't the most reliable source. Security tokens are preferred to this.
[/list]
If i'm not inserting anything, just selecting, can the code still be injected?
[QUOTE=supersnail11;25421518]If i'm not inserting anything, just selecting, can the code still be injected?[/QUOTE]
If you are working with any variables that can be modified by the user in any way, it's injectable.
Lol you have to protect PHP from SQL injection and XSS.
Django does this shit for me; it's so nice.
[QUOTE=PvtCupcakes;25422181]Lol you have to protect PHP from SQL injection and XSS.
Django does this shit for me; it's so nice.[/QUOTE]
Django isn't a programming language, it's a framework. You can get PHP frameworks that do this for you aswell.
[b]Basic PHP Settings[/b]
There are a few settings that you definitely want to check in your php.ini file. These are typically set by the hosting provider if you use shared hosting and in general make PHP a much safer environment to work in. However, if you're running a VPS (or a dedicated server), you would probably want to check these values since you'll most likely be setting up PHP manually:
[code]
safe_mode = off ( a lot of shit cannot be done with this on )
disabled_functions = N/A ( no one, we want all )
allow_url_include = on ( for lfi/rfi )
allow_url_fopen = on ( for lfi/rfi )
magic_quotes_gpc = off ( this will escape ' " \ and NUL's with a backslash and we don't want that )
short_tag_open = on ( some scripts are using short tags,better on )
file_uploads = on ( we want to upload )
display_errors = on ( we want to see the script errors, maybe some undeclared variables? )
[/code]
[b]Remote File Inclusion[/b]
Remote file inclusion is a result of improperly filtered or managed user inputted fields. It can happen when an attacker uses a NULLBYTE or the ? trick.
As of PHP 4, you can use the following function to include external code: require(), require_once(), include(), include_once().
Basic Example:
[code]
<?php
include($_GET['page']);
?>
[/code]
The above code is vulnerable to including [i]any[/i] external files. If you do this, you are leaving a huge security hole. [i]You absolutely need to remove this[/i].
Extended Example:
[code]
<?php
include($_GET['page'] . ".php");
?>
[/code]
So, you've updated your code, and this makes a little improvement over the last one. This will try to include a file with the provided name and extension of ".php". Unfortunately, this is still susceptible to the nullbyte trick where you place a %00 after that included file and PHP discards the rest of the file URL.
Fixing This Problem:
The absolute easiest way to go about fixing this is to make sure the file exists or make it relative to the current directory when you include it. Another issue is the fact that people are able to get access to the file /etc/passwd. This can compromise passwords that are located on your system and leave you vulnerable to attack. You must take both into consideration when you're working with including files.
[code]
<?php
$relativeDirectory = "./";
$_GET['page'] = str_replace("/", "", $_GET['page']);
if(file_exists($relativeDirectory . $_GET['page'])){
include_once($relativeDirectory . $_GET['page']);
} else {
echo "Page Not Found";
}
?>
[/code]
The above would fix any problems with a file being included externally, as well as an attacker trying to compromise local files.
[b]Cross-Site Scripting[/b]
Cross-Site Scripting (XSS) is typically used in order to gain access to victim's account credentials. This typically happens when code is included via parameters that are passed to PHP. XSS typically isn't "included" per say but will affect the page the viewer sees.
Basic Example:
[code]
<?php
echo "Welcome, " . $_GET['name'];
?>
[/code]
One of the major ways this is susceptible is by including JavaScript. The following would alert you with a message that your website has been compromised. http://example.com/xss.php?name=<script>alert("xss");</script>.
Now, there is no definite fix for XSS, however there is a lot that you're able to do in order to protect yourself from XSS attacks. The following code would almost remove the possibilities of an attack:
[code]
<?php
echo "Welcome, " . htmlentities($_GET['name']);
?>
// or
<?php
echo "Welcome, " . htmlspecialchars($_GET['name']);
?>
[/code]
That's all for now. I'll post more when I get a chance since I'm currently working on a couple projects and I need to finish them this weekend. Hopefully I'll be able to post about cross site request forgery, etc.
Couple things,
Why are you switching register_globals on? Surely that's a security risk.
Secondly, you can defend against L/RFI by using the realpath() function and making sure that the root directory you want to serve is in the string returned by realpath()
WHAT A PERFECT EXAMPLE OF SQL INJECTION.
[IMG]http://costeira.com/upl/uploads/conservatives.PNG[/IMG]
[QUOTE=X'Trapolis;25424208]
You can defend against L/RFI by using the realpath() function and making sure that the root directory you want to serve is in the string returned by realpath()[/QUOTE]
There are many solutions to one problem.
[img]http://ahb.me/Kid[/img]
:colbert:
Trust Erp.
Gotta love PHP injection. I wish I could access as admin on the prime minister's website and put porn all over the main page.
Here's a nice article on security tokens with PHP: [url]http://phpsec.org/projects/guide/2.html[/url]
Sorry, you need to Log In to post a reply to this thread.