tisdag 10 november 2009

Säkerhet i webbapplikationer (undvik SQL injections)

Säkerhet i webbapplikationer är ett omspännande område. Det skulle till och med kunna vara titeln på en hel kurs. De enkla säkerhetshålen går att sammanfatta i "Sanitize your input". Det är dock långt ifrån hela sanningen. Följande bild på temat "SQL injection", visar hur illa det kan gå.



Bilden är från http://xkcd.com/327/ och licensierad enligt Creative Commons.

För den som vill veta mer om SQL injections så är Wikipedia en bra startplats.
http://en.wikipedia.org/wiki/SQL_injection

Det enklaste sättet att undvika liknande SQL injections är att alltid kontrollera input-värden. Följande tre exempel visar principer för hur du kan "santize your input" i PHP.

// -------------------------------------------------------------------------
//
// Take care of _GET variables. Store them in a variable (if they are set).
// Then prepare the WHERE part of the DELETE-statement, but only if the _GET
// variables has a value.
//

// http://php.net/manual/en/function.is-numeric.php
//

$idLarare = isset($_GET['idLarare']) ? $_GET['idLarare'] : '';

if(!
is_numeric($idLarare)) {
    die(
"idLarare måste vara ett integer. Välj vilken lärare du vill radera och försök igen.");
}



och/eller


// -------------------------------------------------------------
//
// Take care of GET variables, and validate them
//

// http://php.net/manual/en/function.filter-input.php
//
$antal filter_input(INPUT_GET'antal'FILTER_VALIDATE_INT);
if(
$antal === FALSE || $antal 0) die("Felaktigt värde."); 


och/eller

// -------------------------------------------------------
//
// Prepare and perform a SELECT query
//
// http://php.net/manual/en/mysqli.query.php
// http://php.net/manual/en/mysqli.real-escape-string.php
// http://php.net/manual/en/mysqli-result.num-rows.php
//

// Sanitize data
$search $mysqli->real_escape_string($search);

// Prepare query
$query = <<
SELECT
    *
FROM
    VKompisUtrustning
WHERE
    Namn LIKE '%
{$search}%'
    OR
    Smeknamn LIKE '%
{$search}%'
    OR
    Utrustning LIKE '%
{$search}%'
;
EOD;


Dessa tre exempel visar på hur du kan och bör validera den användar-input du får. Kontrollera alltid för att undvika säkerhetshål.

Jag vill läsa mer om säkerhet...

PHP-manualen, ett stycke om säkerhetsaspekter i PHP:

http://www.php.net/manual/en/security.php

Boken "Databasteknik" hanterar rättigheter i databasen med GRANT och hur man kopplar sig mot databas.
  • Databasteknik: Kapitel 13 Säkerhet i databaser.
Boken "Beginning PHP and MySQL" finns det ett säkerhetsrelaterade kapitel som tar upp konfigurering av PHP, "sanitizing input", skydda data och kryptering.
  • Chapter 21: Secure PHP Programming
Läs boken via Google Books.

1 kommentar:

  1. Ett annat vanligt och säkert sätt att lösa detta är med Prepared statement.

    http://php.net/manual/en/pdo.prepared-statements.php

    //Peter

    SvaraRadera