La seguretat en formularis és un aspecte crític en el desenvolupament web, ja que els formularis són una de les vies més comunes per a l'entrada de dades per part dels usuaris. Sense les mesures de seguretat adequades, els formularis poden ser vulnerables a diversos tipus d'atacs, com ara la injecció SQL, el cross-site scripting (XSS) i el cross-site request forgery (CSRF). En aquesta secció, aprendrem com protegir els nostres formularis PHP contra aquests atacs.
Conceptes Clau
- Validació del Costat del Servidor: Assegura't que totes les dades enviades a través dels formularis siguin validades i sanejades al costat del servidor.
- Protecció contra Injecció SQL: Utilitza declaracions preparades i paràmetres vinculats per evitar la injecció SQL.
- Protecció contra XSS: Sanejament de les dades d'entrada per evitar l'execució de scripts maliciosos.
- Protecció contra CSRF: Utilitza tokens CSRF per assegurar-te que les sol·licituds provenen de fonts legítimes.
Validació del Costat del Servidor
La validació del costat del servidor és essencial perquè els usuaris poden desactivar la validació del costat del client. Aquí tens un exemple de com validar i sanejar les dades d'un formulari:
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { $name = sanitize_input($_POST["name"]); $email = sanitize_input($_POST["email"]); $message = sanitize_input($_POST["message"]); // Validació if (empty($name) || empty($email) || empty($message)) { echo "Tots els camps són obligatoris."; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo "L'adreça de correu electrònic no és vàlida."; } else { // Processar les dades echo "Dades vàlides."; } } function sanitize_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?>
Protecció contra Injecció SQL
Per evitar la injecció SQL, utilitza declaracions preparades amb PDO:
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "database"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("INSERT INTO users (name, email, message) VALUES (:name, :email, :message)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email); $stmt->bindParam(':message', $message); $name = sanitize_input($_POST["name"]); $email = sanitize_input($_POST["email"]); $message = sanitize_input($_POST["message"]); $stmt->execute(); echo "Nou registre creat correctament"; } catch(PDOException $e) { echo "Error: " . $e->getMessage(); } $conn = null; ?>
Protecció contra XSS
Per evitar XSS, utilitza la funció htmlspecialchars
per sanejar les dades d'entrada:
<?php function sanitize_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?>
Protecció contra CSRF
Per protegir-te contra CSRF, genera un token CSRF i verifica'l en enviar el formulari:
Generació del Token CSRF
<?php session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } ?> <form method="post" action="process_form.php"> <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> <!-- Altres camps del formulari --> <input type="submit" value="Enviar"> </form>
Verificació del Token CSRF
<?php session_start(); if ($_SERVER["REQUEST_METHOD"] == "POST") { if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { die("Error: Invalid CSRF token"); } // Processar les dades del formulari } ?>
Exercici Pràctic
Exercici
Crea un formulari de contacte que inclogui els següents camps: nom, correu electrònic i missatge. Implementa les següents mesures de seguretat:
- Validació del costat del servidor.
- Protecció contra injecció SQL.
- Protecció contra XSS.
- Protecció contra CSRF.
Solució
<?php session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } if ($_SERVER["REQUEST_METHOD"] == "POST") { if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { die("Error: Invalid CSRF token"); } $name = sanitize_input($_POST["name"]); $email = sanitize_input($_POST["email"]); $message = sanitize_input($_POST["message"]); if (empty($name) || empty($email) || empty($message)) { echo "Tots els camps són obligatoris."; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo "L'adreça de correu electrònic no és vàlida."; } else { try { $conn = new PDO("mysql:host=localhost;dbname=database", "username", "password"); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("INSERT INTO users (name, email, message) VALUES (:name, :email, :message)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email); $stmt->bindParam(':message', $message); $stmt->execute(); echo "Nou registre creat correctament"; } catch(PDOException $e) { echo "Error: " . $e->getMessage(); } $conn = null; } } function sanitize_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?> <form method="post" action=""> <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> Nom: <input type="text" name="name"><br> Correu electrònic: <input type="text" name="email"><br> Missatge: <textarea name="message"></textarea><br> <input type="submit" value="Enviar"> </form>
Conclusió
En aquesta secció, hem après com protegir els nostres formularis PHP contra diversos tipus d'atacs comuns. La validació del costat del servidor, la protecció contra injecció SQL, XSS i CSRF són mesures essencials per assegurar la seguretat de les nostres aplicacions web. Amb aquestes tècniques, podem garantir que les dades dels nostres usuaris es gestionen de manera segura i que les nostres aplicacions són més resistents als atacs maliciosos.
Curs de Programació PHP
Mòdul 1: Introducció a PHP
- Què és PHP?
- Configuració de l'Entorn de Desenvolupament
- El teu Primer Script PHP
- Sintaxi i Variables de PHP
- Tipus de Dades en PHP
Mòdul 2: Estructures de Control
Mòdul 3: Funcions
- Definició i Crida de Funcions
- Paràmetres de Funció i Valors de Retorn
- Àmbit de Variables
- Funcions Anònimes i Closures
Mòdul 4: Arrays
Mòdul 5: Treballant amb Formularis
Mòdul 6: Treballant amb Fitxers
- Lectura i Escriptura de Fitxers
- Funcions de Gestió de Fitxers
- Permisos de Fitxers
- Funcions de Directori
Mòdul 7: Programació Orientada a Objectes (OOP)
- Introducció a OOP
- Classes i Objectes
- Propietats i Mètodes
- Herència
- Interfícies i Classes Abstractes
- Traits
Mòdul 8: Treballant amb Bases de Dades
- Introducció a les Bases de Dades
- Connexió a una Base de Dades MySQL
- Realització d'Operacions CRUD
- Ús de PDO per a la Interacció amb Bases de Dades
- Seguretat en Bases de Dades
Mòdul 9: Tècniques Avançades de PHP
- Gestió d'Errors i Excepcions
- Sessions i Cookies
- Expressions Regulars
- Treballant amb JSON i XML
- PHP i Serveis Web
Mòdul 10: Frameworks PHP i Millors Pràctiques
- Introducció als Frameworks PHP
- Començant amb Laravel
- Arquitectura MVC
- Millors Pràctiques en Desenvolupament PHP
- Proves i Depuració