I have a bit of code which checks 2 $_GET variables with preg_match. It also looks up one variable value in the database. The problem is that the email address which is url encoded and the # symbol is replaced with %40 is not turned back into readable text when I call the variable.
So if I call $_GET['email'] the value displayed is someone%40example.com while it should be someone#example.com
I understand $_GET variables get decoded automatically but it is not working for me. This problem came with the installation of SSL on this domain. Could it have something to do with that?
Here's my code:
if (isset($_GET['Email']) && preg_match('/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*#([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/', $_GET['Email'])) {
$Email = $_GET['Email'];
}
U need to put urldecode()
$_GET variable doesnot get url decoded automatically. You have to do it manually.
Do something like this
if (isset($_GET['Email']) && preg_match('/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*#([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/', urldecode($_GET['Email'])))
{
$Email = urldecode($_GET['Email']);
}
Also, this is not the proper way of validating email
Check your content-type header you are sending. If you are submitting a form, then I you should probably be using application/x-www-form-urlencoded type in your form to tell PHP that the data is URL-encoded and should be automatically decoded. That is unless you are submitting a file upload, in which case multipart/form-data is appropriate and may require manual decoding of content (using urldecode() depending on how it is actually sent. You can inspect $_SERVER['CONTENT_TYPE'] to help you programatically determine whether you need to manually decode.
A few other pointers:
You should probably consider using POST here instead of GET unless your expectation is that this would be a navigable page/or endpoint tied to that email address (i.e. something someone could bookmark). Think for the GET action is reading something from a location specified by the query string and POST as being related to making some specific action related to the POSTed data.
You should consider using filter_var() or filter_input() along with the email validation filter instead of regex.
Suggested usage would be:
$email = filter_var($_GET['email'], FILTER_VALIDATE_EMAIL);
if(false === $email) {
// validation failed
}
// or
$email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);
if(is_null($email) {
// key was not present in GET params
} else if (false === $email) {
// validation failed
}
Related
I have an iPad app that sends data to a PHP page using a post with body method and this works fine. On receiving this data the PHP page sends a notification email with some of the information from the body.
For one user I am getting this:
For some reason the for this user the app does not send the id or email and the body string looks like:
id=&posted_by=admin&email=
The reason for no id or email obviously needs to be fixed but in the meantime I am trying to catch this occurrence in the php page using:
if ($_POST['id'] == '' OR $_POST['id'] === NULL) {
.... do something...
}
However, this does not work. What would the value of $_POST['id'] be if its value had not been included in the body?
The value of $_POST['id'] will be a warning unset variable id when it does not set in the body.
Before getting the value of $_POST['id'] you should use isset() function as:
if(isset($_POST['id']) && !empty($_POST['id'])){
// do something
}else{
// else part
}
Note: If you have no idea which type of method used to send data then you should use $_REQUEST['id'], it works for both GET and POST methods.
I am just starting PHP and have a form where users can submit data. Before I display or send the data, it is sanitized and validated (trim, stripslashes, and htmlspecialchars) and saved as new variables which are then used instead of the directly submitted values.
My question is, is it safe to do anything at all with the unsanitized values? Do the security implications only become apparent when the values are displayed?
Specifically, would there be any problems with doing code such as
if(empty($_POST["theirname"]){code;}
if they tried some kind of attack or placed code into that box while submitting?
Currently I sanitize all input before checking if they are empty, but I want to avoid errors/warnings in this case if a user submits a blank box for example (as the sanitizing function could be called on POST values that don't exist)
PHP's filter_* functions. They're functions that do sanitizing for every variable you have, be it server variables (like $_SERVER, $_GET, $_POST, $_REQUEST) or your own variables.
Since you want to sanitize $_POST, here's what you should use:
$theirname = filter_input(INPUT_POST, "theirname");
if (!$theirname) {
echo "theirname is invalid!";
} else {
// your code
}
filter_input can check if the variable exists, if it's empty, and if it has anything that can make your code/website vulnerable (HTML tag injection, JS code injection, PHP code injection by evaluation, etc.). It's way better than checking it by yourself.
Of course, you can always just check it by yourself if you decide not to trust the filter_* functions, in that case you need to:
Check if the variable exists by using is_null and/or checking against NULL;
Check if the variable is empty;
Check if the variable has special characters (and escape them properly);
Check if the variable has HTML or XML tags (and escape/delete them);
Check if the variable has JS code or script tags (and escape/delete them);
Check if the variable has PHP code and if it's trying to execute it via eval;
As you can see, it's an extensive list, and if you don't want to rely on PHP's built-in functions, that's what you need to do.
Sources:
PHP: Filter Functions - Official PHP docs
PHP 5 Filter functions - W3Schools
always check for undefined variables first.
if(!is_null($_POST["theirname"])){
if(empty($_POST["theirname"]){code;}
}
It is absolutely required to check for existence for any variable.
$bingo = isset($variable);
Normally you want to first check if a variable is defined at all. You can do this by if(!is_null($_POST["theirname"]))
If it is defined, then you maybe want to check if it is empty, and if not, do some stuff. (for example sanitizing and / or validating)
if(!is_null($_POST["theirname"])){
if(!empty($_POST["theirname"])
{
//Do some stuff here
}
else
{
//send notification that the user didn't input any data
}
}
The error in your example is you have missing ) in your if judgment.
//Your code
if ( empty($_POST["theirname"]) { code; }
^^
//Code updated
if (empty($_POST["theirname"])) { code; }
Before checking if your inputs are empty, you could check if your form is defined and is not NULL.
Example:
//Reset.
$msg = $theirname = NULL;
//Check if the form is defined.
if (isset($_POST)) {
//Check input empty.
if(empty($_POST['theirname'])) {
$msg = 'Inputs are required';
} else {
$theirname = data_filter($_POST['theirname']);
}
//check $theirname.
if ($theirname) {
//Do something with $theirname...
}
}
//Filter function.
function data_filter($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
//Message.
echo $msg;
Checkout filter_var and filter_input.
How to send get&post&cookie at once?
if($_GET[get] && $_POST[post] && $_COOKIE[cookie])
{
//blah blah
}
How to send get,post,cookie data for that code at once??
give me a sample code please!
I used form tag but couldnt send at once but I don't know how to send it at once
Sounds like you want $_REQUEST - this is by default "An associative array that by default contains the contents of $_GET, $_POST and $_COOKIE."
Be aware that by using $_REQUEST you lose information about where the variable came from, so it is recommended to use the individual variables, or set $_REQUEST to only contain GET and POST data, with POST overwriting GET: $_REQUEST = array_merge($_GET, $_POST);
I am developing a basic API for some simple functionality. I am capturing inputs like below:
if ($action == 'delete' && isset($_POST['targetId']) && isset($_POST['userId'])) {
//The isset causes "Do not access Superglobal _POST array directly" warning in Netbeans
$userId = filter_input(INPUT_POST, 'userId');
$beamId = filter_input(INPUT_POST, 'targetId');
}
Should I use filter_input even for checking whether the value is set? Like:
if ($action == 'delete' && filter_input(INPUT_POST, 'targetId') && filter_input(INPUT_POST, 'userId')) {
}
I am not looking at options here rather I would be happy with the most correct solution which is secure and hack resistant.
EDIT: Yes, the above information will be used as inputs for SQL
Another solution could be use filter_has_var().
if (filter_has_var(INPUT_POST, "userId")) {
//occurs when $_POST['userId'] is set, even when empty
}
More info in: Official documentation
filter_input is used to sanitize or check the data type of the input. It is used to make sure that the data you are expecting is in the required format and you can sanitize it using required filters. isset in your case will check if the required variable is set or not (or is not NULL). So both have different usecases. I don't see using isset directly on a POST item as bad but I would recommend using filter_input so that the data can be validated as well.
The main problem with unfiltered input is essentially code injection. That's a problem where you use the input as part of a SQL statement or your output back to the user (JavaScript).
As such, it is not necessary to do it just to check if a value was entered. It is good to rather be consistent and use filter_input first to populate variables and then use those variables to check if the fields were populated if you will be using the value as above later on in your script.
I'm learning PHP and specifically how to secure php forms.
I'm reading an article entitled "Sanitize and Validate Data with PHP Filters" wherein the author checks if the form was submitted using the following code:
if (isset($_POST['Submit'])) {
// do something...
}
Which does work, but I've read that its best to use input filters (i.e. filter_input).
Secondly, using filter_input would also stop netbeans from nagging me about not "accessing the superglobal $_POST Array directly"
So I wrote the following:
function is_form_submit() {
$request = filter_input(INPUT_SERVER, "REQUEST_METHOD");
return $request === 'POST' ? true : false;
}
Which could be used like so:
if ( is_form_submit() ) {
// do something...
}
So my question is: doesn't my code achieve the same thing? If not, why not. Please advise.
While your code would achieve the same result in most cases, it is not the same as the isset call.
What your code does is checks if the REQUEST_METHOD is POST. That is, it checks if the user made a POST request to access the current page.
What the isset does is checks if something with the name of Submit was sent via POST. This usually happens when your submit button is <input name="Submit" type="submit" value="Submit" />, as clicking that (or hitting enter in a text field and it's the first submit button) will result in $_POST['Submit'] being set.
To see the different behaviours, compare the results of curl -X POST your-url.com/page.php with curl -F Submit=submit your-url.com/page.php.
filter_input is untouched user input.
Some scripts add/modify $_POST and $_GET directly. Fine if your code is fail-safe, but if something goes wrong with the manipulated keys/values, there could be errors.
filter_input( INPUT_POST, 'requiredID' )
Would not be affected by the type of coding below
$_POST['requiredID'] = brokenFunction( $_POST['requiredID'] );