cbassett03 Posted September 28, 2012 Share Posted September 28, 2012 (edited) This is probably a broad question, but is there a way that I can prevent (or greatly reduce) code injection via someone typing in "parameters" into their address bar against a PHP script? For example, preventing something like the known "1=1" injection that causes MySQL to return all values in a table. Should I explicity check each variable to make sure it doesn't include "1=1" or something similar that would cause the database to return everything? I'm aware of htmlentities() function in PHP. Just as an FYI, I generally send most of my data from HTML forms using the POST method, partially so the data and parameters are not shown to the user during transmission. Any suggestions, or sites, that discuss PHP security? (I'd consider myself an intermediate PHP programmer at this point--I know my way around the language, but am getting more concerned with security as I move away from personal projects and into more "real-world" projects.) Edited September 28, 2012 by cbassett03 Quote Link to comment https://forums.phpfreaks.com/topic/268870-prevent-code-injection-from-url/ Share on other sites More sharing options...
Christian F. Posted September 28, 2012 Share Posted September 28, 2012 (edited) What you're talking about is input validation, but by the way of blacklisting. While input validation is necessary, doing so with a blacklist is not; You can never know every single instance of "bad" data, and even if you did it would be next to impossible managing the list every time a new attack form was found. The better way to go about it is via white-listing, namely to allow only content you know is legal. Something which requires that you know exactly what kind of input you're getting, and all possible permutations of said content. Still quite a bit to keep track of, but far easier to manage than "everything bad", and the good list rarely changes. To set up such a list you'll first and foremost need to sit down and formulate a rule for what you want to declare legal content, then you need to translate these rules into Regular Expressions1 or use the ctype_* () functions. Now, since some of the good data might still pose a risk to external systems2 you still need to escape the output. This is done with the appropriate method for the target system, and only right before you send the data to said system. Plenty of examples on this forum how to escape output, and as such a search is recommended. For sites and places that discuss security, we got one right here. Check the signatures of the Gurus and the other staff, quite a few of them have links to really good articles in them. 1 For some reason the forum software mangles "Expressions", thus foiled my attempt at making this link: http://www.regular-expressions.info/ 2 Such as database engines, web browsers, e-mail servers/clients, and so forth. Edited September 28, 2012 by Christian F. Quote Link to comment https://forums.phpfreaks.com/topic/268870-prevent-code-injection-from-url/#findComment-1381505 Share on other sites More sharing options...
Psycho Posted September 28, 2012 Share Posted September 28, 2012 Just as an FYI, I generally send most of my data from HTML forms using the POST method, partially so the data and parameters are not shown to the user during transmission. There is no difference between POST and GET data from a security standpoint. Do not thing that because the user does not see the value in the query string that they cannot modify the data. If you have a select list - do not assume that the value passed for that field was one of the ones that you defined for the list. Do not assume that a value you put into a hidden field is not going to be modified by the user. It is very easy for someone to create a modified form to send whatever data they want. There are some tricks that I've seen used to try and prevent form submissions from external sources, but that only adds complexity with no real benefit. There are free tools available that allow a user to 'trap' http data being send from their computer and modify it before continuing on to the web server. You need to validate and sanitize ALL data coming from the user: POST, GET, COOKIE, etc. Don't trust any of it. There is no way to cover absolutely every aspect of what you need to consider. You just need to stop and think about HOW each piece of data will be used and what you should expect the value to be. Here are some examples of the things I would consider: With a select list the displayed label typically corresponds to an ID which will be the actual value passed and it is very common for that ID to correspond to an auto-increment integer in the DB. For any values that should be a integer ID you should always check for an integer or force the value to be an integer. Again, it depends on how it will be used. SCENARIO #1 If the value is used to SELECT some data from the database (e.g. a search/filter) I may just force the value to be an integer by typecasting it as such or using intval(). If the value isn't even a number it will typically be converted to a 0. Auto-increment IDs always start as 1 by default. So, if the value is converted to a 0 (or some other integer that doesn't exist in the DB) then the worst that would happen is that the user would get no results or possible some invalid results - but since they purposefully tried to cheat the system I find that acceptable. SCENARIO #2 Ok, let's say the value is used to SELECT data as above - but the ID is in a list of approved values that the user can select. In other words, there are values we don't want the user to be able to select. In that case (after forcing the value to an integer) I would want to do one of two things. 1) I could verify the value first by running a query to see if the passed value is in the list of approved IDs for the user. Or 2) I could adjust the query used to search the data to do that verification internally. I'm sure there are better ways, but here is a quick example: Instead of this SELECT * FROM data_table WHERE id = '$submittedID' You could use this SELECT * FROM data_table JOIN approved_ids ON data_table.id = approved_ids.id AND approved_ids.user = '$thisUser' WHERE id = '$submittedID' Again, if the user submitted a non-approved ID then they just wouldn't get a result SCENARIO #3: Lastly, let's say that the value passed is used in the creation of a record, the value is required for the records and you must ensure it matches one of a list of existing IDs. For example, the record is for a car and the field is to select the make of the car. Then, in addition to checking or forcing it to be an integer you would want to do a DB check on the value to verify it is in the list of available IDs for makes of cars before trying to insert the record. All of the above is just "off the top of my head" thoughts and does not represent everything to be considered or all possibilities. It is only meant to provide some advice on the thought process you would go through to determine what the right process is for your particular needs Quote Link to comment https://forums.phpfreaks.com/topic/268870-prevent-code-injection-from-url/#findComment-1381554 Share on other sites More sharing options...
Christian F. Posted September 28, 2012 Share Posted September 28, 2012 Forgot to mention Sverre H. Huseby's excellent book "Innocent Code". An absolute must-read for anyone working with web development, either as a hobby or professionally. Quote Link to comment https://forums.phpfreaks.com/topic/268870-prevent-code-injection-from-url/#findComment-1381579 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.