34
1 SQLrand: Preventing SQL Injection Attacks Stephen W. Boyd & Angelos D. Keromytis Columbia University Elia Gaglio 809477 & Mirco Tonin 804425 Seminario AVP a.a. 2006/2007:

SQLrand: Preventing SQL Injection Attacks

  • Upload
    moses

  • View
    83

  • Download
    1

Embed Size (px)

DESCRIPTION

Seminario AVP a.a. 2006/2007:. SQLrand: Preventing SQL Injection Attacks. Stephen W. Boyd & Angelos D. Keromytis. Columbia University. Elia Gaglio 809477 & Mirco Tonin 804425. code injection attacks. sql injection attacks. Code injection attacks. - PowerPoint PPT Presentation

Citation preview

Page 1: SQLrand: Preventing SQL Injection Attacks

1

SQLrand: Preventing SQL Injection Attacks

Stephen W. Boyd & Angelos D. Keromytis

Columbia University

Elia Gaglio 809477 & Mirco Tonin 804425

Seminario AVP a.a. 2006/2007:

Page 2: SQLrand: Preventing SQL Injection Attacks

2

Code injection attacks

“SQL injection attack” è un’istanza dei code injection attacks

Code injection attacks: classe di attacchi che sfruttano il buffer overflow

analisi di un attacco basato sul buffer overflow:

definizione informale: un buffer overflow si verifica ogni qual volta l’insieme dei dati è più grande del buffer ove dovranno essere memorizzati

conseguenza: sovrascrittura della porzione di memoria successiva al buffer, contenente istruzioni macchina necessarie ad una normale esecuzione del programma

code injection attacks

sql injection attacks

Page 3: SQLrand: Preventing SQL Injection Attacks

3

Buffer Overflow (1/3)

Contesto fondamentale per il verificarsi di un BOF:

chiamata ad una funzione

Esempio. Consideriamo il seguente scenario: architettura Intel x86 (32 bits):

registri, salvati nello stack, coinvolti nel BOF: EBP (Base Pointer)(4 bytes): puntatore alla base della

porzione dello stack che stiamo utilizzando EIP (Instruction Pointer) (4 bytes): puntatore

all’istruzione successiva crescita dello stack verso indirizzi bassi di memoria

“buff”: buffer di 8 caratteri (8 bytes) chiamata alla funzione del C, gets: legge dallo

standard input, copia quanto letto in “buff” senza fare nessun controllo se la stringa inserita sia più grande del buffer di destinazione

OBIETTIVO: sfruttare gets per sovrascrivere i registri EBP e EIP salvati

sullo stack, alterando così il normale flusso di esecuzione del programma

l’attaccante deve conoscere

l’architettura del sistema target

Page 4: SQLrand: Preventing SQL Injection Attacks

4

1. void leggistringa(void){

2. char buff[8];

3. gets(buff);

4. }

5.

6. int main(void){

7. leggistringa();

8. return(0);

9. }

programma C:

riem

pim

ento

dello

sta

ck

0x00000000

indirizzi alti

00401258 push ebp

00401250 call 00401258

00401255 …………

assembler:

EIP: 00401255

EBP

buff[0]:buff[1]:buff[2]:buff[3]:buff[4]:buff[5]:buff[6]:buff[7]:

12345678

4 bytes

1 byte...

stringa in input: 12345678aaaabbbb

0x61616161 0x626262

62

aaaa: 61616161bbbb: 62626262

buffer overflow

All’uscita della funzione, avremo che EIP=0x62626262 EBP=0x61616161

Buffer Overflow (2/3) (animata)

Page 5: SQLrand: Preventing SQL Injection Attacks

5

Cosa succede? La cpu tenterà di eseguire l’istruzione che si trova

all’indirizzo contenuto nel registro EIP ovvero 0x62626262, incorrendo in uno di questi casi:

il numero esadecimale 0x62626262 rappresenta un indirizzo che va fuori dall’intero spazio di memoria dedicato al processo

segmentation fault

0x62626262 è un indirizzo valido per il processo in esecuzione. Tale indirizzo potrebbe puntare a del codice maligno inserito da un attaccante

code injection attack

Buffer Overflow (3/3)

Page 6: SQLrand: Preventing SQL Injection Attacks

6

Contromisura: ISR all’interno dei code injection attacks, ricadono

alcuni tipi di attacchi recenti e poco conosciuti:

SQL injection Unix command line Perl code injection

sebbene le tecniche usate in ogni tipo d’attacco differiscono tra loro, tutte hanno un denominatore comune:

l’attaccante inserisce e fa eseguire codice di sua scelta: codice macchina, shell commands, SQL queries,…

da tale fatto, si ricava che alla base di ogni code injection attack c’è la conoscenza da parte dell’attaccante circa l’ambiente / linguaggio interpretato di programmazione del sistema target

code injection attacks

sql injection attacks

unix shell command

s

Perl code injection

contromisura: un approccio generale di prevenzione verso qualsiasi code injection attack: Instruction-Set Randomization

Page 7: SQLrand: Preventing SQL Injection Attacks

7

Un pò di storia…

inquadramento storico:

anno 2003 Columbia University : Countering Code-Injection Attacks With

Instruction-Set RandomizationGaurav S. Kc, Angelos D. Keromytis, Vassilis Prevelakis

anno 2004 Columbia University: SQLrand: Preventing SQL Injection Attacks

Stephen W. Boyd, Angelos D. Keromytis

applicazione del metodo ISR al linguaggio SQL

nostro articolo

Page 8: SQLrand: Preventing SQL Injection Attacks

8

Instruction-Set Randomization

per ogni processo, attraverso una chiave di codifica la più grande possibile, viene creato un insieme unico di istruzioni randomizzate

tali nuove istruzioni andranno a sostituire il codice sorgente del programma originale

verrà creato un ambiente di esecuzione unico per il running process così che l’attaccante non conosce il “linguaggio” usato e di conseguenza non puo’ “speak” alla macchina (non conosce la key di randomizzazione)

due alternativi approcci nell’uso della chiave per la codifica/decodifica (architettura x86 a 32 bits):

XOR bit a bit tra istruzione e chiave:D xor KEY = E E xor KEY= D

(codifica e decodifica hanno la stessa chiave)

attacco brute force: 232 trasposizione randomizzata (basata sulla

chiave) dei bit: (la chiave di decodifica sarà l’inversa) attacco brute force: 32! ( 32! >> 232) => sicurezza maggiore

ENCODED INSTRUCTION

STREAMCPU

ENCODING KEY

xordecoded instruction stream

in ogni caso, una chiave di 32 bits è sufficiente per una protezione verso attacchi di code injection

Page 9: SQLrand: Preventing SQL Injection Attacks

9

Esecuzione di un randomized program

ISR è focalizzato primariamente su attacchi contro remote services (http, dns,…): attacchi che non richiedono un local account sul sistema target

Esecuzione di un generico programma: il codice di ciascun processo (P) è caricato dal rispettivo file eseguibile

memorizzato su disco (efP)

DkeyP

disco

efP

DkeyP

DkeyP

ramSO

PCB: registers:

CPU

tale ‘executable file’ contiene all’interno dell’header, l’appropriata chiave di decodifica (DkeyP) del processo caricato in memoria

nel frattempo, il sistema operativo estrae la chiave di decodifica dall’header dell’eseguibile e la memorizza nel rispettivo Process Control Block del processo

quando la cpu eseguirà il processo P, la chiave di decodifica (DkeyP) sarà presa dal PCB e copiata in un speciale registro del processore

ciò avviene attraverso un’istruzione privilegiata GAVL che permette un accesso in sola scrittura nel speciale registro di CPU.

P

GAVL

Page 10: SQLrand: Preventing SQL Injection Attacks

10

per quei programmi che non sono stati randomizzati, viene fornita una speciale chiave (chiave nulla), che quando caricata attraverso l’istruzione GAVL, disabilita il processo di decodifica

l’esecuzione delle randomization instructions, necessita della scelta tra due possibili soluzioni:

l’utilizzo di una apposita categoria di processori programmabili

(e.g. TransMeta Crusoe, alcuni ARM-based systems)

l’introduzione di un ambiente di esecuzione protetto che emuli una CPU convenzionale

sandboxing environment sarà composto da:

• un CPU emulator: bochs (emulatore open source architetture x86)

• sistema operativo

• l’insieme di processi che si vuole proteggere

Ambiente di esecuzione (1/2)

Page 11: SQLrand: Preventing SQL Injection Attacks

11

Performance

ftp sendmail

fibonacci

bochs 39.0s ≈28 s 5.73s (93s)

linux 29.2s ≈ 1.35s 0.322s

ftp & sendmail (processi I/O intensive): una perdita contenuta nelle performance

fibonacci (CPU intensive application): tremendo slowdown (inaccettabile)

risultati sperimentali:

tempo di esecuzione (in secondi) per identici file binari su Bochs e una macchina Linux (sulla quale è stato fatto girare bochs)

Page 12: SQLrand: Preventing SQL Injection Attacks

12

ISR su altri linguaggi (1/2)

Le idee e i concetti, introdotti al fine di ottenere un’esecuzione sicura delle istruzioni macchina, sono state estese per garantire la sicurezza d’esecuzione di diverse tipologie di programmi:

Perl files: utilizzo dello script Perltidy:

input: ns. programma perl Pforeach $k (sort keys %$tre){ $v = $tre ->{$k}; die ``duplicate key $k\n’ ’ if defined $list {$k}; push @list, @{ $list{$k} };}

output: programma P’, dove ad ogni costrutto perl in P è stata appesa la chiave (‘tag’)foreach123456789 $k (sort123456789 keys %$tre){

$v =123456789 $tre ->{$k}; die123456789 ``duplicate key $k\n’ ’ if123456789 defined123456789 $list {$k}; push123456789 @list, @{ $list{$k} };}

la chiave (‘tag’) viene fornita via a command line argument è necessario una modifica dell’analizzatore lessicale dell’interprete Perl,

affinchè possa riconoscere le keywords seguite dal corretto ‘tag’

Page 13: SQLrand: Preventing SQL Injection Attacks

13

Script Unix:

utilizzo di uno script CGI per la generazione di randomized bash scripts

ogni shell command dello script unix avrà in append la chiave di randomizzazione (‘tag’)

l’interprete bash dovrà essere modificato al fine di riconoscere le nuove keywords (commad+tag)

#!/bin/shif987654 [ x$1 ==987654 x””; then987654 echo987654 “Must provide directory name.” exit987654 1fi987654

/bin/ls987654 –l $1exit987654 0

ISR su altri linguaggi (2/2)

Page 14: SQLrand: Preventing SQL Injection Attacks

14

SQL Injection Attacks:

SQL Injection Attacks:

SQL Injection Attacks è un code injection attack verso un DB…

Attacchi orientati verso script CGI che creano dinamicamente query SQL

OBIETTIVO: carpire/modificare/inserire informazioni verso un DB interfacciato da una web application

Diverse tipologie di attacco possibile, le quali sfruttano vulnerabilità differenti…

Page 15: SQLrand: Preventing SQL Injection Attacks

15

Esempi di SQL Injection Attacks [1/5]

• CONTESTO: pagina di login ad un servizio web, realizzata mediante un’applicazione CGI (si richiedono username e password)

• Nel momento in cui l’utente inserisce i dati viene generata la query:

• Un eventuale utente maligno inserendo nel campo username la stringa ‘or 1=1; --’ causa la generazione da parte dello script della query:

“select * from mysql.user where username = ’ ” . $uid . ” ’ and password = password(’ ” . $pwd . ” ’);”

“select * from mysql.user where username = ’ ’ or 1=1; --’ ’ and password = password(’_any_text_’);”

Page 16: SQLrand: Preventing SQL Injection Attacks

16

Esempi di SQL Injection Attacks [2/5] (animata)

• CONTESTO: applicazione ASP che si interfaccia tramite driver ODBC SQL Server Driver ad un generico DBMS

• Esiste la possibilità di attaccare il DB sfruttando i messaggi di errore forniti:

• Se l’utente inserisse un username fasullo aaa’ verrebbe invocata la URL:

http://127.0.0.1/login.asp?userid=aaa‘

• L’apice finale porterebbe però al seguente messaggio di errore:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark before the character string 'aaa' AND password = ''.

/login.asp, line 7

password

Page 17: SQLrand: Preventing SQL Injection Attacks

17

Esempi di SQL Injection Attacks [3/5] (animata)

• Si può sfruttare la conoscenza acquisita per invocare una nuova URL fittizia in modo da ottenere il nome delle colonne di una tabella:

http://127.0.0.1/login.asp?userid=ddd'%20group%20by%20(password)--

Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'tblUsers.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

/login.asp, line 7

• Il procedimento prosegue fino a quando tutti i nomi delle colonne sono scoperti…

tblUsers

password username

Page 18: SQLrand: Preventing SQL Injection Attacks

18

Esempi di SQL Injection Attacks [4/5] (animata)

http://127.0.0.1/login.asp?userid=aaa'%20group%20by%20(username)--

Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'tblUsers.lastloggedin' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. /login.asp, line 7

• E’ anche possibile determinare il tipo relativo a ciascuna colonna della tabella:

http://127.0.0.1/login.asp?userid=aaa'%20compute%20sum(username)--

Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a nvarchar data type as an argument. /login.asp, line 7

tblUsers

usernamepassword lastloggedin

nvarchar

Page 19: SQLrand: Preventing SQL Injection Attacks

19

Esempi di SQL Injection Attacks [5/5] (animata)

• Dopo aver a disposizione la struttura della tabella sarà possibile da parte dell’attaccante inserire un nuovo account fasullo nel DB:

http://127.0.0.1/login.asp?userid=aaa' insert into tblusers(username,password,lastloggedin,status) values

('jsmith','secret','Oct 31 2000 8:52PM','foo')--

tblUsers

usernamepassword lastloggedin status

nvarchar nvarchar nvarchardate

jsmithsecret Oct 31 2000 8:52PM foo

Page 20: SQLrand: Preventing SQL Injection Attacks

20

SQL Injection Attacks – alcune soluzioni

• Come si possono fronteggiare gli SQL Injection Attacks?

• Accorgimenti per aumentare la sicurezza dell’applicazione (uso di caratteri di escape, filtraggio dei messaggi di errore, limitare la lunghezza dei campi di input, ecc.);

• Utilizzo di costrutti “safe” (es. Prepared statement):

Libreria per la gestione in automatico della formattazione dei tipi rappresentabili nel DBMS (stringhe, date, ecc.)

Garantisce una sicurezza sull’esatta sintassi della query SQL risultantePreparedStatement ps = conn.prepareStatement (“SELECT * FROM mysql.user WHERE username = ? AND password = ?”);

String user = req.getParameter(“userid”);

String pwd = req.getParameter(“password”);

ps.setString(1, user);

ps.setString(2, pwd);

ResultSet rs = ps.executeQuery();

Page 21: SQLrand: Preventing SQL Injection Attacks

21

SQL Injection Attacks – SQL Randomization [1/6]

• Si possono inoltre utilizzare delle tecniche specializzate molto interessanti, SQL Randomization:

Soluzione efficace per fronteggiare SQL Injection Attacks

Tecniche e principi derivati dall’ Instruction Set Randomization

Query randomizzate prodotte dallo script CGI

SQL Randomization

Necessità di modificare l’interprete SQL del DB (in analogia all’approccio seguito per ISR)

introduzione di un ling. sql modificato riscrittura dei precedenti programmi

Possibilità di usare: una key per ogni applicazione keys differenti per applicazioni differenti

Introduzione di un proxy per effettuare la de-randomizzazione delle query

Page 22: SQLrand: Preventing SQL Injection Attacks

22

SQL Injection Attacks – SQL Randomizations [2/6]

• Introduzione di un proxy per de-randomizzare le query prodotte lato client:

• In questo modo le query prodotte lato client saranno comprensibili dall’interprete SQL del DB

• Il proxy lavora esclusivamente a livello sintattico, effettuando anche il filtraggio dei messaggi di errore provenienti dal DB

Page 23: SQLrand: Preventing SQL Injection Attacks

23

SQL Injection Attacks – SQL Randomizations [3/6]

• Le 2 principali componenti del proxy sono:

1) Elemento di de-randomizzazione:

presenza di un parser FLEX modificato (legge un array di caratteri di

input in arrivo dalla rete)

trattamento esplicito per gli errori sintattici (disconnessione del client ed

invio di un generico messaggio di sintax error)

2) Protocollo di comunicazione:

MYSQL fornisce API per l’accesso al DB ma non fornisce librerie server-

side che accettano e disassemblano i pacchetti inviati

Utilizzo di una libreria di base per gestire query, errori e pacchetti di

disconnessione

Page 24: SQLrand: Preventing SQL Injection Attacks

24

SQL Injection Attacks – SQL Randomizations [4/6] (animata)

CLIENT PROXY MYSQL DBMSLibreria: gestisce

query, errori e pacchetti di

disconnessione

• Proxy componente invisibile verso il client

proxy e DBMS sono sulla stessa macchina

(è necessario solamente specificare la porta relativa al proxy)

• La soluzione finale proposta per gestire le comunicazioni è la seguente:

api mysql LATO CLIENT

api mysql LATO CLIENT

C CS S

Page 25: SQLrand: Preventing SQL Injection Attacks

25

• La randomizzazione è basata sull’append di una sequenza di interi random applicata alle keywords di ogni query. Nel nostro esempio:

• Vediamo un semplice esempio pratico di randomizzazione. Partiamo dalla seguente query:

SQL Injection Attacks – SQL Randomizations [5/6]

select gender, avg (age) from cs101.students where dept = %d group by gender

select123 gender, avg123 (age) from123 cs101.students where123 dept = %d group123 by123 gender

Page 26: SQLrand: Preventing SQL Injection Attacks

26

SQL Injection Attacks – SQL Randomizations [6/6]

• A questo punto se un utente maligno volesse formulare un tipico attacco mediante l’inserimento della stringa ’ or 1=1; --’ causerebbe la generazione della query:

select gender, avg (age) from cs101.students where dept = ’ or 1=1; --’ group by gender

• La randomizzazione della query comporta che ogni keyword del linguaggio SQL sia randomizzata. Ma la or, essendo una parola dell’input utente, non è soggetta a randomizzazione la query viene considerata maligna!

select123 gender, avg123 (age) from123 cs101.students where123 dept = ’ or 1=1; --’ group123 by123 gender

Page 27: SQLrand: Preventing SQL Injection Attacks

27

Prove sperimentali

Sono state effettuate due tipologie di test:

1. un’applicazione CGI creata (ad hoc) dagli autori stessi:

nessuna validazione sull’input possibilità di inserire codice SQL nella clausola “where” che si

aspetta un account ID senza SQLrand proxy: un attaccante facilmente ottiene

informazini sugli account degli utenti con SQLrand proxy: injected statement identificato ed emissione

di un generico messaggio d’errore

2. identificare SQL injection attacks su applicazioni web pre-esistenti e molto diffuse:

phpBB v2.0.5 php-Nuke

attacchi neutralizzati con l’uso del proxy

Page 28: SQLrand: Preventing SQL Injection Attacks

28

Performance evaluation

Scenario di test: 3 insiemi di utenti concorrenti: 10 - 25 - 50 esecuzione delle classi in modo round robin in totale 100 prove: ciascuna con 5 differenti query concorrenti lunghezza chiave: 32 bytes lunghezza media queries: 639 bytes la dimensione dei record delle tabelle ranged da 20 a poco piùdi 11.000 records database, proxy e client running su separate macchine x86 con SO RedHat Linux, e tutte sulla stessa rete

Users Min Max Mean Std

10 74 1300 183.5 126.9

25 73 2782 223.8 268.1

50 73 6533 316.6 548.8

proxy overhead (in microsecondi)

Nel peggior dei casi, si ottiene un ritardo di 6.5 millisecondi per ciascuna query

sapendo che se intercorre un tempo che varia da pochi secondi a 10 secondi (a seconda dello scopo dell’applicazione) la risposta di una web application è considerata persa

l’overhead introdotto dal proxy è insignificante

future work: sviluppo di developing tools per assistere i programmatori nell’utilizzo di SQLrand

Page 29: SQLrand: Preventing SQL Injection Attacks

29

ISR: vantaggi - svantaggi

riportandoci al contesto più generale: Instruction-Set Randomization

Vantaggi:

possibile ri-randomizzazione periodica dei programmi in modo da minimizzare il rischio di attacchi persistenti. Ovvero:

nei sistemi operativi open source: quando il sistema viene ricompilato nelle distribuzioni binarie: periodica re-randomization attraverso un automated

script in fase d’installazione

ISR offre trasparenza ad applicazioni, linguaggi e compilatori, nessuno dei quali deve essere modificato

Svantaggi:

l’utilizzo di cpu programmabili per il supporto di istruzioni randomizzate feature non implementata dallla maggioranza dei processori in commercio

alternativamente: emulatore inaccettabile overhead in tutte le applicazioni CPU intesive

Page 30: SQLrand: Preventing SQL Injection Attacks

30

Estensioni & sviluppi futuri [1/4]

• 4 filoni di ricerca contro i Buffer Overflow Attacks:

1) Safe Languages and Compilers: - introduzioni di linguaggi di programmazione

safe (Java, Modula3, ecc.)

- estensioni dei vecchi linguaggi per renderli

safe (es. C), senza snaturarne le proprietà

▪ linguaggi ad alto livello e astratti

Java/Modula3 ▪ nessuna gestione esplicita della memoria

▪ no al controllo dei dati a basso livello

Page 31: SQLrand: Preventing SQL Injection Attacks

31

Estensioni & sviluppi futuri [2/4]

• Come è possibile rendere un linguaggio d’origine “safe” ?

Librerie sicure librerie condivise e pre-caricate per intercettare le

chiamate di funzione delle librerie – trasparenti al programmatore;

API librerie esplicitamente richiamabili da un programma.

Forniscono delle primitive maggiormente sicure.

Vantaggi:

semplice utilizzo da parte del programmatore

non è necessario passare ad un nuovo linguaggio di programmazione

Svantaggi:

protezione riferita solo ad alcune primitive specifiche

Page 32: SQLrand: Preventing SQL Injection Attacks

32

Estensioni & sviluppi futuri [3/4]

2) Compiler Tricks: utilizzo di patch per i più diffusi compilatori (es. gcc)

protezione verso accessi/allocazioni di memoria, gestione

corretta dei puntatori, controllo sulle dimensioni e rispetto

dei limiti degli array, ecc.

contro: mancanza di protezione verso alcuni tipi di code injection attack / introduzione di overhead

3) Process Sanboxing: esecuzione dei processi in un ambiente protetto

filtraggio degli accessi alle system calls

effettuare dei checks a run-time del programma, monitorando i trasferimenti del controllo del flusso del programma (salti condizionati, salti incondizionati, ecc.)

Page 33: SQLrand: Preventing SQL Injection Attacks

33

Estensioni & sviluppi futuri [4/4]

4) Source Code Analysis: rilevazione di vulnerabilità nel codice (es. gets() in C)

tipicamente si sollevano dei warning a tempo di compilazione del programma

esistono 2 tipi di approcci:

approccio statico: tecniche di analisi statica per rilevare classi di attacchi e vulnerabilità conosciute

approccio dinamico: analisi a run-time per effettuare dei controlli sulle procedure/funzioni richiamate, grazie all’introduzione di una data structure che fornisca informazioni sulle strutture allocate nel programma

Page 34: SQLrand: Preventing SQL Injection Attacks

34

Bibliografia G. S. Kc, A. D. Keromytis, and V. Prevelakis. Countering Code-Injection Attacks With

Instruction-Set Randomization. In Proceedings of the ACM Computer and Communications Security (CCS) Conference, pages 272–280, October 2003.

Luigi Auriemma. Buffer overflow: spiegazione tecnica ed esempio pratico. Aprile 2003.http://www.siforge.org/articles/2003/04/15-bofexp.html

G. Mazzei, A. Paolessi, S. Volpini. Buffer Overflow. In Corso di Sistemi Operativi, Facoltà di Ingegneria, Università degli studi di Siena, anno accademico 2001/2002.http://www.clusit.it/whitepapers/GASBof.pdf

T. Jim, G. Morrisett, D. Grossman, M. Hicks, J. Cheney, and Y. Wang. Cyclone: A safe dialect of C. In Proceedings of the USENIX Annual Technical Conference, pages 275–288, Monterey, California, June 2002.

T. C. Miller and T. de Raadt. strlcpy and strlcat: Consistent, Safe, String Copy and Concatentation. In Proceedings of the USENIX Technical Conference, Freenix Track, June 1999.

A. Baratloo, N. Singh, and T. Tsai. Transparent run-time defense against stack smashing attacks. In Proceedings of the USENIX Annual Technical Conference, June 2000.

D. Litchfield. Web Application Disassembly wth ODBC Error Messages. http://www.nextgenss.com/papers/webappdis.doc