0

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");
2
  • Can you post the relevant bits of code? Also, is the server error returned when loading x.php or content.php? Commented Jun 3, 2011 at 1:58
  • @GargantuChe also 500 error is resulting from content.php not x.php Commented Jun 3, 2011 at 2:10

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Great. You got it. Concatenation was definitely an issue. Along with other things i did, it works now.
i'm Just wondering why do i need to use mysql_real_string_escape knowing that i'm only selecting and not inserting. Can you clarify.
@Pinkie, I updated the post to include examples. The short version is that a user could disable or alter your WHERE clause, and cause the query to return just about anything they wanted. Let me know if it makes sense. Thanks!
Thanks for the detailed explanation and examples. It's clear now.
1

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:

  1. Put the contents of $_GET['user'] into the page as a <param> and then have your flash object add that to its request.
  2. Have flash get the information from the query string using the technique from this other article.

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.

7 Comments

@JoshuaRogers Can you clarify your answer. How i put my $_GET as a <param> and how i have the flash object add that to it's request. I wouldn't be asking if knew the answers.
In x.php, add so.addParam("user", "<?php print urlencode($_GET['user']) ?>"); Within your .as, you would change the code to load as follows: var user:String = swfobject.getQueryParamValue("user"); xmlData.load("content.php?user=" + user); You should be aware, however, the code above is vulnerable to SQL injection. Should the user add ?user="Jim"; DELETE FROM users, you would likely find the users table wiped clean. [php.net/manual/en/function.addslashes.php/] I'd recommend PHP's addslashes.
Also, it appears that content.php is failing because there should be quotes around the $_GET['user'] in your SQL.
@JoshuaRogers i added addParam and also modified the .as file as per your instruction. I not getting results although the 500 error is gone now. You didn't mention anything about the sql query. Do i just keep it as b.user_name=\'$_GET["user"]\'
@JoshuaRogers Looking at the request logs i see Request URL:http://domain.com/contentp.php?user=undefined. I'm getting undefined. I'm not so sure user s being passed correctly. Any ideas. By the way i have var user:String = swfobject.getQueryParamValue("user"); in my .as file. Is this correct. I'm assuming that's where it should go
|
1

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

2 Comments

The link you refered me to is not using swfobject. As per @JoshuaRogers help, i added so.addParam("user", "<?php print urlencode($_GET['user']) ?>"); as an swfobject parameter and in my .as file i added var user:String = swfobject.getQueryParamValue("user"); and modified xmlData.load("content.php?user=" + user); In my sql query i have b.user_name=\'$_GET["user"]\' now when i run the player looking at the request logs i see http://domain.com/contentp.php?user=undefined. Not getting results. Any idea why i'm getting undefined.
@Pinkie, sorry for the bad link as, as far as your new problem goes I believe (but I'm no expert) that variables should be passed using flashvars as written about here and here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.