Questa connessione al database Perl è vulnerabile a SQL Injection

3

Ho questa (ridotta) query del database Perl, e mi chiedo se questo possa essere sfruttato in qualche modo. Questo è da una sfida, quindi so che le cose potrebbero essere fatte in modo diverso, il compito è sfruttarlo.

A mia conoscenza utilizza dichiarazioni preparate ed è quindi considerevole e sicuro. Tuttavia potrei trovare questo , per quanto riguarda i problemi con preventivo e param.

if ('POST' eq request_method && param('username') && param('password')){
    my $dbh = DBI->connect( "DBI:mysql:database_name","database_name", "<censored>", {'RaiseError' => 1});
    my $query="Select * FROM users where username =".$dbh->quote(param('username')) . " and password =".$dbh->quote(param('password')); 

    my $sth = $dbh->prepare($query);
    $sth->execute();
    my $ver = $sth->fetch();
    if ($ver){
        print "win!<br>";
        print "here is your result:<br>";
        print @$ver;
    }
    else{
        print "fail";
    }
    $sth->finish();
    $dbh->disconnect();
}
    
posta Ludisposed 18.12.2017 - 14:03
fonte

3 risposte

2

Non è sicuro, ma non penso che sia sfruttabile.

Il punto è che param può restituire uno scalare o una lista. Nel contesto dell'elenco, se passi username=a&username=b a questa pagina, la lista sarà ("a", "b").

In Perl, se si passa una lista a una funzione, questa viene interpretata come argomenti separati.

quote("a", "b")

È equivalente a

@list = ("a", "b")
quote(@list)

Quindi, se chiami quote(param("username")) , l'utente può fornire il secondo parametro a quote , passando in due valori di username . Poiché il secondo parametro determina come eseguire la quotatura, questo può introdurre una vulnerabilità di SQL injection.

Tuttavia, il modo in cui viene gestito il secondo parametro dipende dal driver DBD, che è diverso per ogni tipo di database. Inoltre, dovrebbe essere effettivamente un riferimento all'hash, ma possiamo solo passare una stringa. Quindi può darsi che esista un driver in cui il passaggio di qualcosa cambia il modo in cui viene eseguita l'escaping, ma non sono riuscito a trovarlo. Il driver Postgres, ad esempio, afferma esplicitamente che "Il secondo argomento per quotare deve essere un hashref".

    
risposta data 19.12.2017 - 16:47
fonte
3

Dopo aver ricreato il sito Web localmente e aver esaminato i documenti

Questo programma Perl è vulnerabile a SQL Injection.

  • Tuttavia, ciò dipende dal driver DBI e potrebbe essere riprodotto solo con MySQL

Ci sono 2 difetti con questo in $dbh->quote(param('paramater'))

  1. You see, param is context-sensitive. In scalar context, if the parameter has a single value (name=foo), it returns that value, and if the parameter has multiple values (name=foo&name=bar) it returns an arrayref.

    Dal SO link , il problema con la chiamata diretta param() è che può restituire un array

  2. As a special case, the standard numeric types are optimized to return $value without calling type_info.

    Dai documenti DBI . Chiamare la citazione come list con SQL_INTEGER come secondo parametro, restituirà un valore non quotato.

Poiché SQL_INTEGER == 4 Tutto ciò che serve è questo script python:

def vuln(url):
    params={"username": "valid_username", "password": ["'lol' or 1", 4]}
    print(requests.post(url, data=params).text)
    
risposta data 20.12.2017 - 18:30
fonte
2

In generale è una cattiva idea usare le variabili POST direttamente (il client è controllato dopo tutto). È meglio fare quanto segue:

  • Limita la dimensione dell'input per limitare i flussi in eccesso.
  • Analizza il valore, per assicurarti del tipo che ti aspetti.
  • Sanatizza il parametro per non includere alcuna istruzione di controllo (senza caratteri di escape), la virgola fa la maggior parte di questo ma non tutti (controlla le istruzioni per la tua versione Perl)
  • Utilizza le dichiarazioni preparate correttamente (come suggerisce @Marc)

Per il resto sembra un buon approccio, ma assicurati di utilizzare software e librerie aggiornate. (Va per qualsiasi applicazione)

    
risposta data 18.12.2017 - 14:39
fonte

Leggi altre domande sui tag