Do I need to sanitize strings used to declare geometric shapes? - php

I want an SQL function to receive a string such as point_str = "47.572820 -34.628906". Inside the function, the string will be converted into a shape variable, for example by SET xpoint = PointFromText( concat("POINT(", point_str, ")") );
Before sending this string from php to sql, do I need to sanitize it (for example with floatval)?

You can throw an error on both situations; either when the text is entered, of when it is read. When the data is read and the function fails to genereate a shape, all visitors of that page will see the error.
If you throw the error on creation, there is only one person who gets an error plus the wrong data will never be in your database. So yes. If the output is dependent on the input make sure the input is suitable for the output and sanitize it.

Related

PHP functions: passing variables by reference (and if not possible) by value

I am trying to build an "escape" function (as an exercise). The objective of this function is to transform "dangerous" values into safe values to be inserted in a database. The content of this function is not important.
function escape(&$value){
//some code
return $value;
}
Here's the problem: I want to make this function very handy to use, therefore it should be able to support 2 possible scenarios:
1) returning a safe value:
$safe_val = escape($unsafe_val);
2) changing a variable "by reference":
escape($value);
At the moment, my function does its job, however...if I pass something like:
$safe_val = escape(php_native_change_string_to_something($value));
PHP gets angry and says:
Notice: Only variables should be passed by reference
How can I make PHP accept that if something can't be passed by reference it does not matter and it should just ignore the error and continue the execution?
PHP is complaining because the value being passed into escape by escape(php_native_change_string_to_something($value)) is a temporary value (rvalue). The argument has no permanent memory address so it does not make sense to modify the value.
However, despite this not making sense, PHP will still do what you want. You are receiving a notice, not an error. Your code should still produce the output you are expecting. This short program models your setup:
<?php
function escape (&$s) {
return $s;
}
$s = 'TEXT TO ESCAPE';
$new_s = escape( strtolower( $s ) );
echo "$s\n";
echo "$new_s\n";
and produces the following results:
s: TEXT TO ESCAPE
new_s: text to escape
If you would like to get rid of the notice you will need to use the error control operator (#), #escape(php_native_change_string_to_something($value)).
Despite this being something that will work in PHP I would suggest avoiding this type of usage as it will decrease code readability and is not suggested by PHP (as the notice indicates).

Checking for vulnerabilities including remote file, with parameter, in PHP script

I'm including a remote file with file_get_contents() like so:
function checkData($serial) {
file_get_contents("http://example.com/page.php?somevar=".$serial."&check=1");
return $http_response_header;
}
This remote page performs some basic data manipulation, and looks up the serial number in a database (The input is sanitised and I'm using PDO, so I don't have to worry about SQL injections), and then returns a value in the response header. The input $serial is a get parameter - So completely controlled by the user. I'm wondering if there are any inputs to this function that would lead to undesirable behaviour, for example getting contents of another page other than the one desired.
Thanks in advance.
If the $serial variable is always going to be numeric you can apply intval() around the value to ensure the value will always be a number and not contain other non-numeric data for path traversal / RFC, etc.
E.G.
file_get_contents("http://example.com/page.php?somevar=".intval($serial)."&check=1");
Alternatively you can use preg_replace to strip unwanted characters, should you need alpha characters also.
http://php.net/manual/en/function.preg-replace.php

PHP Injection from HTTP GET data used as PHP array key value

i would like to know if there is a possible injection of code (or any other security risk like reading memory blocks that you weren't supposed to etc...) in the following scenario, where unsanitized data from HTTP GET is used in code of PHP as KEY of array.
This supposed to transform letters to their order in alphabet. a to 1, b to 2, c to 3 .... HTTP GET "letter" variable supposed to have values letters, but as you can understand anything can be send to server:
HTML:
http://www.example.com/index.php?letter=[anything in here, as dirty it can gets]
PHP:
$dirty_data = $_GET['letter'];
echo "Your letter's order in alphabet is:".Letter2Number($dirty_data);
function Letter2Number($my_array_key)
{
$alphabet = array("a" => "1", "b" => "2", "c" => "3");
// And now we will eventually use HTTP GET unsanitized data
// as a KEY for a PHP array... Yikes!
return $alphabet[$my_array_key];
}
Questions:
Do you see any security risks?
How can i sanitize HTTP data to be able use them in code as KEY of an array?
How bad is this practice?
I can't see any problems with this practice. Anything you... errr... get from $_GET is a string. It will not pose any security threat whatsoever unless you call eval() on it. Any string can be used as a PHP array key, and it will have no adverse effects whatsoever (although if you use a really long string, obviously this will impact memory usage).
It's not like SQL, where you are building code to be executed later - your PHP code has already been built and is executing, and the only way you can modify the way in which it executes at runtime is by calling eval() or include()/require().
EDIT
Thinking about it there are a couple of other ways, apart from eval() and include(), that this input could affect the operation of the script, and that is to use the supplied string to dynamically call a function/method, instantiate an object, or in variable variables/properties. So for example:
$userdata = $_GET['userdata'];
$userdata();
// ...or...
$obj->$userdata();
// ...or...
$obj = new $userdata();
// ...or...
$someval = ${'a_var_called_'.$userdata};
// ...or...
$someval = $obj->$userdata;
...would be a very bad idea, if you were to do it with sanitizing $userdata first.
However, for what you are doing, you do not need to worry about it.
Any external received from GET, POST, FILE, etc. should be treated as filthy and sanitized appropriately. How and when you sanitize depends on when the data is going to be used. If you are going to store it to the DB, it needs to be escaped (to avoid SQL Injection. See PDO for example). Escaping is also necessary when running an OS command based on user data such as eval or attempting to read a file (like reading ../../../etc/passwd). If it's going to be displayed back to the user, it needs to be encoded (to avoid html injection. See htmlspecialchars for example).
You don't have to sanitize data for the way you are using it above. In fact, you should only escape for storage and encode for display, but otherwise leave data raw. Of course, you may want to perform your own validation on the data. For example, you may want dirty_data to be in the list of [a, b, c] and if not echo it back to the user. Then you would have to encode it.
Any well-known OS is not going to have a problem even if the user managed to attempt to read an invalid memory address.
Presumably this array's contents are meant to be publicly accessible in this way, so no.
Run it through array_key_exists()
Probably at least a little bad. Maybe there's something that could be done with a malformed multibyte string or something that could trigger some kind of overflow on a poorly-configured server... but that's pure (ignorant) speculation on my part.

What are the necessary and most important things, we should do at validation, if an web application gets the users input or parameters?

I am always thinking about validation in any kind on the webpage (PHP or ASP, it doesn't matter), but never find a good and accurate answer.
For example, a I have some GET-Parameter, which defines a SQL query like DESC oder ASC. (SQL-Injection?)
Or I have a comment-function for user, where the data is also saved in a database.
Is it enought to check for HTML-tags inside the data? Should the validation done before adding it to the database or showing it on the page?
I am searching for the ToDo's which should be always performed with any data given from "outside".
Thanks.
Have a good idea of what you want from the user.
You want them to specify ascending/descending order? That's an enumeration (or a boolean), not part of an SQL query:
$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong
This is wrong no matter how much you escape and sanitize their string, because this is not the way to validate an enumeration. Compare:
if ($_GET['sortOrder'] == 'desc') {
$ascending = false;
} else {
$ascending = true;
}
if ($ascending) {
...
} else {
...
}
...which does not warrant a discussion of string escaping or SQL injection because all you want from the user is a yes/no (or ascending/descending) answer.
You want them to enter a comment? Why disallow HTML tags? What if the user wants to enter HTML code?
Again, what you want from them is, say, "a text... any text with a maximum length of 1024 characters*." What does this have to do with SQL or injection? Nothing:
$text = $_POST['commentText'];
if (mb_strlen($text, ENCODING) <= 1024) {
//valid!
}
The value in the database should reflect what the user entered verbatim; not translated, not escaped. Say you're stripping all HTML <tags> from the comment. What happens when you decide to send comments somewhere in JSON format? Do you strip JSON control characters as well? What about some other format? What happens if HTML introduces a tag called ":)"? Do you go around in your database stripping off smileys from all comments?
The answer is no, as you don't want HTML-safe, JSON-safe, some-weird-format-with-smileys-safe input from the user. You want text that is at maximum 1024 characters. Check for that. Store that.
Now, the displaying part is trickier. In order to display:
<b>I like HTML "tags"
in HTML, you need to write something like:
<b>I like HTML "tags"
In JSON, you would do:
{ "I like HTML \"tags\" }
That is why you should use your language facilities to escape the data when you're using it.
The same of course goes for SQL, which is why you should escape the data when using simple query functions like mysql_query() in PHP. (Parametrized queries, which you should really be using, on the other hand, need no escaping.)
Summary
Have a really good idea of what you want as the input, keeping in mind that you almost never need, say, "HTML-safe text." Validate against that. Escape when required, meaning escape HTML as you send to the browser, SQL as you send to the database, and so on.
*: You should also define what a "character" means here. UTF-8, for example, may use multiple bytes to encode a code point. Does "character" mean "byte" or "Unicode code point"?
If you're using PDO, be sure to use prepared statements - these clean the incoming data automatically.
If using the mysql_* functions, run each variable through mysql_real_escape_string first.
You can also do validation such as making sure the variable is one of an acceptable range:
$allowed_values = array('name', 'date', 'last_login')
if(in_array($v, $allowed_values)) {
// now we can use the variable
}
You are talking about two kinds of data sanitation. One is about putting user-generated data in your database and the other is about putting user-generated data on your webpage. For the former you should follow adam's suggestions. For the later you should look into htmlspecialchars.
Do not mix these two as they do two completely different things. For that purpose sanitation should only take place at the last moment. Use adam's suggestion just before updating the database. Use htmlspecialchars just before echoing data. Do not use htmlspecialchars on data before adding it to the database.
You might also want to look around Stackoverflow, because this sort of question has been asked and answered countless times in the past.

A tidy way to clean your URL variables?

I'm wondering if there is a quick and easy function to clean get variables in my url, before I work with them.( or $_POST come to think of it... )
I suppose I could use a regex to replace non-permitted characters, but I'm interested to hear what people use for this sort of thing?
The concept of cleaning input never made much sense to me. It's based on the assumption that some kinds of input are dangerous, but in reality there is no such thing as dangerous input; Just code that handles input wrongly.
The culprit of it is that if you embed a variable inside some kind of string (code), which is then evaluated by any kind of interpreter, you must ensure that the variable is properly escaped. For example, if you embed a string in a SQL-statement, then you must quote and escape certain characters in this string. If you embed values in a URL, then you must escape it with urlencode. If you embed a string within a HTML document, then you must escape with htmlspecialchars. And so on and so forth.
Trying to "clean" data up front is a doomed strategy, because you can't know - at that point - which context the data is going to be used in. The infamous magic_quotes anti-feature of PHP, is a prime example of this misguided idea.
I use the PHP input filters and the function urlencode.
Regular expressions can be helpful, and also PHP 5.2.0 introduced a whole filter extension devoted to filtering input variables in different ways.
It's hard to recommend a single solution, because the nature of input variables is so... variable. :-)
I use the below method to sanitize input for MYSQL database use. To summarize, iterate through the $_POST or $_GET array via foreach, and pass each $_POST or $_GET through the DBSafe function to clean it up. The DBSafe could easily be modified for other uses of the data variables (e.g. HTML output etc..).
// Iterate POST array, pass each to DBSafe function to clean up data
foreach ($_POST as $key => $PostVal) {
// Convert POST Vars into regular vars
$$key=DBSafe($PostVal);
// Use above statement to leave POST or GET array intact, and use new individual vars
// OR, use below to update POST or GET array vars
// Update POST vars
$_POST[$key]=DBSafe($PostVal);
}
function DBSafe($InputVal) {
// Returns MySQL safe values for DB update. unquoted numeric values; NULL for empty input; escaped, 'single-quoted' string-values;
if (is_numeric($InputVal)) {
return $InputVal;
} else {
// escape_string may not be necessary depending on server PHP and MySQL (i.e. magic_quotes) setup. Uncomment below if needed.
// $InputVal=mysql_escape_string($InputVal);
$InputVal=(!$InputVal?'NULL':"'$InputVal'");
return $InputVal;
}
}

Categories