hur pass säkert/osäkert är detta php login

Permalänk
Medlem

hur pass säkert/osäkert är detta php login

Efter att ha suttit och kollat/läst igenom massa tutorials hit och dit har jag lyckats få ihop ett system som fungerar... Dock är frågan hur pass säkert är detta?
Vad kan förbättras förutom allt?

index.php

<?php session_start(); require 'database.php'; if( isset($_SESSION['user_id']) ){ $records = $conn->prepare('SELECT UserID,UserName,Email,Password FROM Users WHERE id = :id'); $records->bindParam(':id', $_SESSION['user_id']); $records->execute(); $results = $records->fetch(PDO::FETCH_ASSOC); $user = NULL; if( count($results) > 0){ $user = $results; } } ?> <!DOCTYPE html> <html> <head> <title></title> <link rel="stylesheet" type="text/css" href="assets/css/style.css"> </head> <body> <?php if( !empty($user) ): ?> <br />Welcome <?= $user['email']; ?> <br /><br />You are successfully logged in! <br /><br /> <a href="logout.php">Logout?</a> <?php else: ?> <h1>Please Login or Register</h1> <a href="login.php">Login</a> or <a href="register.php">Register</a> <?php endif; ?> </body> </html>

login.php

<?php session_start(); if( isset($_SESSION['user_id']) ){ header("Location: admin.php"); } require 'database.php'; if(!empty($_POST['username']) && !empty($_POST['password'])): $records = $conn->prepare('SELECT UserID,UserName,Email,Password FROM Users WHERE UserName = :username'); $records->bindParam(':username', $_POST['username']); $records->execute(); $results = $records->fetch(PDO::FETCH_ASSOC); $message = ''; if(count($results) > 0 && password_verify($_POST['password'], $results['Password']) ){ $_SESSION['user_id'] = $results['UserID']; header("Location: admin.php"); } else { $message = 'Sorry, those credentials do not match'; } endif; ?> <!DOCTYPE html> <html> <head> <title></title> <link rel="stylesheet" type="text/css" href="assets/css/style.css"> </head> <body> <?php if(!empty($message)): ?> <p><?= $message ?></p> <?php endif; ?> <form action="login.php" method="POST"> <input type="text" placeholder="username" name="username"> <input type="password" placeholder="password" name="password"> <input type="submit"> </form> </body> </html>

register.php

<?php session_start(); if( isset($_SESSION['user_id']) ){ require 'database.php'; $message = ''; if(!empty($_POST['email']) && !empty($_POST['password'])): $sql = "INSERT INTO Users (UserName, Email, Password) VALUES (:username, :email, :password)"; $stmt = $conn->prepare($sql); $stmt->bindParam(':username',$_POST['username']); $stmt->bindParam(':email', $_POST['email']); $stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT)); if( $stmt->execute() ): $message = 'Successfully created new user'; else: $message = 'Sorry there must have been an issue creating your account'; endif; endif; ?> <!DOCTYPE html> <html> <head> <title></title> <link rel="stylesheet" type="text/css" href="assets/css/style.css"> </head> <body> <?php if(!empty($message)): ?> <p><?= $message ?></p> <?php endif; ?> <form action="register.php" method="POST"> <input type="text" placeholder="username" name="username"> <input type="text" placeholder="Enter your email" name="email"> <input type="password" placeholder="and password" name="password"> <input type="password" placeholder="confirm password" name="confirm_password"> <input type="submit"> </form> </body> </html> <?php } else { session_start(); if (!isset($_SESSION['user_id'])){ echo "No can do sir!"; } } ?>

logout.php

<?php session_start(); session_unset(); session_destroy(); header("Location: login.php");

database.php

<?php $server = '*******'; $username = '******'; $password = '******'; $database = '********'; try{ $conn = new PDO("mysql:host=$server;dbname=$database;", $username, $password); } catch(PDOException $e){ die( "Connection failed: " . $e->getMessage()); }

admin.php

<?php session_start(); if( isset($_SESSION['user_id']) ){ ?> <p>lots of secrets!!</p> <a href="logout.php">LOGOUT</a> <?php } else { echo "no way you're allowed here"; } ?>

Visa signatur

Citera om du vill ha svar :)

Permalänk
Medlem

Jag är verkligen inte duktig i varken php eller databashantering, men kan väl tänka mig att det inte är direkt lämpligt att inserta PW/Uname direkt in i databasen (query) i register.php utan att först validera input. Det borde gå att "crafta" ett username/pw som escapear queryt och kör något eget fuffens, typ dumpa databasen i echo

Visa signatur

2600k @ STOCK <|> GTX 970 Omega!<|> Nån samsung 500gb ssd <|> 16 GB Kingston Hyper X <|> BenQ XL2420t
"Det finns inget skrot, bara gamla delar som kan användas på nya sätt" - Mulle Meck

Permalänk
Medlem
Skrivet av elklazor:

Jag är verkligen inte duktig i varken php eller databashantering, men kan väl tänka mig att det inte är direkt lämpligt att inserta PW/Uname direkt in i databasen i register.php utan att först validera input. Kan tänka mig att det borde gå att "crafta" ett username/pw som escapear queryt och kör något eget fuffens, typ dumpa databasen i echo

Det kan nog stämma rät bra, dock ska registreringen ej vara öppen på min sida, då jag bara egentligen behöver en användare Jag har dessutom ett hemmakokat valideringsscript jag kör på registreringssidan, men det bör gå att göra säkrare det har du rätt i

Visa signatur

Citera om du vill ha svar :)

Permalänk
Inaktiv

Det är ett måste att sanitera användardata innan man postar det till DB.
Använd php:s filter funktioner som filter_var()

https://www.w3schools.com/php/php_filter.asp

Permalänk
Medlem
Skrivet av elklazor:

Jag är verkligen inte duktig i varken php eller databashantering, men kan väl tänka mig att det inte är direkt lämpligt att inserta PW/Uname direkt in i databasen (query) i register.php utan att först validera input. Det borde gå att "crafta" ett username/pw som escapear queryt och kör något eget fuffens, typ dumpa databasen i echo

SQL injection problem har man bara om man själv sätter ihop sql strängen utan att använda parametrar. bindParam borde rimligtvis ta bort riskerna för detta.

Däremot, om användarnamnet kommer synas på sidan finns ju en risk för att man lägger in scripts och orsakar XSS (cross site scripting) så det är alltid bra att filtrera det användaren matar in.

Permalänk
Medlem
Skrivet av Chrillemeter:

Det är ett måste att sanitera användardata innan man postar det till DB.
Använd php:s filter funktioner som filter_var()

https://www.w3schools.com/php/php_filter.asp

Tack, ska kolla igenom det

Visa signatur

Citera om du vill ha svar :)

Permalänk
Geeks
Jobbar med data

bindParam löser eventuella SQL-injections, så länge du inte låter användarna specificera ASC eller DESC sorteringar.

Det går att använda HTML Purifier för att validera html, om man måste skriva ut det på sidan (utan htmlspecialchars). Annars _ska_ man alltid använda htmlspecialchars($str, ENT_QUOTES, "UTF-8") innan man skriver ut någonting i webbläsaren som en användare har skrivit. Självklart går det att kombinera med filter_var för att t.ex. validera e-post* eller ta bort alla html taggar**. Dock är det inte skadligt att spara i databasen, så länge man använder htmlspecialchars eller htmlentities vid utskrift.

Är ju inte så vanligt att man använder < eller > i användarnamn direkt. Men filter_var känns mer användbar för att kontrollera siffror, url och e-post.

Ska du skriva ut användardata inuti inputfält måste du stänga/öppna citaten:

<input name="test" type="text" value="<?php htmlspecialchars($str, ENT_QUOTES, "UTF-8"); ?>" />

Du bör även specificera att din databas använder utf8mb4 (version >=5.5.3) och utf8 för PHP, för att få rätt teckenformat. Dina filer ska även använda UTF8 utan BOM.

Personligen väljer jag att kasta bort människor och inte skriver ut en separat text.

if(!isset($_SESSION['user_id'])) { header('Location: login.php'); }

Bara så du vet så klipper password_hash alla lösenord efter 72 tecken. Du kan kringå det genom att först köra en sha kryptering på lösenordet och köra en base64 encode över den. För att sedan hasha och salta med bcrypt.

/** * Verify users password against the one stored in the database. * @param string $password * @param string $userPassword * @return verified password true/false */ public function passwordVerify($password,$userPassword) { return password_verify( base64_encode( hash('sha384', $password, true) ), $userPassword ); } /** * Hash users password before storing it in the database. * @param string $password * @return hashed password */ public function passwordHash($password) { return password_hash( base64_encode( hash('sha384', $password, true) ), PASSWORD_DEFAULT ); }

EDIT: Glömde nämna att du inte har någon CSRF-skydd.
EDIT2: En matnyttig länk:
https://www.wordfence.com/learn/how-to-prevent-cross-site-scr...

*FILTER_VALIDATE_EMAIL
**FILTER_SANITIZE_STRING

Permalänk
Hedersmedlem

*Tråd rensad*

Tagit bort ohjälpsamma inlägg i enlighet med §1.6.
/moderator

Visa signatur

Danskjävel så krattar som en skrivare...

Permalänk
Medlem
Skrivet av jreklund:

bindParam löser eventuella SQL-injections, så länge du inte låter användarna specificera ASC eller DESC sorteringar.

Det går att använda HTML Purifier för att validera html, om man måste skriva ut det på sidan (utan htmlspecialchars). Annars _ska_ man alltid använda htmlspecialchars($str, ENT_QUOTES, "UTF-8") innan man skriver ut någonting i webbläsaren som en användare har skrivit. Självklart går det att kombinera med filter_var för att t.ex. validera e-post* eller ta bort alla html taggar**. Dock är det inte skadligt att spara i databasen, så länge man använder htmlspecialchars eller htmlentities vid utskrift.

Är ju inte så vanligt att man använder < eller > i användarnamn direkt. Men filter_var känns mer användbar för att kontrollera siffror, url och e-post.

Ska du skriva ut användardata inuti inputfält måste du stänga/öppna citaten:

<input name="test" type="text" value="<?php htmlspecialchars($str, ENT_QUOTES, "UTF-8"); ?>" />

Du bör även specificera att din databas använder utf8mb4 (version >=5.5.3) och utf8 för PHP, för att få rätt teckenformat. Dina filer ska även använda UTF8 utan BOM.

Personligen väljer jag att kasta bort människor och inte skriver ut en separat text.

if(!isset($_SESSION['user_id'])) { header('Location: login.php'); }

Bara så du vet så klipper password_hash alla lösenord efter 72 tecken. Du kan kringå det genom att först köra en sha kryptering på lösenordet och köra en base64 encode över den. För att sedan hasha och salta med bcrypt.

/** * Verify users password against the one stored in the database. * @param string $password * @param string $userPassword * @return verified password true/false */ public function passwordVerify($password,$userPassword) { return password_verify( base64_encode( hash('sha384', $password, true) ), $userPassword ); } /** * Hash users password before storing it in the database. * @param string $password * @return hashed password */ public function passwordHash($password) { return password_hash( base64_encode( hash('sha384', $password, true) ), PASSWORD_DEFAULT ); }

EDIT: Glömde nämna att du inte har någon CSRF-skydd.
EDIT2: En matnyttig länk:
https://www.wordfence.com/learn/how-to-prevent-cross-site-scr...

*FILTER_VALIDATE_EMAIL
**FILTER_SANITIZE_STRING

Tusen tack för all input! ska absolut ta åt mig av allt du skriver. Tack igen

Edit: löser jag inte cross site scripting hyffsat bra med mitt javascript som validerar mina inputs?

tex username får enbart innehålla a-ö 0-9 osv?
och sen ha en <noscript> som döljer content om js är avaktiverat

Visa signatur

Citera om du vill ha svar :)

Permalänk
Geeks
Jobbar med data

Nej, då bygger man bara ett eget PHP script som skickar en egen $_POST till din hemsida eller manipulerar DOM via webbläsaren. Och då har man gått förbi JavaScript valideringen. Visst är det trevligt att ha, så att användarna får feedback i realtid, men den riktiga spärren måste ske i PHP-scripten.

Går att använda t.ex. regex för att ta bort alla otillåtna tecken, i det här exemplet tas allt utom 0-9, a-z, A-Z, $, _ och (punkt) bort. Men då kan ju inga kinesiska tecken användas. Finns ju regex för utf8 tecken med såklart.

$dbuser = preg_replace('/[^0-9a-zA-Z$_\\.]+/','',$_POST["dbuser"]);

Permalänk
Medlem
Skrivet av jreklund:

Nej, då bygger man bara ett eget PHP script som skickar en egen $_POST till din hemsida eller manipulerar DOM via webbläsaren. Och då har man gått förbi JavaScript valideringen. Visst är det trevligt att ha, så att användarna får feedback i realtid, men den riktiga spärren måste ske i PHP-scripten.

Går att använda t.ex. regex för att ta bort alla otillåtna tecken, i det här exemplet tas allt utom 0-9, a-z, A-Z, $, _ och (punkt) bort. Men då kan ju inga kinesiska tecken användas. Finns ju regex för utf8 tecken med såklart.

$dbuser = preg_replace('/[^0-9a-zA-Z$_\\.]+/','',$_POST["dbuser"]);

Ah okej då hänger jag med, jag får ta och implementera en sån lösning då tack igen!

EDIT:

Så om jag förstått det rätt kan jag göra typ såhär?:

$sql = "INSERT INTO Users (UserName, Email, Password,Real_Name) VALUES (:username, :email, :password, :realname)"; $stmt = $conn->prepare($sql); $unpreg = preg_replace('/[^0-9a-zA-Z_-åäöÅÄÖ]+/','',$_POST["username"]); $empreg = preg_replace('/[^0-9a-zA-Z_@.-]+/','',$_POST["email"]); $rnpreg = preg_replace('/[^a-zA-ZåäöÅÄÖ]+/','',$_POST["username"]); $stmt->bindParam(':username',$unpreg); $stmt->bindParam(':realname',$rnpreg); $stmt->bindParam(':email', $empreg); $stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT)); if( $stmt->execute() ){ $message = 'Successfully created new user'; } else{ $message = 'Sorry there must have been an issue creating your account'; } }} ?>

verkar fungera iaf...

Visa signatur

Citera om du vill ha svar :)

Permalänk
Geeks
Jobbar med data

Ledsen att jag glömde nämna det, men det är sällan rekommenderat att bara ta bort ogiltiga tecken utan att ge användarna en varning, dvs bara spara i databasen om informationen är korrekt. Vill man dock hoppa över det steget och ta bort ogiltiga tecken direkt, kan du göra t.ex. såhär:

// a-z, A-Z, åäö och ÅÄÖ $unpreg = preg_replace('/[^a-zåäö]+/i','',$_POST["username"]); // Tillåter tecknarna i ASCII mellan 97 och 246, vilket inkluderar é etc. Även _ , - och (punkt) $unpreg = preg_replace('/[^a-ö_\-\.]+/i','',$_POST["username"]); // Tar bort alla tecken utom bokstäver, siffror, _, -, och (punkt) $unpreg = preg_replace('/[^\p{L}\p{N}_\-\.]+/iu','',$_POST["username"]); // Tar bort alla tecken som inte får vara i en e-post, kontrollerar dock inte om den är giltig. $empreg = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL) // Tar bort allt utom bokstäver, - och (mellanslag). $rnpreg = preg_replace('/[^\p{L}\s\-]+/u','',$_POST["realname"]);

Det du dock bör göra är att kontrollera att allting stämmer, det gör man med preg_match. Vilket i det här fallet blir 'Error', då strängen innehåller siffror, och de är inte tillåtet i namn. Det här testen görs ju självklart grafiskt med JavaScript, men ifall någon inaktiverat dem, så skall det finnas ett stopp här med.

$str = 'abc123'; $error = false; if(preg_match('/[^\p{L}\s]+/u',$str)) { $error = true; } if(!$error) { echo 'Insert'; } else { echo 'Error'; }

Allt beror ju på vilka tecken man vill tillåta i t.ex. användarnamn.

Här har du en validering för e-post.

if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) { echo("$email is a valid email address"); } else { echo("$email is not a valid email address"); }

Permalänk
Medlem
Skrivet av jreklund:

Ledsen att jag glömde nämna det, men det är sällan rekommenderat att bara ta bort ogiltiga tecken utan att ge användarna en varning, dvs bara spara i databasen om informationen är korrekt. Vill man dock hoppa över det steget och ta bort ogiltiga tecken direkt, kan du göra t.ex. såhär:

// a-z, A-Z, åäö och ÅÄÖ $unpreg = preg_replace('/[^a-zåäö]+/i','',$_POST["username"]); // Tillåter tecknarna i ASCII mellan 97 och 246, vilket inkluderar é etc. Även _ , - och (punkt) $unpreg = preg_replace('/[^a-ö_\-\.]+/i','',$_POST["username"]); // Tar bort alla tecken utom bokstäver, siffror, _, -, och (punkt) $unpreg = preg_replace('/[^\p{L}\p{N}_\-\.]+/iu','',$_POST["username"]); // Tar bort alla tecken som inte får vara i en e-post, kontrollerar dock inte om den är giltig. $empreg = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL) // Tar bort allt utom bokstäver, - och (mellanslag). $rnpreg = preg_replace('/[^\p{L}\s\-]+/u','',$_POST["realname"]);

Det du dock bör göra är att kontrollera att allting stämmer, det gör man med preg_match. Vilket i det här fallet blir 'Error', då strängen innehåller siffror, och de är inte tillåtet i namn. Det här testen görs ju självklart grafiskt med JavaScript, men ifall någon inaktiverat dem, så skall det finnas ett stopp här med.

$str = 'abc123'; $error = false; if(preg_match('/[^\p{L}\s]+/u',$str)) { $error = true; } if(!$error) { echo 'Insert'; } else { echo 'Error'; }

Allt beror ju på vilka tecken man vill tillåta i t.ex. användarnamn.

Här har du en validering för e-post.

if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) { echo("$email is a valid email address"); } else { echo("$email is not a valid email address"); }

Ah okej ja jo, det är sant. Tack åter igen

Då är det ju "bara" att implementera det... så många if och else att jag blir yr haha

Vet inte om det är jag som är trög i hela hjärnan såhär på kvällskvisten, men har jag såhär så blir allt nekat, borde det inte tillåta när jag skriver typ olga som användarnamn och real name?

$unpreg = $_POST["username"]; $empreg = $_POST["email"]; $rnpreg = $_POST["realname"]; $error = false; if(preg_match("/[^\p{L}\p{N}_.-]+/iu",$unpreg) || (filter_var($empreg, FILTER_SANITIZE_EMAIL)) || (preg_match("/[^\p{L}\s]+/u",$rnpreg))) { $error = true; } if(!$error) { $sql = "INSERT INTO Users (UserName, Email, Password,Real_Name) VALUES (:username, :email, :password, :realname)"; $stmt = $conn->prepare($sql); $stmt->bindParam(':username',$unpreg); $stmt->bindParam(':realname',$rnpreg); $stmt->bindParam(':email', $empreg); $stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT)); $stmt->execute(); $message = 'Successfully created new user'; } else { $message = 'Error, Something went wrong.'; }

edit: (filter_var($empreg, FILTER_SANITIZE_EMAIL)) verkar vara det som ställer till det för mig, (!filter_var($empreg, FILTER_VALIDATE_EMAIL)) fungerar men är det korrekt att göra så? eller ska jag använda (filter_var($empreg, FILTER_VALIDATE_EMAIL) !== false) båda fungerar på samma sätt men..

Visa signatur

Citera om du vill ha svar :)

Permalänk
Geeks
Jobbar med data

Följande fungerar lika, men är ju en frågan om tydlighet.

!filter_var($empreg, FILTER_VALIDATE_EMAIL) filter_var($empreg, FILTER_VALIDATE_EMAIL) === false

Jag uppdaterade din kod lite, du hade inget stöd för (bindestreck) inuti realname. Annars var du på rätt spår gällande att du skulle validera e-posten.

$unpreg = 'anna-karin.svensson'; $empreg = 'anna-karin.svensson@gmail.com'; $rnpreg = 'Anna-Karin Svensson'; $error = false; if( preg_match("/[^\p{L}\p{N}_.-]+/iu",$unpreg) || filter_var($empreg, FILTER_VALIDATE_EMAIL) === false || preg_match("/[^\p{L}\s-]+/u",$rnpreg) ) { $error = true; }

Sen ska man ju såklart berätta vad som gick snett. Men det är typ ingen idag som inte har JavaScript igång, så det har ju redan fått en sådan varning.

Skulle rekommendera att köra en trim() runt $_POST med. För det är ju inte direkt många som med flit väljer att ha ett mellanslag i början/slutet av användarnamnet. Och har de fått med det, så fungerar det ju inte att logga in sen, då de inte nästa gång skriver med ett mellanslag.

Permalänk
Medlem
Skrivet av jreklund:

Följande fungerar lika, men är ju en frågan om tydlighet.

!filter_var($empreg, FILTER_VALIDATE_EMAIL) filter_var($empreg, FILTER_VALIDATE_EMAIL) === false

Jag uppdaterade din kod lite, du hade inget stöd för (bindestreck) inuti realname. Annars var du på rätt spår gällande att du skulle validera e-posten.

$unpreg = 'anna-karin.svensson'; $empreg = 'anna-karin.svensson@gmail.com'; $rnpreg = 'Anna-Karin Svensson'; $error = false; if( preg_match("/[^\p{L}\p{N}_.-]+/iu",$unpreg) || filter_var($empreg, FILTER_VALIDATE_EMAIL) === false || preg_match("/[^\p{L}\s-]+/u",$rnpreg) ) { $error = true; }

Sen ska man ju såklart berätta vad som gick snett. Men det är typ ingen idag som inte har JavaScript igång, så det har ju redan fått en sådan varning.

Skulle rekommendera att köra en trim() runt $_POST med. För det är ju inte direkt många som med flit väljer att ha ett mellanslag i början/slutet av användarnamnet. Och har de fått med det, så fungerar det ju inte att logga in sen, då de inte nästa gång skriver med ett mellanslag.

Ah okej, så jag är inte helt tokigt ute! tack åter igen för tipsen! du förtjänar helt klart en guldstjärna!

Visa signatur

Citera om du vill ha svar :)

Permalänk
Medlem

@jreklund finns det någon bra sida där jag kan göra lite egna regex(regular expression) heter det väl? Jag har hittat ett gäng men jag fattar ingenting alls på dom ^^ implementerar detta i kommentarssystemet också, men där tänker jag att man kan använda a-ö 0-9 ,.-@#()"! egentligen allt utom <>{}[] borde ju vara rätt safe?

Visa signatur

Citera om du vill ha svar :)

Permalänk
Geeks
Jobbar med data

@Pelle Jag använder alltid regex101.com för att skapa mina regex. Och ibland phpliveregex.com för att testa dem på webben i PHP. Du kan hitta ett par exempel på regexlib.com.

Om du vill ta bort <html> taggar kan du använda följande. Men om användarnas** html kod ska fungera måste du använda HTML Purifier (och hoppa över allt i det här inlägget)

$newstr = filter_var($str, FILTER_SANITIZE_STRING);

Du är dock helt säker mot XSS attacker om du alltid använder htmlspecialchars eller htmlentities vid utskrift. Vilket Sweclockers använder sig utav, då den inte tar bort min <html> kod i den här raden.

echo htmlspecialchars($str, ENT_QUOTES, "UTF-8");

Det här är detsamma som ovan, OM default_charset (php.ini) är UTF-8 (standard i PHP 5.6). Varför jag skriver som ovan istället och väljer själv.

echo filter_var($str, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

Skriver du ut användarnas kommentar inuti en <div>_användare_kommentar_</div>* med hjälp av htmlspecialchars så kommer inga attacker att ske, du behöver inte ens ta bort <html> taggarna, då du kommer visa dem som text. Skulle du lägga det i en onmouseover="_användare_kommentar_" eller glömmer htmlspecialchars ligger du riktigt illa ute.

Ska du stödja festil kan du använda dig utav BBCode, som Sweclockers gör.

* <p> etc fungerar ju med
** En admins html kod, vanliga användare skall aldrig få använda <html> kod.

Permalänk
Medlem
Skrivet av jreklund:

@Pelle Jag använder alltid regex101.com för att skapa mina regex. Och ibland phpliveregex.com för att testa dem på webben i PHP. Du kan hitta ett par exempel på regexlib.com.

Om du vill ta bort <html> taggar kan du använda följande. Men om användarnas** html kod ska fungera måste du använda HTML Purifier (och hoppa över allt i det här inlägget)

$newstr = filter_var($str, FILTER_SANITIZE_STRING);

Du är dock helt säker mot XSS attacker om du alltid använder htmlspecialchars eller htmlentities vid utskrift. Vilket Sweclockers använder sig utav, då den inte tar bort min <html> kod i den här raden.

echo htmlspecialchars($str, ENT_QUOTES, "UTF-8");

Det här är detsamma som ovan, OM default_charset (php.ini) är UTF-8 (standard i PHP 5.6). Varför jag skriver som ovan istället och väljer själv.

echo filter_var($str, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

Skriver du ut användarnas kommentar inuti en <div>_användare_kommentar_</div>* med hjälp av htmlspecialchars så kommer inga attacker att ske, du behöver inte ens ta bort <html> taggarna, då du kommer visa dem som text. Skulle du lägga det i en onmouseover="_användare_kommentar_" eller glömmer htmlspecialchars ligger du riktigt illa ute.

Ska du stödja festil kan du använda dig utav BBCode, som Sweclockers gör.

* <p> etc fungerar ju med
** En admins html kod, vanliga användare skall aldrig få använda <html> kod.

Åter igen ett stort tack till dig

Visa signatur

Citera om du vill ha svar :)