Reputation: 10246
I have a flash player embedded on page x.php?user=john using swfobject. The player calls the xml file content.php to get the results. in content.php i have $_GET['user']. I'm trying to get the user name from the url id and fetch results based on that. I'm however getting a 500 error. I don't think content.php is able to access the user
variable. if i just put in the username "john" instead of $_GET['user'] then it works. How can i get this to work with $_GET['user']
XML file content.php looks like this
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=$_GET['user'] and... //if i replace $_GET['user'] with john then it works
In x.php flash is embeded like this
<script type="text/javascript">
var flashvars = {};
var so = new SWFObject("play2.swf", "sotester", "1000", "400", "8", "#000000");
so.addParam("allowFullScreen", "true");
so.addParam("scale", "noscale");
so.addParam("menu", "false");
so.write("flashcontent");
</script>
My Player Actionscript is of course pointing to content.php which is not the issue here
xmlData.load("contentp.php");
Upvotes: 0
Views: 544
Reputation: 5779
Pinkie, thanks for posting the code.
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=$_GET['user'] and... //if i replace $_GET['user'] with john then it works
There are a few issues here, but we can work through them.
A syntax error is introduced when you change the string. You have the right idea with the way $video
and $users
. But when adding the $_GET['user']
, PHP thinks that the first apostrophe is ending the current string.
Consider that:
' where b.user_name=$_GET['user'] and...'
looks like two strings, separated by the word "user":
' where b.user_name=$_GET[' user '] and...'
This isn't proper syntax, so the 500 error is returned. I'm guessing that your error would go away if you tried:
' where b.user_name=' . $_GET['user'] . ' and...'
The next issue is that if a user were to send a carefully crafted value for the "user" parameter, they could cause the query to behave in a way that you didn't intend.
Try this: create a file called login.php, with the following content:
<?php
// Just display the output; no HTML formatting needed
header("Content-Type: text/plain");
// This must succeed, or mysql_real_escape_string() won't have any effect
mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
$safeQuery = 'SELECT count(*) FROM users WHERE user=\'' . mysql_real_escape_string($_GET['username']) . '\' AND pass=\'' . mysql_real_escape_string($_GET['password']) . '\';';
echo " safeQuery is: $safeQuery\n";
$unsafeQuery = 'SELECT count(*) FROM users WHERE user=\'' . $_GET['username'] . '\' AND pass=\'' . $_GET['password'] . '\';';
echo "unsafeQuery is: $unsafeQuery\n";
?>
Load login.php?username=bob&password=sample
. The output looks reasonable:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
Now try loading login.php?username=bob&password=sample' OR 'hello'='hello"
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample\' OR \'hello\'=\'hello';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample' OR 'hello'='hello';
The safe query will return zero, unless you have a user called bob whose password really is sample' OR 'hello'='hello"
.
The unsafe version, however, will return the total count of users in the database. The WHERE clause is now:
WHERE user='bob' AND pass='sample' OR 'hello'='hello'
The OR 'hello'='hello'
will make the condition true in all cases, even if bob
doesn't exist or has a password other than sample
.
Part of your query could even be commented out. Try login.php?username=bob' --
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob\' --' AND pass='';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' --' AND pass='';
The password parameter is now ignored, because it's embedded within a SQL comment.
So even if you're just executing a SELECT statement, the results can be manipulated by a clever user if their inputs weren't escaped.
You can use mysql_real_escape_string to protect against such bad values. This function will add backslashes where necessary to keep input data from being executed as SQL.
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=\'' . mysql_real_escape_string($_GET['user']) . '\' and...';
Example 1 from the php.net page for mysql_real_escape_string has a great example using sprintf:
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
Each %s
is replaced with the parameters (in the order they are specified). This makes it easier to keep your query readable, while protecting against bad input data.
Upvotes: 2
Reputation: 3292
So Joshua definitely has the right idea, but let me see if I can clarify and expand on it a little.
Essentially you should pass the GET variable to flash using the flash vars param (you can read an excellent tutorial on it here). Once flash has the variable it should append the query for content.php with ?yourNewGetVariable=ValuePassedOnToFlash
, and Joshua is right before you pass on that value you should definitely sanitize it and encode it for URL's. Then your content.php file should have no problem accessing yourNewGetVariable
Upvotes: 1
Reputation: 405
So, if I'm reading this correctly, when a user visits the page at x.php?user=john, your server is returning a page that contains a flash object. That flash object in turn attempts to load the xml page at content.php. You are correct that content.php cannot access any of the $_GET variables from x.php, because they are two completely different requests.
There are two things that you could do:
I feel this deserves a warning though, please remember to sanitize the contents of the query string before using it, so that you won't end up with a CSS or SQL injection vulnerability.
Upvotes: 1