PHP help. The <?=$variable?> shortcut isn't working

Doesn’t seem to achieve the safe query…



<form method = post action = <?=$_SERVER['PHP_SELF']?>>
Enter a name <input type=text name=name />
<input type=submit name=submit />
</form>

<?php
if (isset($_POST['submit']))
{

$string = "select * from atable where name = '" . $_POST['name'] . "'";

echo $string;

echo "<br>";

$goodinput = addslashes($_POST['name']);

$string = "select * from atable where name = '" . $goodinput . "'";

echo $string;

}
?>


Output… (with “’; drop table wargaarble;” as the input)

select * from atable where name = ‘’; drop table wargaarble;’
select * from atable where name = ‘’;drop table wargaarble;’
which could still perform the database actions after the ;

I know it seems lazy to ask that, (and yes I’m lazy) but I think people are more likely to put the effort in to sanitize their sql if it is a straightforward excercise.

And I am sure that when it comes time for moi to create a mysql based publicly accessable php data access system I will properly santize the code using the ‘complicated’ established correct way. But at the learning stage it is beneficial to be able to play with code features without having to make real connections to databases, and since the functions are working on strings and not on data directly, it seems odd that these functions would be so closely tied to the database components/objects such that it isn’t apparent how to test/play with them without putting in the data access elements (not to mention actually having a database to work on, which I don’t at work, not a mysql one anyway)

So again. Apologies for wanting to be lazy about this.

Lobsang has been trying to help me via PMs, examining my unsuccessful PHP code and making useful suggestions.

Despite his efforts, and mine (such as they are), I am still not successful at writing a routine whereby a find query would be POSTed from one .html file and the input received by a .php file and the input value used along with other criteria as the query string.
Here is my current code for the form.html document in which a user would type in a caseworker’s name and submit it, either to the (currently nonworking) php file that attempts to query the MySQL database or to a debugging php file that just echoes back the parsed string:

[noparse]<html>
<head></head>
<body>
<form action=“nextsqlphp.php” method=“post”>
Enter your find request: <input type=“text” name=“msg” size=“30”>
<input type=“submit” value=“Send”>
</form>
<form action=“wtfsqlphp.php” method=“post”>
Test syntax of your find request: <input type=“text” name=“msg” size=“30”>
<input type=“submit” value=“Send”>
</form>
</body>
</html>
[/noparse]

When sent from the second form (“Test syntax of your find request”), the file wtfsqlphp.php obligingly echoes back this string: select client.firstname, client.lastname, reoptxfr.casetype, reoptxfr.datefield, reoptxfr.closedon from client, reoptxfr WHERE client.assignedworkerslastname = ‘hunter, allan’ and client.statusofcase = ‘1 Active Case’ and client.clientid = reoptxfr.clientid order by client.lastname, client.firstname, reoptxfr.sequencenumber

But when sent from the first form (“Enter your find request”), the file nextsqlphp.php loads as a blank page. It’s supposed to be performing as a query the above bolded string and then return the results. This same page’s code works fine if I use a hardwired query instead of trying to snag the input from form.html, so that must be the place where I’m doing something wrong. Here’s the code for the file nextsqlphpl.php:

[noparse]
<html>
<head></head>
<body>

<?php

$connection = mysql_connect(‘localhost’, ‘guest’, ‘pass’);
input = _POST [‘msg’];
mysql_select_db (‘ebcoa’);

$result = mysql_query (‘select client.firstname, client.lastname, reoptxfr.casetype, reoptxfr.datefield, reoptxfr.closedon from client, reoptxfr WHERE client.assignedworkerslastname = ‘’.$input.’’ and client.statusofcase = ‘1 Active Case’ and client.clientid = reoptxfr.clientid order by client.lastname, client.firstname, reoptxfr.sequencenumber’);
if (mysql_num_rows ($result) >0)
{
echo ‘<table width=100% cellpadding=10 cellspacing=0 border=1>’;
echo
‘<tr><td><b>FIRSTNAME</b></td><td><b>LASTNAME</b></td><td><b>CASETYPE</b></td><td><b>OPENED</b></td><td><b>CLOSED</b></td></tr>’;wq
while($row = mysql_fetch_row($result))
{
echo ‘<tr>’;
echo ‘<td>’ . $row[0] . ‘</td>’;
echo ‘<td>’ . $row[1] . ‘</td>’;
echo ‘<td>’ . $row[2] . ‘</td>’;
echo ‘<td>’ . $row[3] . ‘</td>’;
echo ‘<td>’ . $row[4] . ‘</td>’;
echo ‘</tr>’;
}
echo ‘</table>’;
}
else
{
echo ‘No rows found!’;
}

mysql_free_result ($result);

mysql_close($connection);
?>

</body>
</html>
[/noparse]

(I’m clueless about PHP)
To answer your question, though, it appears that the mysql_real_escape_string() function is indeed your sanitize() function.

In Oracle databases, we go through all of that faffing about for type safety and performance reasons.
Since the query itself is a static text string, not changing in length with each different last name, the SQL only needs to be parsed once, and is theoretically sitting pre-parsed in cache the next time we need it.
I always take that with a grain of salt, imagining that it shaves a millisecond off of what may be a five-second query. Nevertheless, using the “?” placeholders is a great way to avoid all of the SQL syntax hassles that come from the O’Brians of the world.

Largely off-topic, but my recommendation for PHP is to not try and intersperse HTML and PHP code. All of my PHP coding uses objects that encapsulate HTML tags. They all have, at minimum:

->set()
->setStyle()
->setClass()
->setName()
->get()

Plus some item-specific methods. Particularly my Table class has a lots of ways to build complex tables programmatically (I would need to write some examples to illustrate it.)

For instance, the following:


define("PAGE_STYLE", "background-color: yellow;");

$page = new Page("Titlebar Greeting!"); // html, head, title, and body tags
$page->setStyle(PAGE_STYLE); // operates on the body
$page->set("Hello world!"); // operates on the body

echo $page->get();

This turns into:



<html>
    <head>
        <title>Titlebar Greeting!</title>
    </head>
    <body style="background-color: yellow;">
        Hello world!
    </body>
</html>


I wouldn’t say it necessarily saves you any typing (though it probably does by a little bit in the long run), but it lets you have everything in one language, properly indented code throughout, a linear construction that is independent of the output HTML, and comments. Interspersing PHP through a page of HTML just looks ugly and can be confusing. It makes it hard to structure things like a regular program.

Anyways, if you’re interested I can write up some documentation. Here’s the file (just retitle it as .php)

http://www.aahz.com/random/html.txt

Quoted, so you know who I’m replying to.

You have an extraneous wq after the line:
[noparse]’<tr><td><b>FIRSTNAME</b></td><td><b>LASTNAME</b></td><td><b>CASETYPE</b></td><td><b>OPENED</b></td><td><b>CLOSED</b></td></tr>’;
[/noparse]
If you don’t have any error reporting turned on, then the page is die’ing without you knowing about it, hence the lack of output. Reporting can be turned on in your php.ini file like this:
error_reporting = E_ALL & ~E_NOTICE

If you change this you will need to restart your webserver to pick up the new php.ini file.

If you have error reporting turned on, you should get this message:

Parse error: syntax error, unexpected T_WHILE in C:\Apache\caw est
extsqlphp.php on line 19

When I removed the wq from the code, it works fine here.

Except that it doesn’t. Not being sarcastic, but did you actually try it?

The 1st query is malformed and you should get an error back something like this.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘; drop table wargaarble;’’ at line 1

The reason this one fails is that you have 3 single quotes. They are unmatched so the query doesn’t execute.

What the 2nd query is doing is looking for a name which is equal to this string exactly ';drop table wargaarble;

The ’ is not being treated as a delimiter, but is actually part of the value that is trying to be matched. The \ in front of the ’ (i.e. ') tells the query that this is part of the value and not the end of the field to be searched.

i.e. If the name was o’brian then the 2nd query would be like this (perfectly valid).
select * from demotivations where date = ‘o’brian’


$query = "select * from atable where date = '" . $_POST['name'] . "'";


It’s the ’ at the start and end that cause the SQL injection to fail as you are encapsulating the string in quotes. If you were to take them away, then the problem arises.

So, in summary:
Ensure that you are encapsulating your parameters with a ’ (single quote) or " (double quote) at either end as you have done.
Ensure that you escape (addslashes) your variables to avoid unescaped quotes.