$queryDetails = mysql_query("SELECT * from members WHERE username = '$current_url' ");
I'm trying to use fwrite to create a page on register. This is the only thing what is going wrong. As I'm using 'fwrite', I cannot use speech marks as it ends the 'fwrite' command.
I've tried escaping the query out;
$queryDetails = mysql_query('SELECT * from members WHERE username = \'$current_url\' ');
But that hasn't worked. I can't use " as it closes the fwrite.
Any help?
The full code is
$queryDetails = mysql_query('SELECT * from members WHERE username = \'$current_url\' ');
$queryNumRowsDetails = #mysql_num_rows($queryDetails);
if ($queryNumRowsDetails != 0){
//collect data from SQL database
while ($row = mysql_fetch_assoc($queryDetails)){
$dbUsername = $row['username'];
$dbClub = $row['club'];
$dbReputation = $row['reputation'];
}
}
else{
die("There was a problem gathering user data.");
}
And if I try to escape the ' as shown in the second code block. It goes to the "There was a problem gathering user data."
$current_url is a variable collecting the current URL and taking away a few bits, leaving only a username remaining. Meaning example.com/users/AdziHades/index.php equates to just AdziHades.
Though your question lacks the information indicating what's not working, it looks like your problem with the query might be that you're using single quotes and trying to have it evaluate the variable inside. For example:
$myvar = 2;
$mystring = "I have $myvar apples.";
In that code, $mystring would evaluate to I have 2 apples.. If, instead, you use single quotes, like so:
$myvar = 2;
$mystring = 'I have $myvar apples.';
You will get I have $myvar apples.'. This is because single quotes will not evaluate variables automatically. Note: I am NOT referring to the quotes used in the query itself (around $current_url), I'm talking about the quotes around the entire query.
You have two options here. The 'easy' option is to just concatenate the value of the variable. The better, more future-proof way is to switch to using prepared statements with PDO (here is a page that explains why you should be using this and how to use it or at least mysqli. Prepared statements will allow for more secure queries without you having to manually escape your values to prevent SQL injection. I highly recommend you look at going down this route. The mysql_* extensions you're using have been deprecated and will most likely cause you problems in the future.
Related
This is probably a stupid question, but I have been Googling an answer for the better part of the day and can't get anywhere. I am trying to get the following bit of code to work, but can't find any help on how to properly format a prepared Postgres request in PHP.
$foo = $_GET[bar];
echo $foo; // 5555
//what I'm trying to do:
pg_prepare($dbconn,"table_query","SELECT Members FROM programs WHERE programID = '$1' ");
pg_execute($dbconn,"table_query", array($foo));
If I hardcode the statement with a value, it works fine, but only if I include the single quotes. I've tried just about every method I can find to escape the single quotes or append the quotes to the string, but all I can get are parsing errors.
What totally obvious thing am I missing?
Edit: Changed the snippet to clarify that the variable I am getting does not include quotes. Any method I where I try to add the quotes fails.
Let’s study a complete example. Suppose you got your value from a GET query which set the name pid. From your example query I expect the value to be the decimal representation of an integer, different from zero. It is a string, since nothing else can come from a GET query.
$pid = $_GET['pid'];
// This is _very_ important.
// Anything that comes from outside must be validated or sanitized.
// FILTER_VALIDATE_INT refuses "0" too (correct if needed).
if (filter_var($pid, FILTER_VALIDATE_INT) === false) {
// Deal with invalid input
}
$result = pg_query_params($dbconn,
'SELECT Members FROM programs WHERE programID = $1',
array($pid)
);
pg_query_params binds $1 with $pid and quotes it correctly, while you cannot use double quotes around the statement because PHP would expand $1 incorrectly. There is no need to put quotes around $pid manually, because pg_query_params takes care of this. Furthermore, PostgreSQL accepts an integer value both with quotes and without them, so fumbling with quotes is pointless in this case.
Instead of using the traditional pg_ functions, you might use PDO, the PHP Database Object abstraction layer.
In that case (disregarding possible options needed in your case):
$dsn = 'pgsql:host='. $host .';port=5432;dbname='. $database;
$dbh = new PDO($dsn, $user, $password);
$dbh->prepare('SELECT Members FROM programs WHERE programID = ?');
$result = $dbh->execute(array($pid)); // $pid as before
You should be using prepared statements. This should solve your quoting problem and also remove a major risk of SQL injection. Try something like this:
$stmt = $conn->prepare("SELECT Members FROM programs WHERE programID = ?");
$stmt->bind_param("s", $foo);
$foo = "5555";
$stmt->execute();
I've made a simple search-script in PHP that searches a mySQL database and outputs the result. How this works is like this:
User searches for "jack's" through a search-form.
My PHP-script GETs this search, and sanitizes it.
Then the script, with the use of SELECT and LIKE, gets the results.
The script then outputs the result to the user.
Lastly, the script tells the user that "jack's returned x results." with the help of escaping.
What I would like to ask is, am I doing it right?
This is how I sanitize before SELECTING from the database:
if(isset($_GET['q'])){
if(strlen(trim($_GET['q'])) >= 2){
$q = trim(mysql_real_escape_string(addcslashes($_GET['q'], '%_')));
$sql = "SELECT name, age, address FROM book WHERE name LIKE '%".$q."%'";
}
}
And this is how I escape before outputting "jack's returned x results.":
echo htmlspecialchars(stripslashes($q)) . " returned x results.";
Is this the correct way to do it?
By the way, I know that PDO and mySQLi is preferred as they sanitize themselves through the use of prepared statements, but I have no real experience with them whatsoever. But I would gladly take a look, if you guys could link me some newbie tutorials/explanations.
Furthermore, I heard that magic_quotes and charset could in some way or another lead to injections -- is this correct?
For some reason we need also escape a backslash too.
So, the proper code would be, I believe
if(isset($_GET['q'])){
$_GET['q'] = trim($_GET['q']);
if(strlen($_GET['q']) >= 2){
$q = $_GET['q'];
$q = '%'.addCslashes($q, '\%_').'%';
// now we have the value ready either for escaping or binding
$q = mysql_real_escape_string($q);
$sql = "SELECT name, age, address FROM book WHERE name LIKE '$q'";
//or
$sql = "SELECT name, age, address FROM book WHERE name LIKE ?";
$stm = $pdo->prepare($sql);
$stm->execute(array($q));
$data = $stm->fetchAll();
}
}
For the output, use
echo htmlspecialchars($_GET['q']);
stripslashes not needed here.
Furthermore, I heard that magic_quotes and charset could in some way or another lead to injections -- is this correct?
magic quotes won't harm your security if you won't use them.
charset is dangerous in case of some extremely rare encodings but only if improperly set. if mysql(i)_set_charset or DSN (in case of PDO) were used for the purpose - you are safe again.
As for PDO, a tag wiki should be enough for starter, I believe
So I do this:
<?php
session_start();
include("../loginconnect.php");
mysql_real_escape_string($_POST[int]);
$int = nl2br($_POST[int]);
$query = "UPDATE `DB`.`TABLE` SET `interests`='$int' WHERE `user`='$_SESSION[user]'";
mysql_query($query) or die(mysql_error());
mysql_close($con);
?>
And let's say that $_POST[int] is "Foo' bar." The single-quote remains unescaped AND I get a MySQL error when running the script, due to the quote. What's wrong?
m_r_e_s() RETURNS the escaped value, it doesn't modify the original.
$int = mysql_real_escape_string($_POST['int']);
$query = "UPDATE ... interests = '$int' ...";
Note that I've added quotes around the int in the POST value. Without the quotes, PHP sees it as a constant value (e.g. define()). If it doesn't find a constant of that name, it politely assumes you meant it to be used a string and adjust accordingly, but issues a warning. If you had done
define('int', 'some totally wonky value');
previously, then you'd be accessing the wrong POST value, because PHP would see it as $_POST[some totally wonky value] instead.
You're not using the results of mysql_real_escape_string in your query.
Try doing this:
$int = nl2br(mysql_real_escape_string($_POST[int]););
You should be using prepared statements. It has a slight learning curve over mysql_* functions, but is well worth it in the long run.
You should quote your strings, like $_POST['int'] instead of $_POST[int].
At the top of your file put error_reporting(-1);
This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 3 years ago.
How do I escape quotes in PHP when trying to query a MySQL database?
Without adding addslashes on every value:
$fname = addslashes("Value's with quote''s'");
$lname = addslashes("Value's with quote''s'");
The proper way is using prepared statements, e.g. via PDO.
If you can't do that, you have to process all values which are passed into a database query with mysql_real_escape_string() - and no, doing that simply on all $_POST data is not an option since that would render them unusable for HTML output, etc. You could create a $_ESC or something similar though... but note that this variable will not be superglobal!
You ought to escape special characters (not only quotes) on every string value (it's useless to escape values you're not going to enclose in quotes in a query. Those values require another treatment).
To avoid boring repetitive typing you can apply an escaping function to array items in a loop.
In case you're using MySQL and for INSERT/UPDATE queries, you can use this helper function:
function dbSet($fields) {
$set = '';
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$set .= "`$field`='" . mysql_real_escape_string($_POST[$field]) . "', ";
}
}
return substr($set, 0, -2);
}
It is used like this:
$id = intval($_POST['id']);
$table = 'users';
$fields = explode(" ","name surname lastname address zip fax phone");
$query = "UPDATE `$table` SET ".dbSet($fields).", `date`=NOW() WHERE id=$id";
Also don't forget to set proper encoding using mysql_set_charset() as it's required for the mysql_real_escape_string() function.
A good idea would be using PDO prepared statements as described here.
It will automatically escape those characters.
Firstly, don't use addslashes() - it is not recommended for use with escaping DB query strings because it doesn't escape everything that actually needs to be escaped; there are some characters that can still get through.
The correct solution depends on the database you're using. Assuming you're using MySQL, the correct function to use instead of addslashes() is mysql_real_escape_string().
You probably notice that using this on every line is even more verbose than addslashes(), so it doesn't really answer your question.
If your fields are all separate variables (as per your example), then you're really stuck with doing that for a bunch of lines of code.
If you're using an array (eg $_POST), then you can do it in a loop, which will make things a lot neater - you can do things like this:
foreach($_POST as $key=>$value) {
$sqlstrings[$key]="`".$key"` = '".mysql_real_escape_string($value)."'";
}
$sql = "update table ".implode(' ',$sqlstrings)." where id=".$update_id;
A more up-to-date method for doing SQL is to use an object model rather than manually building the queries. PHP has a number of libraries that may help: mysqli is an improved MySQL library, and PDO is a database-neutral library. Either of these would give you much better security and flexibility than building the SQL code directly. However if you already have a lot of code in place then they would represent a fairly significant overhead of code changes, so you may want to go with the mysql_real_escape_string() option discussed above in the short term. I do recommend investating them them though.
I have a searchable database of the House and Senate and I just want to make a simple web page that can search this database. The only problem is, while I'm comfortable writing SQL select statements, how do I properly format them for use in PHP?
For example, here's my radio button to select Senators by state:
$sql = "";
if ($_POST['pkChamber'] == "Senate") {
if ($_POST['pkParty'] == "Y") {
$sql = SELECT * FROM senateinfo
WHERE state = (Variable = "stname")
ORDER BY last_name, first_name');
}
else
{
$sql = SELECT * FROM senateinfo
WHERE state = (Variable = "stname")
ORDER BY last_name, first_name
}
}
I am not sure what you're asking for, But I have a good example of reliable and safe way for building WHERE statement dynamically:
$w = array();
$where = '';
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where = "WHERE ".implode(' AND ',$w);
$query = "select * from table $where";
Hope this helps.
Your query seems fine. I think you just need to understand some of the finer points of string parsing in PHP.
When you use double quotations (") to enclose a string, PHP actually will try to parse it looking for variables and/or other php code to process first. Something like this:
$sql = "SELECT * FROM table WHERE state = '{$state}' AND user = {$user->id}";
PHP will substitute out $state for whatever is defined in that variable and the same for the id of whatever user is instantiated in that class. (Also, you don't have to wrap your simple variables in {}. It does help with readability but is only required for class methods/variables.)
If you use single quotes (') to enclose a string, PHP simply treats it like normal. For your above query, I would suggest enclosing it in single quotes like this:
$sql = 'SELECT * FROM senateinfo WHERE state = (Variable = "stname") ORDER BY last_name, first_name)';
If you want to use variables later on in this query, then you will need to escape the double quotations that are in there like this:
$sql = "SELECT * FROM senateinfo WHERE state = (Variable = \"stname\") ORDER BY last_name, first_name)";
This way, PHP doesn't error out thinking you were trying to concatenate strings incorrectly when all you were doing was pasting a query.
You need to focus on one issue at a time.
Try to avoid writing SQL in PHP until you've a clear handle on strings in PHP, and how to inject variables into those strings. So:
Read up on string quoting in PHP (double quotes vs. Single quotes, and yes, HEREDOC)
Read up on variables in strings in PHP (note that if it doesn't have a $ dollar sign, it's a CONSTANT, not a string variable. Start off right with $strings and $variables where they're supposed to be used, not CONSTANTs, which only fall back to turn into strings if nothing else is available.)
Read up on binding SQL in PHP. Anything else will lead you down the path of SQL injection. If there are only naked strings used in your PHP SQL, then you are setting yourself up for failure when you finally deploy your web scripts to the harsh and unforgiving Internet. It's full of sharks ready to take advantage of SQL injection prone scripts.
Here is an example of code I use daily to bind SQL, centered around a custom function that makes it easy:
query("select * where someTable where someTable_id = :bound_id", array(':bound_id'=>13));
I can get you a function for creating bound SQL simply like that later (when I'm actually at a computer instead of mobile) if you're interested.
I use HEREDOCs for writing out non-trivial queries:
$sql = <<<EOL
SELECT blah, blah, blah
FROM table
WHERE (somefield = {$escaped_value}) ...
ORDER BY ...
HAVING ...
EOL;
Heredocs function as if you'd done a regular double-quoted string, but with the bonus of not having escape internal quotes. Variable interpolation works as expected, and you can do indentation on the text as well, so your query looks nicely formatted
I always do mine like this to keep it looking nice.
$sql = "SELECT * FROM senateinfo " .
"WHERE state = (Variable = "stname") " .
"ORDER BY last_name, first_name')";