webForumDet fria alternativet

Den godkänner inte två kommandon

PHP

19 svar · 1 474 visningar · startad av Jerpa

Medlem sedan feb. 20032 532 inlägg
Frågan#1

Har byggt ihop detta från webdesignskolan och det fungerar men så fort jag lägger till personnummer och postnummer säger den ifrån.
En gång släppte den igenom postnummer men den "klagar" jämt på personnummret.

Vad ska jag skriva för att få det att fungera? Vet att jag inte har en validering för personnummret men sååå viktigt är det inte nu. Men om nån vill fixa det så är det helt ok. (y)

<?php

// anger en variabel som kan lagra de eventuella felaktigheterna
$errors = array();

// kontrollera om ett Namn angivits
if (!$_POST["name"])
$errors[] = "- Förnamn och efternamn";

// kontrollera om ett Personnummer angivits
if (!$_POST["personnummer"])
$errors[] = "- Personnummer";

// kontrollera om ett Postnummer angivits
if (!$_POST["postnummer"])
$errors[] = "- Postnummer";

// kontrollera om ett Adress angivits
if (!$_POST["adress"])
$errors[] = "- Adress";

// kontrollera om ett Telefonnummer angivits
if (!$_POST["telefonnummer"])
$errors[] = "- Telefonnummer";

// kontrollera om en Epostadress angivits
$emailcheck = $_POST["email"];
if(!preg_match("/^[a-z0-9\å\ä\ö._-]+@[a-z0-9\å\ä\ö.-]+\.[a-z]{2,6}$/i", $emailcheck))
$errors[] = "- Din epostadress saknas eller är felaktig";    

// om felaktig information finns visas detta meddelande
if (count($errors)>0){
echo "<span class='text'>";
echo "<h2>Följande information måste anges innan du kan skicka formuläret:</h2><br /><br />";
foreach($errors as $fel)
echo "<span class='textbakgrund'> $fel <br /><br /></span>";
echo "<br />Ange den information som saknas och skicka formuläret igen. Tack! <br /><br />";
echo "<a href='javascript:history.go(-1)'>&laquo; klicka här för att komma tillbaka till formuläret</a></span>";
}

else {
// formuläret är korrekt ifyllt och informationen bearbetas
$to = "XXXX@XXXXX.com";
$from = $_POST["email"];
$subject = $_POST["subject"];
$name = $_POST["name"];
$message = $_POST["message"];
$personnummer = $_POST["personnummer"];
$postnummer = $_POST["postnummer"];
$adress = $_POST["adress"];
$telefonnummer = $_POST["telefonnummer"];

if (mail($to, $subject, $message ,"From: $name <$from>"))
echo nl2br("<span class='text'><h2>Ditt meddelande har skickats!</h2>
<b>Namn:</b> $name
<b>Personnummer:</b> $personnummer
<b>Postnummer:</b> $postnummer
<b>Adress:</b> $adress
<b>Telefon:</b> $telefonnummer
<b>Email:</b> $email
<b>Meddelande:</b>$message
</span>
<a href='javascript:history.go(-1)'>Tillbaka till sidan!</a></span>");
    
    else
    echo "Det gick inte att skicka ditt meddelande";
}
	
?>
Medlem sedan jan. 20023 327 inlägg
#2

Vad menar du med klagar? Posta även ditt formulär, kontrollera att du har samma namn på formulär-fältet för person-nummer som det du hämtar med $_POST["personnummer"].

Jerpa skrev:

Vet att jag inte har en validering för personnummret men sååå viktigt är det inte nu. Men om nån vill fixa det så är det helt ok. (y)

Nja varför inte implementera algoritmen modulo 10 själv? Ganska kul och kanske lärorikt. Definition:

Susning.nu skrev:

Om tredje siffran i födelsenumret är udda är personen en man, är den jämn är personen en kvinna. Om man genomgår ett könsbyte får man ett nytt personnummer. Könet i personnumret bestäms utifrån vad könsorganet är mest likt.

Kontrollsiffran räknas fram genom en algoritm som kallas för modulo 10 som t.ex. även används för kontrollsiffror i svenska postgiro- och bankgiro-nummer.

Man räknar ut den genom att addera siffrorna man får när man växlar med att multiplicera med 1 och 2 och sedan tar differensen till 10.

Ex: 7 3 0 2 3 1 - 4 9 1
* 2 1 2 1 2 1 2 1 2
14 3 0 2 6 1 8 9 2 = 1+4+3+0+2+6+1+8+9+2 = 36.

Differensen upp till närmaste 10-tal är 4.
Kontrollsiffran är alltså 4 och personnumret
730231-4914.

(Notera att 14 räknas som 1+4)

Medlem sedan feb. 20032 532 inlägg
#3

Hmm, nu får jag iväg mailet. Hade totalt glömt bort att titta i formuläret. Men nu har jag ett annat problem. I mailet jag tar emot står endast det jag skriver i meddelanderutan. Skriver jag inget där får jag ett tomt mail.

Klaga menade jag med att om man har glömt något kommer ett felmeddelande upp och säger till vilka rutor man har glömt.
När man fyllt i korrekt får man upp en liknande ruta:

Ditt meddelande har skickats!

Namn: Testperson
Personnummer: 123456-7890
Postnummer: 12345
Adress: Byhålan
Telefon: 020123456
Email: nisse@hult.nu
Meddelande: hej hej ett test

Tillbaka till sidan!

Formuläret:

<form name="kontakt" method="post" action="mail_blimedlem.php">
<table border="0" align="left" cellpadding="10" cellspacing="0" class="mail_kantlinje">
<tr>
<td class="fetgul">
För & Efternamn: *<br>
<input name="name" type="text" size="30" class="mail_bg"><br><br>

Personnummer: *<br>
<input name="personnummer" type="text" size="30" class="mail_bg"><br><br>

Postnr / Adress *<br>
<input name="postnummer" type="text" size="5" class="mail_bg"> <input name="adress" type="text" size="20" class="mail_bg"><br><br>

Telefon inkl riktnr eller mobilnr *<br>
<input name="telefonnummer" type="text" size="30" class="mail_bg"><br><br>

Epost *<br>
<input name="email" type="text" size="30" class="mail_bg"><br><br>

Ev. meddelande:<br>
<textarea name="message" cols="30" rows="3" class="mail_bg"></textarea><br><br>

<input name="submit" type="submit" value="Skicka" class="mail_skicka">
</td>
</tr>
</table>
</form>

Omskrivna koden.

<?php

// anger en variabel som kan lagra de eventuella felaktigheterna
$errors = array();

// kontrollera om ett Namn angivits
if (!$_POST["name"])
$errors[] = "- Förnamn och efternamn";

// kontrollera om ett Personnummer angivits
if (!$_POST["personnummer"])
$errors[] = "- Personnummer";

// kontrollera om ett Postnummer angivits
if (!$_POST["postnummer"])
$errors[] = "- Postnummer";

// kontrollera om ett Adress angivits
if (!$_POST["adress"])
$errors[] = "- Adress";

// kontrollera om ett Telefonnummer angivits
if (!$_POST["telefonnummer"])
$errors[] = "- Telefonnummer";

// kontrollera om en Epostadress angivits
$emailcheck = $_POST["email"];
if(!preg_match("/^[a-z0-9\å\ä\ö._-]+@[a-z0-9\å\ä\ö.-]+\.[a-z]{2,6}$/i", $emailcheck))
$errors[] = "- Din epostadress saknas eller är felaktig";    

// om felaktig information finns visas detta meddelande
if (count($errors)>0){
echo "<span class='text'>";
echo "<h2>Följande information måste anges innan du kan skicka formuläret:</h2><br /><br />";
foreach($errors as $fel)
echo "<span class='textbakgrund'> $fel <br /><br /></span>";
echo "<br />Ange den information som saknas och skicka formuläret igen. Tack! <br /><br />";
echo "<a href='javascript:history.go(-1)'>&laquo; klicka här för att komma tillbaka till formuläret</a></span>";
}

else {
// formuläret är korrekt ifyllt och informationen bearbetas
$to = "XXXXX@XXXXX.com";
$from = $_POST["email"];
$subject = $_POST["subject"];
$name = $_POST["name"];
$message = $_POST["message"];
$personnummer = $_POST["personnummer"];
$postnummer = $_POST["postnummer"];
$adress = $_POST["adress"];
$telefonnummer = $_POST["telefonnummer"];

if (mail($to, $subject, $message ,"From: $name <$from>"))
echo nl2br("<span class='text'><h2>Ditt meddelande har skickats!</h2>
<b>Namn:</b> $name
<b>Personnummer:</b> $personnummer
<b>Postnummer:</b> $postnummer
<b>Adress:</b> $adress
<b>Telefon:</b> $telefonnummer
<b>Email:</b> $email
<b>Meddelande:</b>$message
</span>
<a href='javascript:history.go(-1)'>Tillbaka till sidan!</a></span>");
    
    else
    echo "Det gick inte att skicka ditt meddelande";
}
	
?>
Medlem sedan feb. 2007278 inlägg
#4

Grova säkerhetshål

Jerpa skrev:

Har byggt ihop detta från webdesignskolan....

Say no more! Ursäkta sågningen. Inte ditt fel, utan du har haft dåliga lärare, men personnumret är inte ditt stora problem.

Kodningsstilen är bara en workaround för att PHP sedan 4.2 inte längre har register_globals på. (Googla om du inte vet vad jag menar!)

Du kunde lika gärna gjort så här:

extract($_POST);

Gör inte det! Läs varningen på manualsidan: http://se.php.net/extract

Det som görs i detta exempel är lika dumt. Dessutom är HTML-koden gräslig. Webbdesignskolan strikes again!

Ditt exempel är av dessa skäl vidöppet för s.k. SMTP-header injection attacker. Jag skulle med lätthet kunna använda ditt skript och spamma några tusen personer - och du skulle få skulden.

Själva poängen med att man har de s.k. superglobala arrayerna (GET/POST/SERVER/ENV/SESSION/COOKIE) är just att man skall tänka på säkerheten.

Använd det inte till annat än personliga experiment. Lägg aldrig upp koden på en publik server.

Indata måste filtreras!

http://shiflett.org/blog/2005/feb/my-top-two-php-security-practices

Jag håller på att skriva en guide till mejlhantering i PHP, men till den är kvar, finns det någon på detta forum som känner till en vettig dito?

Medlem sedan juni 20014 421 inlägg
#5

Det har varit en del snack om bl.a crlf-injections i asp-forumet. Teorin, exemplena och förklaringarna går ju att applicera här med. Vill man ha något som går direkt på php, kan väl dessa två länkar vara läsvärda, de förklarar problemet lite olika, men har (ganska självklart) nästan samma lösningar: http://www.securephpwiki.com/index.php/Email_Injection
http://www.nyphp.org/phundamentals/email_header_injection.php

Fler länkar om ämnet finns här: http://www.mailinjection.com/links

Medlem sedan feb. 20001 590 inlägg
#6

-> itpastorn

Skulle vara kul om du kunde förklara varför HTML kodningen i detta exempel är gräslig...

Medlem sedan feb. 2007278 inlägg
#7

Varför HTML-koden är dålig

Toonster skrev:

-> itpastorn

Skulle vara kul om du kunde förklara varför HTML kodningen i detta exempel är gräslig...

1. Tabell för layout - som dessutom bara innehåller en enda cell! Varför tabell alls då? I stället för tabellen borde det vara en fieldset eller en div.
2. Inga label-element (som bör finnas till varje input utom submit och hidden)
3. "Bed and breakfast" kodning
4. Somliga klassnamn valda endast efter förväntat utseende, ej funktion ("fetgul")
5. Javaskriptlänkar

Och om man skall vara petig: <br> ibland och <br /> ibland. HTML eller XHTML? Antingen - eller, tack!

http://microformats.org/wiki/posh#The_POSH_Checklist
http://adactio.com/atmedia2005/

Medlem sedan feb. 2007278 inlägg
#8

Artiklar

colione skrev:

http://www.securephpwiki.com/index.php/Email_Injection
http://www.nyphp.org/phundamentals/email_header_injection.php

Vettiga förklaringar men dåliga regexp för icke-amerikaner i artikeln från New York PHPUG. Varför måste amerikaner envisas i sina exempel med [a-z0-9] som inte kan flyttas, medan [[:alnum:]] tar hänsyn till locale.

Båda artiklarna missar - fast den ena nämner på slutet - försök till manipulation med MIME-typen.

Vad jag efterlyser är emellertid ett nybörjarexempel om mejl i PHP som kan ersätta skiten som Jerpa läst.

Medlem sedan feb. 2007278 inlägg
#9

itpastorn skrev:

1. Tabell för layout...

Och en halvpetig sak till. Klassen mail_bg är satt på i stort sett varje input-element = "Classitis"

Är den en krok för javaskript? I så fall kan vi använda oss av smartare lösning som "event delegation" alternativt hitta alla input-element av typen text/password samt alla textarea.

Är det en krok för CSS? Avkomlingsselektorn!

Till Jerpa: Ge inte upp och tappa inte sugen av min kritik! Den är kraftigt formulerad bara för att jag blir så sur när de som undervisar lär ut skräp.

Ha lite tålamod så skall vi fixa detta åt dig!

Medlem sedan feb. 2007278 inlägg
#10

Ett snabbt utkast

Jag hade svårt att sova. Här kommer ett utkast.

Testa att skriva "bcc:" eller "to:" i något fält

<?php
/**
 * mail/mail_example.php
 * 
 * Visa ett formulär, verifiera befintlighet och säkerhet på indata, skicka mejl.
 * 
 * @author     Lars Gunther <gunther@keryx.se>
 * @copyright  Lars Gunther <gunther@keryx.se>
 * @license    Creative Commons Attribution-Noncommercial-Share Alike 3.0
 *             {@link http://creativecommons.org/licenses/by-nc-sa/3.0/}
 * @package    bokdemo
 * @subpackage mail
 * @filesource
 *
 * @version    0.01 proof of concept
 * @todo       Öhh - själva mejlandet + per fält kontroller + smartare felmeddelanden
 */

// Fixa ev. magic quotes som lätt förstör både mejltext och regexp-matchning
if ( get_magic_quotes_gpc() && ( ! ini_get('magic_quotes_sybase') ) ) {
    array_walk_recursive($_POST,'stripslashes');
}

/**
 * Denna funktion letar efter försök till SMTP-header injection i en sträng
 * 
 * @param $string Den sträng som skall undersökas
 * @return bool
 */
function smtp_header_injection_check($string) {
    // Regexp som letar efter rader som börjar med något skumt
    $regexp = "/^cc:|bcc:|to:|content-type:/im";
    return preg_match($regexp,$string);
}
if ( count($_POST) ) {
    echo "<pre>";
    $highly_suspicious  = array_filter($_POST,'smtp_header_injection_check');
    if ( count($highly_suspicious) ) {
        // Trolig attack!
        var_dump($highly_suspicious);
        exit;
    } else {
        // Vi är någorlunda säkra, men alla värden måste kollas också av användbarhetsskäl
        
    }
    var_dump($_POST);
    exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Mejlexempel</title>
<style type="text/css">
/*<![CDATA[*/
body {
    max-width: 50em;
    margin: auto; 
}
/* Inspiration: [url]http://www.cssplay.co.uk/menu/form.html[/url] */
label {
    clear: left;
    display: block;
    float: left;
    text-align: right;
    padding-right: 10px;
    width: 150px;
    margin-bottom: 15px;
}
input {
    margin-bottom: 15px;
    width: 200px;
}
.formlabelgroup {
    clear: left;
    display: block;
    float: left;
    text-align: right;
    padding-right: 10px;
    width: 150px;
}
.formlabelgroup label {
    clear: none;
    display: inline;
    float: none;
    width: auto;
    padding-right: 0;
}
input#zip {
    width: 40px;
    margin: 0 0 15px;
}
input#town {
    width: 150px;
    margin: 0 0 15px 6px;
}
textarea {
    width: 200px;
    height: 3em;
}
input[type=submit] {
    width: 100px;
    margin: 20px 0 0 130px;
}
/*]]>*/
</style>
  </head>
  <body>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
      <fieldset>
        <legend>Persondata</legend>
        <label for= "firstname">Förnamn</label>
        <input id = "firstname" name="firstname" type="text" maxlength="50" /><br />
        <label for= "lastname">Efternamn</label>
        <input id = "lastname" name="lastname" type="text" maxlength="50" /><br />
        <label for= "socsecnum">Personnummer</label>
        <input id = "socsecnum" name="socsecnum" type="text" maxlength="11" /><br />
        <div class="formlabelgroup">
          <label for="zip">Postnummer</label> och <label for="town">stad</label>
        </div>
        <input id = "zip" name="zip" type="text" maxlength="6" /><input id = "town" name="town" type="text" maxlength="50" /><br />
        <label for= "phone">Telefon</label>
        <input id = "phone" name="phone" type="text" maxlength="15" /><br />
        <label for= "mail">Mejladress</label>
        <input id = "mail" name="mail" type="text" maxlength="100" /><br />
        <label for= "msg"><abbr>Ev.</abbr> meddelande</label>
        <textarea name="msg"></textarea><br />
        <input type="submit" value="Registrera" />
      </fieldset>
    </form>
  </body>
</html>
Medlem sedan feb. 20032 532 inlägg
#11

Nej jag tar inte illa vid mig. Kritik är bra och det du skriver uppfattar jag inte som negativt. Är ingen PHPkodare utan mer en klipp-o-klistra-phpare.

När jag postat förra gången så såg jag <br> men det mesta var ju redan fel i vilket fall som helst så det spelade ingen roll.

Det ser bra ut med fieldset men jag har nu bara en fråga.
Var o hur skriver jag för att välja till vilken mailadress den ska gå till?

Medlem sedan feb. 2007278 inlägg
#12

Bifogad fil med färdig lösning

Hej igen

Den bifogade filen torde lösa de flesta problem.

SMTP-headers stoppas till 100 % och inga botar göre sig besvär!

Vad som återstår:

1. Snygga till utseendet på formuläret.
2. Separera sidkontroller, HTML-mall ochh CSS-mall.
3. Anpassa till PHP < 5.2 (OBS! just nu krävs alltså 5.2 eller senare)

Jag skickar all formulärdata i mejlet. Troligen hade du tänkt att bara skicka en del och använda resten för att uppdatera en databas? Jag lämnar det med varm hand till någon annan att fixa! Det blev ändå inalles 401 rader kod.

Medlem sedan juni 20014 421 inlägg
#13

Det finns ett fel i scriptet (jag har inte testkört det, men detta hittades vid en snabb genomläsning.)
du använder $kosher['firstname'] på rad 349, detta bör istället vara: $safe_indata['firstname']

Medlem sedan feb. 20032 532 inlägg
#14

Jag kommer ha formuläret till att folk får anmäla sig som medlem. vilket inte händer allt för ofta. Sen kommer jag säkert ha det som anmälningsformulär till våra större evenemang, ca 100-150 personer.

Medlem sedan feb. 20032 532 inlägg
#15

Har nu försökt testa det men får bara upp en vit sida. Även om jag lägger in det på den sida som ska ha det så blir det bara vitt.

Är det nåt fel jag gör, eller hur tar man reda på vilken php man har?

3. Anpassa till PHP < 5.2 (OBS! just nu krävs alltså 5.2 eller senare)

Föreningens sida ligger på one.com

Medlem sedan jan. 20023 327 inlägg
#16

Så här kan du göra för att se vilken version du har...

<?php
echo 'PHP version: ' . phpversion();
?>

@ itpastorn (y)

Medlem sedan feb. 2007278 inlägg
#17

Jerpa skrev:

Har nu försökt testa det men får bara upp en vit sida. Även om jag lägger in det på den sida som ska ha det så blir det bara vitt.

Är det nåt fel jag gör, eller hur tar man reda på vilken php man har?
Föreningens sida ligger på one.com

Se också till att din felhantering gör så att du - under utvecklingen - får se felmmeddelanden på skärmen.

Du utvecklar väl på en lokal kopia av PHP och inte på den skarpa servern?

Leta reda på

display_errors = Off

i php-ini och ändra till "On". Starta sedan om webbservern.

Komplettera med att ha följande inställning också:

error_reporting  =  E_ALL

Vill du vara riktigt petig så kör du:

error_reporting  =  E_ALL | E_STRICT

Du kan sätta på och stänga av felen i enskilda skript med error_reporting() och ini_set() funktionerna. http://se.php.net/error-reporting

@colione: Good catch! (Jag kan inte skicka mejl på min laptop där jag skrivit skriptet.)

Medlem sedan feb. 20032 532 inlägg
#18

itpastorn skrev:

Du utvecklar väl på en lokal kopia av PHP och inte på den skarpa servern?

Nej nej, så avacerad är jag inte. Har prövat två gånger men misslyckat båda gångerna. Så jag kör FTP och nätet...
Tar lite tid men det funkar...

PHPversionen är 5.2.3

Medlem sedan feb. 20001 507 inlägg
#19

Lyfter denna tråd lite med ett litet problem jag får med itpastorns fil.

// Fixa ev. magic quotes som lätt förstör både mejltext och regexp-matchning
if ( get_magic_quotes_gpc() && ( ! ini_get('magic_quotes_sybase') ) ) {
    array_walk_recursive($_POST,'stripslashes');
}

Får följande felmeddelande "Warning: Wrong parameter count for stripslashes() in ....." på stycket ovan.

Medlem sedan juni 20014 421 inlägg
#20

Hej JaktJanne. Svaret till varför det blir så finns här:
http://www.webforum.nu/showthread.php?p=1369422#post1369422
Och bästa sättet att lösa det på hittas här:
http://www.webforum.nu/showthread.php?p=1384106#post1384106

Då recursiva anrop lätt kan sänka servern om någon skulle få för sig att kasta in några speciella tecken i urlen.

286 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
133 ms — deklarationer (db)
0 ms — hämta statistik (cache)
150 ms — hämta tråd, inlägg och bilagor (db)
121 ms — ändringar (db)