Question on use of ternary operator
Moderator: General Moderators
- akimm
- Forum Contributor
- Posts: 460
- Joined: Thu Apr 27, 2006 10:50 am
- Location: Ypsilanti Michigan, formally Clipsburgh
Question on use of ternary operator
To use ternary operator do I need to use GET. I'm just trying to incomperate ternary into my next program so I can learn how to utilize it. I don't need anything at this point except an answer if possible.
You can use the tenerary in any condition
Code: Select all
$var = ( isset($var1) ) ? "ya" : "non";- akimm
- Forum Contributor
- Posts: 460
- Joined: Thu Apr 27, 2006 10:50 am
- Location: Ypsilanti Michigan, formally Clipsburgh
something like this?
Code: Select all
echo "<h2><a href=\"".$_SERVER['PHP_SELF'];
if ($part != $char) echo "?part=".$char;
echo "\">- ".$char." -</a></h2>\n"sure?I wouldn't get into a habit of using $_SERVER['PHP_SELF'] as it contains user input.
http://www.php.net/manual/en/reserved.variables.php wrote:'PHP_SELF'
The filename of the currently executing script, relative to the document root. For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar would be /test.php/foo.bar. The __FILE__ constant contains the full path and filename of the current (i.e. included) file.
taken from elsewhere
A predominant PHP developer (whose name I didn't get permission to drop, so I won't, but many of you know who I mean) has been doing a bunch of research related to Cross Site Scripting (XSS), lately. It's really opened opened my eyes to how much I take user input for granted.
Don't get me wrong. I write by the "never trust users" mantra. The issue, in this case, is something abusable that completely slipped under my radar.
Most developers worth their paycheque, I'm sure, know the common rules of "never trust the user", such as "escape all user-supplied data on output," "always validate user input," and "don't rely on something not in your control to do so (ie. Javascript cannot be trusted)." "Don't output unescaped input" goes without saying, in most cases. Only a fool would "echo $_GET['param'];" (and we're all foolish sometimes, aren't we?).
The problem that was demonstrated to me exploited something I considered to be safe. The filename portion of request URI. Now I know just how wrong I was.
Consider this: you build a simple script; let's call it simple.php but that doesn't really matter. simple.php looks something like this:
Alright. Let's put this script at: http://example.com/tests/simple.php. On a properly-configured web server, you would expect the script to always render to this, on request:
Right? No.
What I forgot about, as I suspect some of you have, too (or maybe I'm the only loser who didn't think of this (-; ), is that $_SERVER['PHP_SELF'] can be manipulated by the user.
How's that? If I put a script at /simple/test.php, $_SERVER['PHP_SELF'] should always be "/simple/test.php", right?
Wrong, again.
See, there's a feature of Apache (I think it's Apache, anyway) that you may have used for things like short URLs, or to optimize your query-string-heavy website to make it search-engine friendly. $_SERVER['PATH_INFO']-based URLs.
Quickly, this is when scripts are able to receive data in the GET string, but before the question mark that separates the file name from the parameters. In a URL like http://www.example.com/download.php/path/to/file, download.php would be
executed, and /path/to/file would (usually, depending on config) be available to the script via $_SERVER['PATH_INFO'].
The quirk is that $_SERVER['PHP_SELF'] contains this extra data, opening up the door to potential attack. Even something as simple the code above is vulnerable to such exploits.
Let's look at our simple.php script, again, but requested in a slightly different manner:
http://example.com/tests/simple.php/extra_data_here
It would still "work"--the output, in this case, would be:
I hope that the problem is now obvious. Consider:
http://example.com/tests/simple.php/%22 ... t%3E%3Cfoo
The output suddenly becomes very alarming:
If you ignore the obviously-incorrect <foo"> tag, you'll see what's happening. The would-be attacker has successfully exploited a critical (if you consider XSS critical) flaw in your logic, and, by getting a user to click the link (even through a redirect script), he has executed the Javascript of his choice on your user's client (obviously, this requires the user to have Javascript enabled). My alert() example is non-malicious, but it's trivial to write similarly-invoked Javascript that changes the action of a form, or usurps cookies (and submits them in a hidden iframe, or through an image tag's URL, to a server that records this personal data).
The solution should also be obvious. Convert the user-supplied data to entities. The code becomes:
And an attack, as above, would be rendered:
This still violates the assumption that the script name and path are the only data in $_SERVER['PHP_SELF'], but the payload has been neutralized.
Needless to say, I felt silly for not thinking of such a simple exploit, earlier. As the aforementioned PHP developer said, at the time (to paraphrase): if guys who consider themselves experts in PHP development don't notice these things, there's little hope for the unwashed masses who have just written their first 'echo "hello world!\n";'. He's working on a generic user-input filtering mechanism that can be applied globally to all user input. Hopefully we'll see it in PECL, soon. Don't forget about the other data in $_SERVER, either..
... ...
Upon experimenting with this exploit on my own server (and watching the raw data in my _SUPERGLOBALS, conveniently, via phpinfo()), I noticed something very interesting that reminded me that even though trusting this data was a stupid mistake on my part, I'm not the only one to do so. A fun (and by fun, I mean nauseating) little game to play: create a file called "info.php" (or whatever name you like). In it, place only "<php phpinfo(); ?>". Now request it like this:
http://your-server/path/to/info.php/%22 ... %3E%3Cblah
Nice huh? A little less nauseating: it's fixed in CVS.
A predominant PHP developer (whose name I didn't get permission to drop, so I won't, but many of you know who I mean) has been doing a bunch of research related to Cross Site Scripting (XSS), lately. It's really opened opened my eyes to how much I take user input for granted.
Don't get me wrong. I write by the "never trust users" mantra. The issue, in this case, is something abusable that completely slipped under my radar.
Most developers worth their paycheque, I'm sure, know the common rules of "never trust the user", such as "escape all user-supplied data on output," "always validate user input," and "don't rely on something not in your control to do so (ie. Javascript cannot be trusted)." "Don't output unescaped input" goes without saying, in most cases. Only a fool would "echo $_GET['param'];" (and we're all foolish sometimes, aren't we?).
The problem that was demonstrated to me exploited something I considered to be safe. The filename portion of request URI. Now I know just how wrong I was.
Consider this: you build a simple script; let's call it simple.php but that doesn't really matter. simple.php looks something like this:
Code: Select all
<html>
<body>
<?php
if (isset($_REQUEST['submitted']) && $_REQUEST['submitted'] == '1') {
echo "Form submitted!";
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>Alright. Let's put this script at: http://example.com/tests/simple.php. On a properly-configured web server, you would expect the script to always render to this, on request:
Code: Select all
<html>
<body>
<form action="/tests/simple.php">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>What I forgot about, as I suspect some of you have, too (or maybe I'm the only loser who didn't think of this (-; ), is that $_SERVER['PHP_SELF'] can be manipulated by the user.
How's that? If I put a script at /simple/test.php, $_SERVER['PHP_SELF'] should always be "/simple/test.php", right?
Wrong, again.
See, there's a feature of Apache (I think it's Apache, anyway) that you may have used for things like short URLs, or to optimize your query-string-heavy website to make it search-engine friendly. $_SERVER['PATH_INFO']-based URLs.
Quickly, this is when scripts are able to receive data in the GET string, but before the question mark that separates the file name from the parameters. In a URL like http://www.example.com/download.php/path/to/file, download.php would be
executed, and /path/to/file would (usually, depending on config) be available to the script via $_SERVER['PATH_INFO'].
The quirk is that $_SERVER['PHP_SELF'] contains this extra data, opening up the door to potential attack. Even something as simple the code above is vulnerable to such exploits.
Let's look at our simple.php script, again, but requested in a slightly different manner:
http://example.com/tests/simple.php/extra_data_here
It would still "work"--the output, in this case, would be:
Code: Select all
<html>
<body>
<form action="/tests/simple.php/extra_data_here">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>I hope that the problem is now obvious. Consider:
http://example.com/tests/simple.php/%22 ... t%3E%3Cfoo
The output suddenly becomes very alarming:
Code: Select all
<html>
<body>
<form action="/tests/simple.php/"><script>alert('xss')</script><foo">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>If you ignore the obviously-incorrect <foo"> tag, you'll see what's happening. The would-be attacker has successfully exploited a critical (if you consider XSS critical) flaw in your logic, and, by getting a user to click the link (even through a redirect script), he has executed the Javascript of his choice on your user's client (obviously, this requires the user to have Javascript enabled). My alert() example is non-malicious, but it's trivial to write similarly-invoked Javascript that changes the action of a form, or usurps cookies (and submits them in a hidden iframe, or through an image tag's URL, to a server that records this personal data).
The solution should also be obvious. Convert the user-supplied data to entities. The code becomes:
Code: Select all
<html>
<body>
<?php
if (isset($_REQUEST['submitted']) && $_REQUEST['submitted'] == '1') {
echo "Form submitted!";
}
?>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>And an attack, as above, would be rendered:
Code: Select all
<html>
<body>
<form action="/tests/simple.php/"><script>alert('xss')</script><foo">
<input type="hidden" name="submitted" value="1" />
<input type="submit" value="Submit!" />
</form>
</body>
</html>This still violates the assumption that the script name and path are the only data in $_SERVER['PHP_SELF'], but the payload has been neutralized.
Needless to say, I felt silly for not thinking of such a simple exploit, earlier. As the aforementioned PHP developer said, at the time (to paraphrase): if guys who consider themselves experts in PHP development don't notice these things, there's little hope for the unwashed masses who have just written their first 'echo "hello world!\n";'. He's working on a generic user-input filtering mechanism that can be applied globally to all user input. Hopefully we'll see it in PECL, soon. Don't forget about the other data in $_SERVER, either..
... ...
Upon experimenting with this exploit on my own server (and watching the raw data in my _SUPERGLOBALS, conveniently, via phpinfo()), I noticed something very interesting that reminded me that even though trusting this data was a stupid mistake on my part, I'm not the only one to do so. A fun (and by fun, I mean nauseating) little game to play: create a file called "info.php" (or whatever name you like). In it, place only "<php phpinfo(); ?>". Now request it like this:
http://your-server/path/to/info.php/%22 ... %3E%3Cblah
Nice huh? A little less nauseating: it's fixed in CVS.
-
mikesmith76
- Forum Commoner
- Posts: 34
- Joined: Fri Aug 25, 2006 7:10 am
- Location: Manchester, UK
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA
I had written a little function (before feyd taught me basename() ) that took the page based on $_SERVER['PHP_SELF'] and stripped everything out of it except the name of the page. If I can find it, I will post it for review/appreciation/condemnation. I never use $_SERVER['PHP_SELF'] by itself.
EDIT | Found it. I haven't tested this against XSS (nor have I tested basename() against XSS).
EDIT | Found it. I haven't tested this against XSS (nor have I tested basename() against XSS).
Code: Select all
<?php
function get_page_name($page_name = '')
{
if ($page_name == '')
{
$page_name = $_SERVER['PHP_SELF'];
}
//This is added to handle page names with query strings
if ( strpos($page_name, '?') )
{
$page_name = substr($page_name,0,(strlen($page_name)-strpos($page_name, '?')));
}
$page = substr($page_name,0,strlen($page_name)-4);
$page_array = explode("/",$page);
$page_array_index = count($page_array)-1;
$page = $page_array[$page_array_index];
return $page;
}
?>
Last edited by RobertGonzalez on Fri Sep 15, 2006 11:50 am, edited 1 time in total.
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA