What is the proper way of validating data? I mean say you have an insert function:
function newUser($name, $lastname, $age) {
// some validation process
$this->pdo->prepare("INSERT INTO user VALUES (?,?,?)",
array($name, $lastname, $age)); // this is another class
// that runs execute in itself
}
So basically, the question is whether the //some validation procecss part should take place in newUser function or should it be done outside the function? I am asking this because I am writing a request class which I will store basic validation rules in that class and automatically filter my get and post values. So if I do that, and if I also validate inside newUser (similarly on other functions like this) it means that I will validate the same input twice or maybe thrice.
So in short, is there anything wrong if I assume that variables that are passed to function newUser are already validated? In this case, I am also assuming that newUser is only called from my application (I am not sure whether a third party can also run the function without my permission, this is actually why I asked the question) and therefore the variables are already validated before having called the newUser function.
P.S: Sorry if the question is asked in a complicated way, just comment if you don't understand what I mean.
If I were you, i would make a validation class, this contains kinds of validation (for email, string, numbers, string and numbers).
Depending on what you want the vars in your function to be, validate them like that and put them in the database.
A third party shouldn't be able to run your function if you make sure you script safely.
Example how not to script:
include( $_GET['file'] );
Basically, I could put a own file to include in your system using the ?file parameter in your URL. Also with queries is this possible:
mysql_query( "INSERT INTO table (row) VALUES (". $_GET['value'] .")" );
You should always check parameters that can be accessed from outside of your scripts, so in your case making a new user, you would have to validate it in your new user function before you put it in your database.
It depends on how you are working. For example, if you were using the MVC pattern, the test should be done in the Controller (so not in the function you are using).
In your case you have to choose if you have to validate the data using a validation function (or maybe a method of a class) and then use the one you wrote to insert the data or to let this function to ensure them. I would suggest you the first solution so the "insert" function will achieve just one task.
Just to improve my answer, I suggest you to ensure the data at least for the SQL Injection and for the XSS (Cross Site Scripting).
Related
I want to understand why we need specific classes to work with Request and Response. What's wrong with global variables like $_POST, $_GET, etc...
Why is better and what's the problems it solves?
edit 1:
Thank you, I know about PSRs. But the real question why is it bad?
I don't think that the using $_GET, $_POST, etc is bad. Because why we would change its values?
As mentioned here :
The Request class is an object-oriented representation of the HTTP request message. With it, you have all the request information at your fingertips
and
As a bonus, the Request class does a lot of work in the background that you'll never need to worry about. For example, the isSecure() method checks the three different values in PHP that can indicate whether or not the user is connecting via a secured connection
I have an application with the following code:
<?php
if(isset($_GET['function'])){
$_GET['function']();
}
?>
So if i entered this url: http://localhost/?function=phpinfo
I will see the phpinfo function output on the screen.
can i have a way to concatenate 2 function in the url like this example:
http://localhost/?function=shell_exec('ls') AND phpinfo
So i want to see the first function output..
If you may asking why i need this, is because i am pen testing an web application with this situation..
By the way any suggestion to hack this situation will help.
Thanks for the help..
You cannot concatenate functions as it's not code injection per se, ie: you cannot affect the way the parser reads the code. Further more in the example you provided you have no control over any parameters passed to the function, so what you are proposing is not feasible.
You would have to find a way to pass control to a function which performs unsafe operations directly on user supplied input ($_GET, $_POST, etc) in order to leverage this weakness remote code execution. Depending on the complexity of the application you may be able to identify a function which calls system, eval, unserialize, or another dangerous function on user supplied data.
Background
I use .htaccess to redirect every URI to a single PHP file that displays the right page by calling different functions with different inputs based on the requested URI. I found myself checking user input twice. Once in the handling PHP file that checks first if everything is fine before calling the display function and than again within the display function, to make sure nobody exploits the function by calling it with wrong parameters (e.g. with the username of someone else). This means, that I need twice as many mysql querys etc. for checking valid inputs.
I can't just check within a function because based on those checks, the handling PHP file calls different functions. So I have to perform the checks at least there. But the more I think about it, the more I wonder, if it is necessary to check again within a function. I started this because I was worried that somebody might call one of my functions with improper input, but I guess if somebody can call one of my PHP functions and pass wrong parameters, I'm pretty much screwed already right? Because as far as I understand PHP, this would mean that this person already has access to my server at least via a shell or something like that.
I should further add, that I never ever call a function via a variable like discussed in this thread: Call PHP function from URL
Question
Is it a security risk, not to check the parameters passed to a function within that function, if you already checked it before the function call?
Good rule of thumb - Pretend EVERYONE is out to pwn your app! (Yes get out your tin foil hat!). Good practice would be to clean the data for example putting data in a database, you should still clean it coming back out of the database.
Unless you are in a position where one of your functions is providing the parameters and there is no way to access the (potentially insecure) function except through the preparation function then I would advise cleaning all data
HTHs - Thanks,
//P
Check out Private Public and Protected Functions
I'm relatively new to PHP, and I want to ensure I code as efficiently and as correctly I can - specifically, I'd like to ask about how functions should be implemented with each other and how large and how many tasks they each should do under optimal conditions.
Example
For the sake of an example (and possibly something I will need to implement), say there is link to a page which reads "forgotten your username/password?", upon clicking this link, they are brought to a page forgot.php, which has two forms on it:
1) If they've forgotten their password, they enter their username, and a link to a reset form is sent to their email address.
2) And another is if they've forgotten their username, they enter their email address, and this is sent to them via their email address .
Upon clicking submit, the relevant form is $_POST'ed to a new page called forgotsubmit.php, which checks if it is being accessed legitimately through an if statement:
//loggedIn() is a previously defined function
if (!loggedIn() && isset($_POST['forgotUsername']) || isset($_POST['forgotPassword'])) {
header('Location: index.php');
exit();
}
Otherwise, the page will run normally, and that is: start a function(s), and display a message telling the user to check their email. How I would implement/create the function(s) necessary for this to occur.
Possibility One - 1 function
Should there be a single, large, function that is called that can handle both forgotten passwords and usernames, through an if statement inside the function, then create a query fetching the relevant fields of data from a MySQL databse, organize and then strip_tags() all the data, send an email containing the necessary information, and then echo a success/failure back depending on what form was chosen and whether the code completed without errors?
Possibility Two - 2 functions
Have an if statement on forgotsubmit.php which determines which function to run - one to fetch a username, and another to reset the password, each doing what was described in possibilty one.
Possibility Three - a handful of functions
The same as possibility two, except a separate sendMail() function could send out the email, another function could handle the MySQL queries, etc.
Does calling too many functions slow performance? Is the (if any) performance loss made up by the time cost of not having to code sending mail twice, for example?
Possibility Four - dozens of functions, no functions, something else entirely?
Could I be using something better for a task like this? Would multiple functions be appropriate? I have heard of classes, but haven't looked into them, would they be appropriate?
Summary
I hope I have made myself concise enough. As I understand (or have read), the job of a function is to 'make repetitive processes simple', perhaps one of these possibilities would fulfill that task. How would you code it? Thanks.
It completely depends on the task on your hand. Its always better to have some functions like do_this(), do_that() instead do_all_stuff().
For me I follow a general rule. Each time I end up need a code block I wrote earlier, I convert it to a function. If you follow this rule, you'll end up creating lots of re-usable functions. Also the code will automatically be refactoring.
No matter what programming paradigm or language you're using, there's a good rule saying that a function should only do one thing. It makes your code more readable and easier to maintain, and has the additional benefit of allowing more code re-use.
Even though PHP was built for the web, one thing it lacks is a good architecture for building an entire web application. Out of the box, you get single file scripts that don't have any architected lines of communication with one another.
I highly reccomend using a framework. Zend Framework is a good choice, but there are dozens of others. The conventions they use will answer most of your questions, as they will outline what files need to be created, what functions go where, and give you a way to wire everything together.
Some frameworks:
Zend Framework
CakePHP
Code Igniter
Kohana
My partner on a PHP project objects my practice of always sanitizing integer values in dynamic SQL. We do use parameterized queries when possible. But for UPDATE and DELETE conditions Zend_Db_Adapter requires a non-parameterized SQL string. That's why I, even without thinking, always write something like:
$db->delete('table_foo', 'id = ' . intval($obj->get_id()));
Which is equivalent, but is a shorter version of (I've checked the ZF source code):
$db->delete('table_foo', $db->qouteInto('id = ?', $obj->get_id(), 'INTEGER'));
My partner strongly objects this intval(), saying that if $obj ID is null (the object is not yet saved to DB), I will not notice an error, and the DB operation will just silently execute. That's what has actually happened to him.
He says that if we sanitize all the HTML forms input, there's no way an integer ID can possibly get into '; DROP TABLE ...', or ' OR 1 = 1', or another nasty value, and get inserted into our SQL queries. Thus, I'm just paranoid, and am making our lives unnecessarily more complicated. "Stop trusting the $_SESSION values then" he says.
However, for string value conditions he does agree with:
$db->update->(
'table_foo',
$columns,
'string_column_bar = ' . $db->qoute($string_value))
);
I failed to prove him wrong, and he failed to prove me wrong. Can you do either?
Frankly, your partner is off his rocker: sanitizing is cheap, there's no good reason not to do it. Even if you are sanitizing what is in the HTML forms, if those checks somehow break on production, you'll be happy that you have a backup in other places. Also, it promotes a good practice.
You should sanitize—always
Which do you consider more trouble:
Having to track down a bug that didn't cause a failed SQL query.
Having to restore data after you make a mistake in sanitizing the form input and someone exploits that.
Whichever you pick, there's your answer. Personally, I tend to lean towards the paranoid side of things as well.
If anything, you could do both: create your own function that first checks for null and then calls intval(), and use that instead. Then you get the best of both worlds.
I think your partner is wrong - he is not considering separation of concerns between data sanatisation in the model (where your DB code lives) and data validation of your forms.
Normally your form validation logic will be in a separate area of the application to your model. I.e. when adding validators to form elements, and so this is often done in the form class itself. The purpose of this layer of validation code is to validate the input of the form and return the appropriate messages if there is anything wrong.
So I think data sanitisation in the model should be considered separately to this, as the Model is really a standalone class - and thus should be responsible for it's own data sanitisation. Since in theory you should be able to re-use this model elsewhere in your application, the model should not then assume that the sanitisation has been done elsewhere, i.e. as part of the form validation layer.
Your partners main point about not noticing failed SQL queries is not really an issue in practice - it is better to code defensively.
You should of course always sanitize and not rely on HTML forms. What if you change your code and reuse that part with some other data, that came not from HTML form but from webservice or email or any other source that you decide to add a year later? Using intval() here seems to be fine.
form input should idd always be sanitized, but not every variable that goes into a query should be sanitized imo...
The origin of the variable does play a significant role here.
You just have to know if the data used can be trusted...
If you look deeper inside the Zend framework code, you'll see that $db->quoteInto() turns into $db->quote which returns (string) intval($value) with INTEGER as type.
If type is undefined, $db->_quote() is called. Its code is following:
protected function _quote($value)
{
if (is_int($value) || is_float($value)) {
return $value;
}
return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
}
Whatever the calling method used (with or without specifying type), $db->delete is totally safe.
You should first check that the ID is not null. If it is, you know not to do a useless query and continue from there. It does not make sense to track down issues by reading failed SQL queries or so.
All data retrieved from a form should be sanitized. No exceptions. All data retrieved from your system should have already been sanitized before it got into your system, and therefore shouldn't be sanitized when retrieved from the system again.
So, the question is - where is this integer coming from?