|
| Designskifte og cookie Fra : Erik Ginnerskov |
Dato : 11-02-07 00:57 |
|
Hej NG
Jeg sidder og prøver at tilføje cookie-styring af et script, der giver
mulighed for at vælge mellem en række forud definerede sidelayouts.
Jeg synes, at jeg har lavet min cookie-kode sådan, som det er forklaret i
min ellers dyre-nok php-bog:
<?php
define('BASICSTYLESHEET', '../hss-main.css');
function is_harmful($userstring) {
$harmless = array('../hss-main.css','ds2.css','ds3.css');
$harmful = array('@','%',"\\",'<','>','(',')',';','script','http','www');
$lowcasestring=strtolower($userstring);
$newstring=str_replace($harmful,$harmless,$lowcasestring);
// Hvis de er forskellige, var der en udskiftning - der var altså nogle
farlige tegn:
return $newstring!=$lowcasestring;
}
// Hovedrutinen:
if (isset($_GET["style"])) $style=$_GET['style']; // Saml input op - også en
tom streng.
if (is_harmful($style) || $style=='') $style=BASICSTYLESHEET;
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+30, "/",
" http://hjemmesideskolen.dk", 0);
?>
Designskiftet kører helt uproblematisk, men der bliver ikke sat nogen cookie
(aflæsning af cookien gemmer jeg indtil der er noget at aflæse).
Jeg har lavet et par testsider:
http://hjemmesideskolen.dk/usenet/designskift.php
http://hjemmesideskolen.dk/usenet/setcookie.php
Sidstnævnte kan I prøve at kalde med parametrene
?style=../hss-main.css
?style=ds2.css
?style=ds3.css
.... og navnet på den valgte css bliver udskrevet med en <? echo $style; ?>
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
Michael Zedeler (11-02-2007)
| Kommentar Fra : Michael Zedeler |
Dato : 11-02-07 16:00 |
|
Erik Ginnerskov skrev:
>
> Jeg sidder og prøver at tilføje cookie-styring af et script, der giver
> mulighed for at vælge mellem en række forud definerede sidelayouts.
>
> Jeg synes, at jeg har lavet min cookie-kode sådan, som det er forklaret i
> min ellers dyre-nok php-bog:
Lige omkring is_harmful(). For det første er der et problem i din
håndtering af ikke-tilladte værdier. Du har en lister over de tegn, du
ikke vil tillade - det er langt mere usikkert end at have en liste over
de tegn, du vil tillade. Dernæst er funktionen unødvigt kompleks. Du kan
nøjes med dette her:
function is_harmful($string) {
return !preg_match('^[[:alnum:]\.-_]+$');
}
(Med forbehold for mindre fejl.)
> setcookie("phpdesignskifte", $style, time()+30, "/",
> " http://hjemmesideskolen.dk", 0);
> ?>
>
> Designskiftet kører helt uproblematisk, men der bliver ikke sat nogen cookie
> (aflæsning af cookien gemmer jeg indtil der er noget at aflæse).
Der er ingen grund til at medtage de to sidste parametre. I manualen
står der:
> setcookie() defines a cookie to be sent along with the rest of the HTTP headers.
> Like other headers, cookies must be sent before any output from your script (this
> is a protocol restriction).
Har du sikret dig at det sker før dit script genererer andet output?
Og et sidste p.s.: husk at indentere din kode - det gør det meget
nemmere at arbejde med.
Mvh. Michael.
--
Which is more dangerous? TV guided missiles or TV guided families?
I am less likely to answer usenet postings by anonymous authors.
Visit my home page at http://michael.zedeler.dk/
| |
Erik Ginnerskov (11-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 11-02-07 23:13 |
|
Michael Zedeler wrote:
> Lige omkring is_harmful(). For det første er der et problem i din
> håndtering af ikke-tilladte værdier. Du har en lister over de tegn, du
> ikke vil tillade - det er langt mere usikkert end at have en liste
> over de tegn, du vil tillade.
Jame, der er allerede en liste over de input, der er tilladte.
> Dernæst er funktionen unødvigt
> kompleks. Du kan nøjes med dette her:
>
> function is_harmful($string) {
> return !preg_match('^[[:alnum:]\.-_]+$');
> }
Muligvis rigtigt, det ændrer bare ikke rigtigt på, at der ikke bliver sat
den nødvendige cookie, jeg siden skal have lavet indlæsning af (i tilfælde
af manglende brugerinput vedrørende style).
>> setcookie("phpdesignskifte", $style, time()+30, "/",
>> " http://hjemmesideskolen.dk", 0);
> Der er ingen grund til at medtage de to sidste parametre.
Det var lige den forskel, der fik scriptet til at sætte den ønskede cookie.
Så kan jeg komme i gang med at lave først en validering, om cookien skal
aflæses og i bekræftende fald lave en aflæsning af den. Jeg vender
"frygtelig" tilbage, når/hvis jeg kører fast i det.
> Har du sikret dig at det sker før dit script genererer andet output?
Jeg har lagt hele scriptet før sidens DTD, hvis det er det, du mener.
> Og et sidste p.s.: husk at indentere din kode - det gør det meget
> nemmere at arbejde med.
Ja, sorry, det var en forglemmelse, skal prøve at huske.
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
Martin (12-02-2007)
| Kommentar Fra : Martin |
Dato : 12-02-07 08:32 |
|
Erik Ginnerskov wrote:
> Hej NG
>
> Jeg sidder og prøver at tilføje cookie-styring af et script, der giver
> mulighed for at vælge mellem en række forud definerede sidelayouts.
>
> Jeg synes, at jeg har lavet min cookie-kode sådan, som det er forklaret i
> min ellers dyre-nok php-bog:
>
> <?php
> define('BASICSTYLESHEET', '../hss-main.css');
>
> function is_harmful($userstring) {
> $harmless = array('../hss-main.css','ds2.css','ds3.css');
> $harmful = array('@','%',"\\",'<','>','(',')',';','script','http','www');
> $lowcasestring=strtolower($userstring);
> $newstring=str_replace($harmful,$harmless,$lowcasestring);
> // Hvis de er forskellige, var der en udskiftning - der var altså nogle
> farlige tegn:
> return $newstring!=$lowcasestring;
> }
>
> // Hovedrutinen:
> if (isset($_GET["style"])) $style=$_GET['style']; // Saml input op - også en
> tom streng.
> if (is_harmful($style) || $style=='') $style=BASICSTYLESHEET;
Tjaa.. det virker sikkert godt nok...
men hvorfor?
if(!in_array($_GET["style"],$harmless)) $style=BASICSTYLESHEET;
else $style = $_GET["style"];
> // læg style-info i coogie
> setcookie("phpdesignskifte", $style, time()+30, "/",
> " http://hjemmesideskolen.dk", 0);
Drop alle de ekstra ting...
Dvs. brug kun de 3 første argumenter.
For at læse den igen.
if(!in_array($_GET["style"],$harmless)) {
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
$style=BASICSTYLESHEET;
} else {
$style=$_COOKIE["phpdesignskifte"];
}
} else {
$style = $_GET["style"];
}
| |
Erik Ginnerskov (12-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 12-02-07 15:15 |
|
Martin wrote:
> Tjaa.. det virker sikkert godt nok...
> men hvorfor?
>
> if(!in_array($_GET["style"],$harmless)) $style=BASICSTYLESHEET;
> else $style = $_GET["style"];
>
>> // læg style-info i coogie
>> setcookie("phpdesignskifte", $style, time()+30, "/",
>> " http://hjemmesideskolen.dk", 0);
>
> Drop alle de ekstra ting...
> Dvs. brug kun de 3 første argumenter.
>
> For at læse den igen.
>
> if(!in_array($_GET["style"],$harmless)) {
> if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
> $style=BASICSTYLESHEET;
> } else {
> $style=$_COOKIE["phpdesignskifte"];
> }
> } else {
> $style = $_GET["style"];
> }
Det har jeg prøvet:
<?php
define('BASICSTYLESHEET', '../hss-main.css');
function is_harmful($userstring) {
$harmless = array('../hss-main.css','ds2.css','ds3.css');
$harmful = array('@','%',"\\",'<','>','(',')',';','script','http','www');
$lowcasestring=strtolower($userstring);
$newstring=str_replace($harmful,$harmless,$lowcasestring);
// Hvis de er forskellige, var der en udskiftning - der var altså nogle
farlige tegn:
return $newstring!=$lowcasestring;
}
// Saml input op - også en tom streng.
if(!in_array($_GET["style"],$harmless)) $style=BASICSTYLESHEET;
else $style = $_GET["style"];
// Hvis ikke brugerinput, hent cookie
if(!in_array($_GET["style"],$harmless)) { // 18
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) { // 19
$style=BASICSTYLESHEET;
} else {
$style=$_COOKIE["phpdesignskifte"];
}
} else {
$style = $_GET["style"];
}
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+30, "/");
?>
Så får jeg disse fejlmeldinger:
Warning: in_array() [function.in-array]: Wrong datatype for second argument
in getcookie.php on line 14
Warning: in_array() [function.in-array]: Wrong datatype for second argument
in getcookie.php on line 18
Warning: in_array() [function.in-array]: Wrong datatype for second argument
in getcookie.php on line 19
Linjerne 18 og 19 er vist med kommentarer
| |
Martin (12-02-2007)
| Kommentar Fra : Martin |
Dato : 12-02-07 16:44 |
|
Erik Ginnerskov wrote:
> Så får jeg disse fejlmeldinger:
>
> Warning: in_array() [function.in-array]: Wrong datatype for second argument
> in getcookie.php on line 14
>
> Warning: in_array() [function.in-array]: Wrong datatype for second argument
> in getcookie.php on line 18
>
> Warning: in_array() [function.in-array]: Wrong datatype for second argument
> in getcookie.php on line 19
Det er fordi dit array $harmful kun findes inde i funktionen, hvis du
smider funktionen ud - og kun beholder arrayet, så burde det virke. :)
| |
Erik Ginnerskov (13-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 13-02-07 14:24 |
|
Martin wrote:
> Det er fordi dit array $harmful kun findes inde i funktionen, hvis du
> smider funktionen ud - og kun beholder arrayet, så burde det virke. :)
Så slap jeg godt nok for fejlmeldingerne, men scriptet holdt op med at kunne
ændre sidens layout:
<?php
define('BASICSTYLESHEET', '../hss-main.css');
$harmless = array('../hss-main.css','ds2.css','ds3.css');
$harmful = array('@','%',"\\",'<','>','(',')',';','script','http','www');
$lowcasestring=strtolower($userstring);
$newstring=str_replace($harmful,$harmless,$lowcasestring);
// Hvis de er forskellige, var der en udskiftning - der var altså nogle
farlige tegn:
return $newstring!=$lowcasestring;
// Saml input op - også en tom streng.
if (isset($_GET["style"])) $style=$_GET['style'];
if (is_harmful($style) || $style==''); // $style=BASICSTYLESHEET;
// Hvis ikke brugerinput, hent cookie
if(!in_array($_GET["style"],$harmless)) {
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
$style=BASICSTYLESHEET;
} else {
$style=$_COOKIE["phpdesignskifte"];
}
} else {
$style = $_GET["style"];
}
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+30, "/");
?>
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
Erik Ginnerskov (13-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 13-02-07 15:03 |
|
Martin wrote:
> Det er fordi dit array $harmful kun findes inde i funktionen, hvis du
> smider funktionen ud - og kun beholder arrayet, så burde det virke. :)
Jeg lavede det helt om og nu virker det næsten helt som ønsket:
Jeg kan skifte sidens design
Ved sideskift fastholdes det valgte design
Jeg mangler kun at kunne blokere for uønsket input - ved forsøg herpå skal
det default css indsættes.
http://hjemmesideskolen.dk/usenet/desigsnkift.php
Script:
<?
// Saml input op - også en tom streng.
if (isset($_GET["style"])) $style=$_GET['style'];
$harmless = array('../hss-main.css','ds2.css','ds3.css');
// Hvis ikke brugerinput, hent cookie
if(empty($_GET["style"])) {
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
$style="../hss-main.css";
} else {
$style=$_COOKIE["phpdesignskifte"];
}
}
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+30, "/");
?>
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
Martin (13-02-2007)
| Kommentar Fra : Martin |
Dato : 13-02-07 15:38 |
|
Erik Ginnerskov wrote:
> Jeg mangler kun at kunne blokere for uønsket input - ved forsøg herpå skal
> det default css indsættes.
Nu skal jeg lige være HELT sikker..
uønsket input er ALT andet end.
ds2.css, ds3.css og hss-main.css ikke?
> <?
> // Saml input op - også en tom streng.
> if (isset($_GET["style"])) $style=$_GET['style'];
> $harmless = array('../hss-main.css','ds2.css','ds3.css');
>
> // Hvis ikke brugerinput, hent cookie
> if(empty($_GET["style"])) {
> if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
Denne... !in_array betyder Hvis $_COOKIE["phpdesignskifte"] IKKE er i
arrayet $harmless.
Du skal også gøre det samme med din $_GET["style"] - så blokerer den for
den også får uønsket input.
Så din kode burde se sådan her ud
if(!in_array($_GET["style"],$harmless)) {
// Blokerer forkert input i $_GET["style"]
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
// Blokerer forkert input fra cookien
$style = BASICSTYLESHEET;
// Hvis begge indeholder uønsket indhold,
// så sætter vi bare den til "normal"
} else {
$style=$_COOKIE["phpdesignskifte"];
// Hov.. vores cookie indeholder et rigtigt input
// Så vi sætter $style til vores cookie
} else {
$style=$_GET["style"];
// Hov.. vores _GET indeholder et rigtigt input
// Så vi sætter $style til vores _GET indhold
}
> // læg style-info i coogie
> setcookie("phpdesignskifte", $style, time()+30, "/");
Nu hvor du sætter en cookie til 30min, så burde du måske overveje
istedet for at bruge sessions.
Man er sikker på sessionen bliver sat, i forhold til cookie, da nogle
ikke ønsker sådan en fætter.
| |
Martin (13-02-2007)
| Kommentar Fra : Martin |
Dato : 13-02-07 15:40 |
|
Martin wrote:
> Erik Ginnerskov wrote:
>> Jeg mangler kun at kunne blokere for uønsket input - ved forsøg herpå
>> skal det default css indsættes.
>
> Nu skal jeg lige være HELT sikker..
> uønsket input er ALT andet end.
> ds2.css, ds3.css og hss-main.css ikke?
>
>> <?
>> // Saml input op - også en tom streng.
>> if (isset($_GET["style"])) $style=$_GET['style'];
>> $harmless = array('../hss-main.css','ds2.css','ds3.css');
Hov... fjern lige din IF sætning her!
Den vil ødelægge det senere, da du allerede her definerer $style.
Det skal du ikke gøre, det gøres nede i den IF sætning jeg har skrevet
>
> if(!in_array($_GET["style"],$harmless)) {
> // Blokerer forkert input i $_GET["style"]
> if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
> // Blokerer forkert input fra cookien
> $style = BASICSTYLESHEET;
> // Hvis begge indeholder uønsket indhold,
> // så sætter vi bare den til "normal"
> } else {
> $style=$_COOKIE["phpdesignskifte"];
> // Hov.. vores cookie indeholder et rigtigt input
> // Så vi sætter $style til vores cookie
> } else {
> $style=$_GET["style"];
> // Hov.. vores _GET indeholder et rigtigt input
> // Så vi sætter $style til vores _GET indhold
> }
| |
Erik Ginnerskov (13-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 13-02-07 22:02 |
|
Martin wrote:
> Nu skal jeg lige være HELT sikker..
> uønsket input er ALT andet end.
> ds2.css, ds3.css og hss-main.css ikke?
Bingo.
> Så din kode burde se sådan her ud
>
> [klip kode]
Jeg prøvede din kode, men kunne ikke få det til at fungere - heller ikke med
den ændring, du kom med i dit næste indlæg.
Men ved at lege lidt videre med mit eget, er jeg nu kommet frem til at kunne
blokere uønsket input.
Der er kun den lille skønhedsfejl, at ved uønsket input fastholdes det
seneste valide input i stedet for at det defaulte layout bruges. Jeg ville
gerne have den til at gå til default ved uønsket input:
<?
// Definer lovligt style-input
$harmless = array('../hss-main.css','ds2.css','ds3.css');
$style=$_GET["style"];
// Blokerer forkert input i $_GET["style"]
if(!in_array($_GET["style"],$harmless)) {
$style=$_COOKIE["phpdesignskifte"];
// Blokerer forkert input fra cookien
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
$style = "../hss-main.css";
}
}
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+30, "/");
?>
>
> Nu hvor du sætter en cookie til 30min,
Det skulle da gerne være 30 dage. Et hurtigt kig i min php-bog fortæller, at
det faktisk er sat til 30 sekunder, så jeg retter til 2592000, så skulle det
passe (60×60×24×30).
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
Martin (14-02-2007)
| Kommentar Fra : Martin |
Dato : 14-02-07 17:29 |
|
Erik Ginnerskov wrote:
> Der er kun den lille skønhedsfejl, at ved uønsket input fastholdes det
> seneste valide input i stedet for at det defaulte layout bruges. Jeg ville
> gerne have den til at gå til default ved uønsket input:
if(!in_array($_GET["style"],$harmful)) $style=DEFAULT;
else $style=$_GET["style"];
if(!in_array($_COOKIE["design"],$harmful)) $style=DEFAULT;
else $style=$_COOKIE["design"];
Sådan...?
> <?
> // Definer lovligt style-input
> $harmless = array('../hss-main.css','ds2.css','ds3.css');
>
> $style=$_GET["style"];
> // Blokerer forkert input i $_GET["style"]
> if(!in_array($_GET["style"],$harmless)) {
>
> $style=$_COOKIE["phpdesignskifte"];
> // Blokerer forkert input fra cookien
> if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) {
>
> $style = "../hss-main.css";
> }
> }
Et stort problem er at du definerer $style først - dette skal først
gøres til allersidst.
>
> // læg style-info i coogie
> setcookie("phpdesignskifte", $style, time()+30, "/");
> ?>
>
>> Nu hvor du sætter en cookie til 30min,
>
> Det skulle da gerne være 30 dage. Et hurtigt kig i min php-bog fortæller, at
> det faktisk er sat til 30 sekunder, så jeg retter til 2592000, så skulle det
> passe (60×60×24×30).
>
Faktisk sætter du cookien kun til 30 sekunder, nu hvor jeg tænker mig om.
time() giver jo antal sekunder fra unix time (1/1-1971 00:00:00 så vidt
jeg lige kan huske unix date)
Så
60 sek * 60 min * 24 timer * X antal dage
setcookie("phpdesignskifte", $style, time()+(60*60*24*30), "/");
Nu skulle den gerne sætte sig til 30 dage.
PS: For at slette en cookie
setcookie("phpdesignskifte",$style,time()-3000);
| |
Erik Ginnerskov (15-02-2007)
| Kommentar Fra : Erik Ginnerskov |
Dato : 15-02-07 00:36 |
|
Martin wrote:
> if(!in_array($_GET["style"],$harmful)) $style=DEFAULT;
> else $style=$_GET["style"];
>
> if(!in_array($_COOKIE["design"],$harmful)) $style=DEFAULT;
> else $style=$_COOKIE["design"];
>
> Sådan...?
Det prøvede jeg (gjorde jeg det som du mente?):
// Definer lovligt style-input
$harmless = array('../hss-main.css','ds2.css','ds3.css');
$defaultstyle = "../hss-main.css";
$style=$_GET["style"];
// Blokerer forkert input i $_GET["style"]
if(!in_array($_GET["style"],$harmless)) $style = $defaultstyle;
else $style=$_GET["style"];
$style=$_COOKIE["phpdesignskifte"];
// Blokerer forkert input fra cookien
if(!in_array($_COOKIE["phpdesignskifte"],$harmless)) $style =
$defaultstyle;
else $style=$_COOKIE["phpdesignskifte"];
// læg style-info i coogie
setcookie("phpdesignskifte", $style, time()+2592000, "/");
?>
Det gjorde så, at jeg slet ikke kan skifte sidens style - siden bliver
fastholdt i, hvad der er defineret i cookien, uanset hvilket input jeg
giver.
> Et stort problem er at du definerer $style først - dette skal først
> gøres til allersidst.
Det mener jeg da ikke, at jeg har gjort:
Jeg startede med at tjekke, om brugeren har defineret style (ved
klik på link eller ved indtastning i adresselinje).
Dernæst validerede jeg input.
Hvis intet eller ulovligt input, kigges efter en cookie.
Derefter valideredes input fra cookie (principielt ikke nødvendigt,
da en cookie kun bør kunne have lovligt indhold, men teoretisk
kan en bruger have manipuleret med sin cookie).
Var der endnu ikke fundet lovligt indhold, brugtes den defaulte
style-definition.
Til slut sattes/opdateredes cookie med aktuelle style.
Principielt er det ikke nogen katastrofe, at et ulovligt input resulterer i
at cookiens style-definition bliver brugt i stedet for den defaulte, så jeg
skulle måske vælge at stoppe her?
> Faktisk sætter du cookien kun til 30 sekunder, nu hvor jeg tænker mig
> om. time() giver jo antal sekunder fra unix time (1/1-1971 00:00:00
> så vidt jeg lige kan huske unix date)
Hvis jeg sætter time()+2592000, skulle cookien, hvis din formodning holder,
være dløbet længe før den bliver sat. jeg har observeret, at den er aktiv
flere timer efter at den er sat. Og kigger jeg i cookien, kan jeg se, at den
er sat til at udløbe 30 døgn efter det tidspunkt, den blev sat / sidst blev
opdateret.
> PS: For at slette en cookie
> setcookie("phpdesignskifte",$style,time()-3000);
Det er jeg klar over - negativ tidsangivelse = ingen holdbarhed.
--
Med venlig hilsen
Erik Ginnerskov
http://hjemmesideskolen.dk/ - http://ginnerskov.dk/
http://html-faq.dk
| |
|
|