December 4, 200817 yr I've currently got a page which includes an id on links like so: <a href="assignment.php?id=ass01>See assignment 1</a> <a href="assignment.php?id=ass02>See assignment 2</a> On the following page (and on any other page) I use GET to store the id as a variable. A friend is telling me that this is bad for security and that a POST function should be used instead to send the variable between pages. Is this right? If so, do I have to make every link a form and form button in order to use the post method? (If anyone wants to have a look at this in operation, let me know and I can post up the web address and sample login details to the section where it is)
December 4, 200817 yr um, your friend is miss guided... i see where he is coming from~ish... the ONLY difference is $_GET you can manipulate in the url but with $_POST it requires the hacker to have some brain cells [but not much]. it will NOT make any difference in the security other than making it convenient to manipulate your script. it dosnt matter what input type... if your server takes info and processes it your running a risk, the way to defend yourself is to validate all input. also on a practical note, using form navigation is a BAD idea, google wouldn't find your pages very well and also when the user presses the back button they would get a warning box and in google chrome they would see a white page telling them to hit refresh... obviously not something you want users doing!
December 4, 200817 yr As long as you're not passing that variable without sanitisation to a database or something along those lines, you should be ok. We'd be able to give you a better answer if we knew what the code on assignment.php was doing.
December 4, 200817 yr Author We'd be able to give you a better answer if we knew what the code on assignment.php was doing. http://www.numyspace.co.uk/~unn_p387495/ (username - s123456 password - test) Once in just click on ass01, ass02 to send the assignmentID through the URL The assignment.php code is along the line of: $assignmentID = $_GET['id']; if(!empty($assignmentID)) { do a query WHERE assignmentID = assignmentID }
December 4, 200817 yr I would change this: if(!empty($assignmentID)) to: if(!empty($assignmentID) && ereg("^[A-Za-z0-9]*$", $assignmentID)) so that $assignmentID HAS to be letters or numbers. This will help prevent SQL injection.
December 4, 200817 yr Passing through GET poses three risks (as I understand it): 1: If you pass important information (i.e: user id's, passwords etc) they are clearly visible in the URL 2: If you administer a query to a database without sanitising the input, it allows for a SQL attack - as the user can edit the variables through the URL (see Jem and Kelso's posts) 3: If the URL is corrupted in any way, and you haven't configured your error handling appropriately, it could cause the script to break and report an error - which could contain potentially sensitive information about your scripts or the server they're running on. GET is not 'secure', but it's still VERY useful to pass data between pages, especially considering it's application from an anchor. Just ensure you're using it appropriately.
December 4, 200817 yr 2 and 3 also apply so easily to POST too though, so they're not necessarily reason to avoid using GET... we need to be careful not to make it sound like switching to POSTed forms is the end to all security issues
December 4, 200817 yr Author Cheers for the input guys. I've read up on using POST by styling links as input buttons but instead I've: • Used GET to get the assID • Used trim to get rid of whitespace on the assID • Used substr to make sure the assID is exactly 6 characters long (i.e. $assID = substr($assID,0,6)) • Only allow the id to be used if it is all letters and numbers only (courtesy of Jem's ereg function). Otherwise it throws up an error message. That should make it secure enough shouldn't it?
December 4, 200817 yr • Used substr to make sure the assID is exactly 6 characters long (i.e. $assID = substr($assID,0,6)) Good thinking! strlen() would be quicker for that though Sounds like you've got all bases covered.
December 4, 200817 yr Most importantly... if your using that variable directly in a database query you should be escaping it first too! http://uk3.php.net/mysql_real_escape_string
December 5, 200817 yr Most importantly... if your using that variable directly in a database query you should be escaping it first too! http://uk3.php.net/mysql_real_escape_string If the query is restricted to purely letters and numbers, there's nothing to escape. I mean, it won't do any harm to use mres too, but it's not necessary.
December 5, 200817 yr There is still a security flaw, especially with the examples you guys gave above. Even if it is sanitized there is still another risk, the 3rd one sunwukung mentions. $assignmentID = $_GET['id']; if(!empty($assignmentID)) { do a query WHERE assignmentID = assignmentID } Yes thats good practice, but there is a tricky hacker trick to perform a FPD (Full Path Disclosure), a tricky hacker technique. An FPD is one of the first things a hacker will look for because it gives them more information about your site/script and also help with other methods of penetration. By setting up a url on your site like this: assignment.php?id[]=ass01 (see Empty Array on owasp) I could find out the full path of the script running on your server, very useful indeed. Never think you're safe
December 7, 200817 yr OK, here's another PHP security related question: It's general wisdom that you shouldn't pass data in the URL that will form part of a query executed in the target page (since this gives haxxorz an opportunity for SQL injection). However, can you safely pass a variable in a URL that will trigger a query, but none of the data in the URL forms part of the query itself? In short, can you safely hit the DB off a $_GET?
December 8, 200817 yr There is still a security flaw, especially with the examples you guys gave above. Even if it is sanitized there is still another risk, the 3rd one sunwukung mentions. [..] Yes thats good practice, but there is a tricky hacker trick to perform a FPD (Full Path Disclosure), a tricky hacker technique. An FPD is one of the first things a hacker will look for because it gives them more information about your site/script and also help with other methods of penetration. By setting up a url on your site like this: assignment.php?id[]=ass01 (see Empty Array on owasp) I could find out the full path of the script running on your server, very useful indeed. Actually, you're wrong. FPD only works if the GET query is being used to include a page. This GET query string is only being used in a MySQL statement (in the code sample provided). Never think you're safe And never spread FUD just for the sake of looking cool.
December 8, 200817 yr However, can you safely pass a variable in a URL that will trigger a query, but none of the data in the URL forms part of the query itself? In short, can you safely hit the DB off a $_GET? So, I think what you're asking is something like.. if isset GET['bla'] and GET['bla'] == foo do query one else do query two ..where neither queries use info from the URL? In that case, there's no obvious security risk I can think of off the top of my head, although you'd want something there to prevent someone just madly refreshing and knocking up loads of queries IMO.
December 8, 200817 yr Didn't think so - I'm building my first PHP specific site to consolidate what I've learnt over the past few months. Nothing like a real project to burn stuff in. I use a views counter to redirect the page after a set number of refreshes.
December 10, 200817 yr when Im using $_GET I always try and make sure the $_GET is an integer. Then you can force int it like below : $id = (int)$_GET['page_id']; if($id == 0 || $id < 0){ header('Location : /error.htm'); } //if int is less than or equal to 0 take them to an error page //do what what you want with the ID
Create an account or sign in to comment