A LIST Apart: For People Who Make Websites

No. 152

Discuss: Build a PHP Switcher

Pages

 <  1 2 3 4 5 >  Last »

21 Dumb question

OK, this is probably showing some ignorance on my part, but doesn’t this method (stage two, detecting styles) require all pages using the switcher to be parsed by php? A <?php echo (!$sitestyle)?‘defaultstyle’:$sitestyle ?> in a “link” tag isn’t going to be executed in a plain HTML page unless the server is configured to have PHP parse .html as well as .php, right? And mod_perl pages and other things with their own handlers wouldn’t do anything with PHP instructions either. Am I missing something?

posted at 11:02 am on October 14, 2002 by

22 Re: Dumb questions

You aren’t missing anything. The PHP snippet to echo the stylesheet name requires the page to be parsed as PHP.
But it’s possible to achieve the same effect with [removed] read a cookie named ‘stylesheet’, if it doesn’t exist, make stylesheet = a default string. “This is left as an exercise for the reader.” :)

posted at 11:13 am on October 14, 2002 by michel v

23 A better way?

There is more chance that a user will have cookies disabled than JavaScript disabled. All the above will not work without cookies.
I am using SESSIONS in my version, this script assumes that PHP 4.2+ is installed and that register_globals is off with —enable-trans-sid.

Code as below:

<?php
session_start();
?>
<?php
if(isset($_GET[‘css’])){
switch ($_GET[‘css’]) { case ‘css1’: $stylesheet = ‘<link href=“theme1.css” type=“text/css” rel=“stylesheet”>’; $_SESSION[‘csschanger’]=$stylesheet; break; case ‘css2’: $stylesheet = ‘<link href=“theme2.css” type=“text/css” rel=“stylesheet”>’; $_SESSION[‘csschanger’]=$stylesheet; break; case ‘css3’: $stylesheet = ‘<link href=“theme3.css” type=“text/css” rel=“stylesheet”>’; $_SESSION[‘csschanger’]=$stylesheet; break; case ‘css4’: $stylesheet = ‘<link href=“theme4.css” type=“text/css” rel=“stylesheet”>’; $_SESSION[‘csschanger’]=$stylesheet; break; default: $stylesheet = ‘<link href=“cssdefault.css” type=“text/css” rel=“stylesheet”>’; $_SESSION[‘csschanger’]=$stylesheet;
}
}
?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html >
<head>
<title>CSS Changer</title>
<meta http-equiv=“Content-Type” content=“text/html; charset=iso-8859-1” />
<?php echo ($_SESSION[‘csschanger’])? $_SESSION[‘csschanger’]: ‘<link href=“cssdefault.css” type=“text/css” rel=“stylesheet”>’ ;?>
</head>

<body>
[url=”<?php echo $_SERVER[‘PHP_SELF’]; ?>?css=css1”]Stylesheet 1[/url]

[url=”<?php echo $_SERVER[‘PHP_SELF’]; ?>?css=css2”]Stylesheet 2[/url]

[url=”<?php echo $_SERVER[‘PHP_SELF’]; ?>?css=css3”]Stylesheet 3[/url]

[url=”<?php echo $_SERVER[‘PHP_SELF’]; ?>?css=css4”]Stylesheet 4[/url]

</body>
</html>

As an extra, for future visits, you could of course set a cookie as well, but this method would not need cookies or JavaScript to work during the users SESSION. If cookies were disabled, then the SID would be passed with the URL, or you could even code the SID in if enable-trans-sid is not compiled on your server.

posted at 11:54 am on October 14, 2002 by Peter Hawkes

24 a better way, indeed.

Thank you, Peter Hawkes! This is exactly what I was hoping to find, and even better, it works. PHP rocks.

For those still using older versions of PHP:

change $_GET to $HTTP_GET_VARS
change $_SESSION to $HTTP_SESSION_VARS
change $_SERVER to $HTTP_SERVER_VARS

thanks again. cheers, Robert Roberts

posted at 10:24 pm on October 14, 2002 by Robert Roberts

25 hows this for cool

The person who suggested PHP be put in the CSS document was real close – you can’t put PHP inside a .css file, since .css isn’t parsed by PHP unless you set it to, so here’s an easier trick:

Use a CSS document name of <file>.php – the file will (haven’t tested this, but it makes sense) be parsed by PHP before being shipped off to the client when they request it. As long as you make sure to define it as text/css, the browser shouldn’t care about it’s extension.

In the <file>.php file, just put all the code you need to do your dirty work. Oh and a tip for this… don’t use cookies with long expiry dates – set the expiry time to 0, which will make it die as soon as the browser closes (at the end of a “session”). Also, as mentioned before, don’t let people set whatever they want :) Whenever you accept user input, you have to take every precaution imaginable to prevent someone mis-using your scripts.

posted at 10:03 pm on October 15, 2002 by

26 HTML Insertion attack

One week after I’d finished my own version of this it appears here. Never mind.

My version is different in that it doesn’t use GET variables to set the cookie. At the moment my switch-style links point to locations of the form: /ui/configure/“style-to-apply”/. Whilst this means that at the moment I am having to put code in each subdirectory it does mean that the only way to do an HTML insertion attack is to change the actual value of the cookie.

Whilst this is not the best solution to the problem it avoid the injection attack. One way to make the code easier to maintain would be to use the techniques from http://www.alistapart.com/stories/succeed/ the mod_rewrite article to redirect requests to the subdirectory to a script that could encode the correct cookie.

Just a thought. Great article, can’t wait for next weeks.

posted at 03:27 am on October 16, 2002 by Lllama

27 um ..

>>>>>>
In the <file>.php file, just put all the code you need to do your dirty work. Oh and a tip for this… don’t use cookies with long expiry dates – set the expiry time to 0, which will make it die as soon as the browser closes (at the end of a “session”).
>>>>>>

what would be the point of using a cookie then if you’re setting it to 0? If that’s the case then you should be using a session variable instead.

posted at 09:12 am on October 16, 2002 by D K

28 um

what would be the point of setting the cookie to 0 ?? If you want it removed at the end of a session , just use a session variable instead.

posted at 09:13 am on October 16, 2002 by D K

29 re: um's

What’s the point of having ‘save’ on the file menu? It gives you different ways of doing the same thing.

Also, regarding the suggestion that, without checking, a malicious user could run their own PHP code: not possible. For this to happen, the script must contain an eval() statement or something that uses unchecked user input.

posted at 07:52 pm on October 16, 2002 by Linus

30 minor quibble about code style.. ? :

where the example uses (!$foo) ? ‘default’ : $foo

it would be much clearer to simply write

$foo ? $foo : ‘default’

because then you don’t have to parse the negation as well, and neither does the computer.

posted at 07:23 am on October 17, 2002 by

Pages

 <  1 2 3 4 5 >  Last »

Discussion Closed

New comments are not being accepted, but you are welcome to explore what people said before we closed the door.

Got something to say?

Discuss this article. We reserve the right to delete flames, trolls, and wood nymphs.

Create a new account or sign in below if you’d like to leave a comment.

Remember me

Forgot your password?

Subscribe to this article's comments: RSS (what’s this?)