Can the PHP superglobal $_GET be used and work as intended outside of the form tags? For example, can I do $_GET('select box id') outside of the form tags and have it work as intended?
<?php
---Placeholder for DB login info---
switch($_GET['select box id'])
{
case "text shown for second option of select box":
$query = mysql_query("placeholder for actual query");
$row = mysql_fetch_row($query);
$textboxValue = $row[0];
break;
}
?>
Can the PHP superglobal $_GET be used and work as intended outside of the form tags?
Yes. The position of PHP code within HTML is entirely irrelevent except in determining where output will appear in a document.
$_GET['select box id']
Form controls use their names for submission keys, not ids.
mysql_query
Read the big red warning box on the documentation page for that function.
If this is for login info, you should not be using a get request anyway--you should be using post.
But at any rate, yes it should work. As long as the data is sent with the query, it should work.
That said, you may also want to do some research into some basic security aspects, such as validating and sanitizing inputs. Otherwise, you may wind up opening yourself up to some rather nasty attacks.
I would recommend the book Essential PHP Security from O'Reilly Press. I would also look into using something like MySql PDO for making database queries, as it tends to be more reliable and secure than simply using mysql_query.
Superglobal means available for use anywhere/everywhere.
Related
I am using wordpress for a web site. I am using snippets (my own custom php code) to fetch data from a database and echo that data onto my web site.
if($_GET['commentID'] && is_numeric($_GET['commentID'])){
$comment_id=$_GET['commentID'];
$sql="SELECT comments FROM database WHERE commentID=$comment_id";
$result=$database->get_results($sql);
echo "<dl><dt>Comments:</dt>";
foreach($result as $item):
echo "<dd>".$item->comment."</dd>";
endforeach;
echo "</dl>";
}
This specific page reads an ID from the URL and shows all comments related to that ID. In most cases, these comments are texts. But some comments should be able to point to other pages on my web site.
For example, I would like to be able to input into the comment-field in the database:
This is a magnificent comment. You should also check out this other section for more information
where getURLtoSectionPage() is a function I have declared in my functions.php to provide the static URLs to each section of my home page in order to prevent broken links if I change my URL pattern in the future.
I do not want to do this by using eval(), and I have not been able to accomplish this by using output buffers either. I would be grateful for any hints as to how I can get this working as safely and cleanly as possible. I do not wish to execute any custom php code, only make function calls to my already existing functions which validates input parameters.
Update:
Thanks for your replies. I have been thinking of this problem a lot, and spent the evening experimenting, and I have come up with the following solution.
My SQL "shortcode":
This is a magnificent comment. You should also check out this other section for more information
My php snippet in wordpress:
ob_start();
// All my code that echo content to my page comes here
// Retrieve ID from url
// Echo all page contents
// Finished generating page contents
$entire_page=ob_get_clean();
replaceInternalLinks($entire_page);
PHP function in my functions.php in wordpress
if(!function_exists("replaceInternalLinks")){
function replaceInternalLinks($reference){
mb_ereg_search_init($reference,"\[custom_func:([^\]]*):([^\]]*)\]");
if(mb_ereg_search()){
$matches = mb_ereg_search_getregs(); //get first result
do{
if($matches[1]=="getURLtoSectionPage" && is_numeric($matches[2])){
$reference=str_replace($matches[0],getURLtoSectionPage($matches[2]),$reference);
}else{
echo "Help! An unvalid function has been inserted into my tables. Have I been hacked?";
}
$matches = mb_ereg_search_regs();//get next result
}while($matches);
}
echo $reference;
}
}
This way I can decide which functions it is possible to call via the shortcode format and can validate that only integer references can be used.
I am safe now?
Don't store the code in the database, store the ID, then process it when you need to. BTW, I'm assuming you really need it to be dynamic, and you can't just store the final URL.
So, I'd change your example comment-field text to something like:
This is a magnificent comment. You should also check out this other section for more information
Then, when you need to display that text, do something like a regular expression search-replace on 'href="#comment-([0-9]+)"', calling your getURLtoSectionPage() function at that point.
Does that make sense?
I do not want to do this by using eval(), and I have not been able to accomplish this by using output buffers either. I would be grateful for any hints as to how I can get this working as safely and cleanly as possible. I do not wish to execute any custom php code, only make function calls to my already existing functions which validates input parameters.
Eval is a terrible approach, as is allowing people to submit raw PHP at all. It's highly error-prone and the results of an error could be catastrophic (and that's without even considering the possibly that code designed by a malicious attacker gets submitted).
You need to use something custom. Possibly something inspired by BBCode.
Alright, so I've set up a small system where I can add pages through an administration panel and for them to appear on the main site. As well as html pages that are made in the admin panel I have also got about two PHP pages with queries that are stored in the database.
Anyways I am calling these by using 'Eval' which I've read that it is unsafe.
Although since its only html codes going in from the administration panel [php codes are disallowed and wont function if posted in these pages] and the PHP pages are unediable unless access to the database, is this safe?
One PHP page involves user comments but all HTML and PHP codes are stripped from the form. I've tested it involving a few exploiting techniques but none seemed to succeed.
But is using eval for my purpose safe? Is there a better work around?
Code:
<?php
if (isset($_GET['p']))
{
$stmt = $dbh->prepare('SELECT * FROM pages WHERE shortname = :p');
if (!$stmt->execute(array(':p' => $_GET['p'])))
{//
exit('Could not exec query with param: '.$_GET['p']);
}
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
eval(" ?>".$row["content"]."<?php ");
echo '</div>';
}
}
//ends connection
$row->dbh = null;
?>
Sometimes writing secure code is more than being sure that it is safe. Maybe we all look at your code and think that it is safe, but oversee something small and obvious that will make a big security hole.
Better safe than sorry. You say [php codes are disallowed and wont function if posted in these pages] So why do you use eval then?
Back to your code. The parts that you have posted look safe to me (as for the eval part). But what if there is some small sql injection hole somewhere else in your application that lets the attacker change rows? The attacker will be able to put php code in your database and later execute it with your eval statement.
I would say: No, this code is not safe.
Also, do not echo user given content in your errors, this can lead to an xss vulnerability.
$name="document.write(get_name());";
echo $n= $name; // Here it prints name also (correct one)
$sql=mysql_query("INSERT INTO tab1 (name,visited_time) values ('$n',NOW())");
Ideally this should print got name from the function but it inserting
document.write(get_name());
Note : get_name function is returning the value correctly. and function is mandatory. Only the problem is it inserting document.write(get_name()); instead it's value.
It looks like you missed an important chapter about PHP / JS programming...
PHP code is executed server side.
JavaScript code is executed client side.
Steps to solve this are:
whenever you need this query to be executed, you need to make a call from JavaScript to PHP and pass the variables to the PHP. You can do this with an asynchronous call with jquery for example:
// JS, executed on client side
var name = get_name(); // this javascript function must exist
$.get("path/to/your/page.php", {"name":name});
More info about jQuery here: http://api.jquery.com/jQuery.get/
then, in PHP, you get this value from the global $_GET and you can use it:
// php code that will be executed when path/to/your/page.php will be called
$name = $_GET['name'];
$sql = "INSERT INTO tab1 (name,visited_time) values ('" . $name . "',NOW())";
$rs= mysql_query($sql);
And that will do what you expect.
You can use this code to implement the logic, but it requires lots of improvements then:
It is highly unsecured and leaves room for the most simple SQL injection attack. You must "quote" all values you use in your SQL queries (you can't trust any data coming from the client)
$_GET['name'] may not exist or contain what you except so you need to use function like isset and to do more tests after to verify that nobody is trying to hack your variable
you should POST method and not GET since this HTTP call will result in changing the state of the datbase
mysql_query is deprecated: http://us2.php.net/manual/en/function.mysql-query.php you should use mysqli_query or PDO...
I'm not gonna talk about all these topics, they are highly covered on the web and a simple search your favorite search engine will give all the information you need.
Note: I wrote that "JavaScript code is executed client side". This is not exactly true since it is possible to build a server in JavaScript but this is far far far away from you concern and that wouldn't even change the fact that you still need to send the value from the client to the server with the kind of logic I just described.
Lets say I have an index.php file and some $_GET variables. After a few hundred lines of code I call a method, with the variables as parameters.
Should I validate the variables on top of everything, or should I validate them inside the class/method I call?
2 things in mind:
Avoiding to validate the variables multiple times, everywhere..
Having multiple sources, not only $_GET, and multiple calls to such a method from different files.
Some code:
<?php
function do_something($string) {
// Validate $string here?
}
// ...or here, before using it?
$result = do_something($_GET['some_string']);
This is a question where's no standard solution possible.
You could write yourself a helper class (i recommend this since this is a solution with less maintanance and best flexibility) which is called at the very first beginning of your index.php file, as some kind as a "contract" which is like:
<?
require_once "validator.php";
$validator = new Validator();
$validated = $validator->validateGet($_GET);
// all the remaining site's php code goes here
?>
this class could return anything you want, such like a boolean indicating whether every variable is okay or not, or an array containing the values with removed tags, etc.
Another barrier for cross site scripting and/or SQL injection should be prepared statements: http://php.net/manual/de/pdo.prepared-statements.php
All your SQL queries should also be contained in a external utilities class called ProductDataAccessObject (ProductDAO) or ProductQuerier, etc., which is also for structural/maintanance reasons.
But there's no rule that says "you must validate your variables at the very first beginning or at time of use"
Validate at the very first point when you are receiving $_GET at the entry level so that you are sure for the below code at later stage as well-
// Validate $_GET['some_string'] HERE
$result = do_something($_GET['some_string']);
If you validate here -
function do_something($string) {
// Validate $string here?
}
then there is a possibility that u miss the validation and it will open a loop hole in the code as validation is available only to the method this time.
If you are setting some values for the database, it is a good practice to double check the data and make it safe from code injections.
You can validate on top of the page your every single variable with a one line
$_GET = array_map("mysqli_real_escape_string",$_GET);
Array_map applies one function over every value of an array which in our case is applying mysqli_real_escape_string to the array $_GET
IMPORTANT:
Please do note this is only for sanitization and not validation
You need to validate every variable by your own, for example if what is being sent in an integer, make sure to use intval to validate it
Refer to this question for more information: Sanitization and Validation
I'm not satisfied with your answers yet, I did not ask HOW to validate, I did ask WHERE to do it.
Here is my own suggestion:
As I think the times for procedural coding in PHP are finally over (!!), I dont have any logic inside of my index.php, all logic goes into controller classes.
So you have a data Sender, and data Reciever.
As a Reciever (not only in PHP, it's something very common in realife, too), I have to validate the information sent by the Sender. The Reciever does not trust anybody (this is important in APIs for example). Therefore, validation has to be inside the methods you create, not at the top of index.php files or outside of a class. Imagine someone else using your method, is he going to validate the arguments, or has it been YOUR task? I think it's up to you, so you (the Reciever!) can throw Exceptions.
I also like to keep my data ($_GET, $_POST, ...) as raw as possible outside of the controller. Imagine you have a method which needs validated data at line 100, and a method at line 200 which needs raw data. Now on liee 5 you changed the raw into sanitized. => You have to keep two variables, $data and $data_raw, which is unnecassary overhead.
Think about it
I am working on my personal site, where I want to store my customers recent search result limited to that particular session.
I am using PHP platform and Javascripts.
Here is an example of what I am exactly looking at :
It stores your previously searched domain name for that particular session so that user can make decision by comparing those results.
Thanks.
EDIT- Well Thanks for all of your answers and suggestions.
But If you have noticed
above example
It looks like some kind of script loading a new content on the same page without refreshing it and keeping previous search content <div> as it is.
How to achieve this using javascripts or some sort of div layer ????
UPDATE START
This example uses page reload. If you want to do it without page reload, you can but you'll have to use AJAX to load new search results. But then, it's not a PHP question. I suggest looking at jquery library, as it makes it easy. Tutorials: http://docs.jquery.com/Tutorials and e.g. this one ( http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery#Rate_me:_Using_Ajax ).
When loading data via AJAX, the page rendering result (in my example search.php) should return only HTML for results part, not whole HTML page. This is generally a first part of my tutorial (without session).
But I really think that AJAX in here is not really needed. Session is more reliable and allows access to your page from older / mobile browsers where not always JS works correctly.
UPDATE END
Ok then. Let's try the simple tutorial then. Sorry if too simple, but I don't know your exact level.
PHP has mechanism called sessions. In reality they are just bytes stored on server. Server knows which session is for each client by reading session cookie from client browser.
Not every page uses sessions (not every page needs it, and session uses server space, even if only temporarily), session is not enabled by default. To turn on session you use command
<?php session_start(); ?>
In most cases this is either run by PHP framework you use, or put near the top of your site. Session is definitely needed if you want to authenticate user somehow. Or in your case :)
To access session you can use superglobal $_SESSION variable (superglobal means that you can access it anywhere). It's an array, so session element will be e.g. $_SESSION['search'] etc.
As example, let's assume that your page looks like that
<html>
...
<form action="search.php" method="post">
Search: <input type="text" name="searchQuery" />
<input type="submit" value="Search" />
</form>
...
</html>
this very form will send user search to file named search.php. It can be the same file where the form resides - in simplest case when you put both your code and HTML in one file. Beginners often use this schema, although it's not advisable as result is a mess and hard to further change.
In search.php then, you'll use similar code:
<?php
if (!empty($_POST['searchQuery'])) //we have a new search
{
$result = do_search($_POST['searchQuery']);
}
?>
Then, somewhere below you'll display your search result ($result variable). do_search() function is your search mechanism, I guess you have it somewhere. You may have it not 'wrapped' in a function, then I advise to create it like that, it's much more useful.
function do_search($searchQuery)
{
...
return $result;
}
mind it, the above code doesn't use sessions yet. Let's add saving previous search results in session. The code may then look like that:
<?php
session_start(); //Starting session
//let's create session variable used to store results
if (!isset($_SESSION['searches']))
$_SESSION['searches'] = array();
if (!empty($_POST['searchQuery'])) //we have a new search
{
if (isset($_SESSION['searches'][$_POST['searchQuery']]) //User already searched on this value, delete previous result from sesion
{
unset($_SESSION['searches'][$_POST['searchQuery']]);
}
$result = do_search($_POST['searchQuery']);
//Let's add new search on the begining of session array to make iterations easier.
$result = array($_POST['searchQuery'] => $result); //convert result to same format as session table
$_SESSION['searches'] = array_merge($result, $_SESSION['searches']);
}
?>
In display you'll now not iterate on $result variable as before, but instead you will do something like
foreach ($_SESSION['searches'] as $query => $result)
{
...//display of single result
}
I haven't tested following code and it's not a full program. Parts to display result and to do actual search are not described but I guess you have them already prepared. Also, this is only one possible approach of countless possibilities. But I hope this helps :)
Possible modification - now I always perform search, even if user already searched on this term. You may want to receive the result from cache without second search. Then the code will look like
if (isset($_SESSION['searches'][$_POST['searchQuery']]) //User already searched on this value
{
$result = $_SESSION['searches'][$_POST['searchQuery']];
unset($_SESSION['searches'][$_POST['searchQuery']]);
}
else
{
$result = do_search($_POST['searchQuery']);
}
For more in-depth information about sessions and some other constructs used in my example I suggest PHP manual
http://pl.php.net/manual/en/book.session.php
and various tutorials over the network. Or you can add a comment here :)
Put this code near the beginning of your script(s):
if (!isset($_SESSION['previous_searches']) || !is_array($_SESSION['previous_searches'])) {
$_SESSION['previous_searches'] = array();
}
[edit]
This code snippet checks if if there is already an array with prevous searches and if not it will be created.
[/edit]
Then when the user hits the search page put this code in the receiving script of the search:
$_SESSION['previous_searches'][] = $_GET['what_ever_your_search_value_might_be'];
[edit]
This code snippet adds the current search value to the and of the array with previous search values
[/edit]
Now you have all previous search values in $_SESSION['previous_searches']
If your website is a web application where you never reload the page nor change the page, you can keep it JavaScript in a global store (declare at top level something like var StoredSearch = []; and use it). If not, then use $_SESSION to store this and AJAX to save/load searches from JavaScript to PHP.