07/03/2012

Paginazione PHP con HTTP POST

La paginazione è uno dei metodi più gettonati per ripartire i contenuti dinamici di un sito Web su più pagine. Spesso, però, per ragioni di sicurezza (e non solo) risulta più conveniente sostituire il GET con il POST, avvalendosi di un pò di codice Javascript da utilizzare lato client.

 

web.jpg

Ecco un il codice (testato e funzionante):

$query = "SELECT * FROM Utenti";
           
$risultato = $mysqli->query($query);

$count = mysqli_num_rows($risultato);
$per_pagina = 30; //secondo parametro di LIMIT
$tot_pagine = ceil($count / $per_pagina); //approssima la divisione all'intero
$pagina_corrente = 1;
           
 if(isset($_POST['pagina']) && is_numeric($_POST['pagina']))
 {
            $pagina_corrente = $_POST['pagina'];
 }
$primo = ($pagina_corrente - 1) * $per_pagina; //primo parametro di LIMIT
$query = $query."ORDER BY C.Cognome ASC LIMIT $primo, $per_pagina";
           
$risultato = $mysqli->query($query1);

lato server, mentre lato client il codice Javascript è così definito:

<script type="text/javascript">
function invia()
{
    document.loginform4.method="post";
    document.loginform4.action="visualizzacontatti.php";
    document.loginform4.submit();
}
</script>

Inoltre, il numero di pagina calcolato nell'ambito del codice PHP verrà salvato in un campo di input hidden:

<input type="hidden" name="pagina" id="pagina" value="<?php echo $pagina_corrente?>"/>

I numeri di pagina cliccabili saranno così definiti:

<div id="paginazione">
    <p align ="center">
    <?php
    if($pagina_corrente == 1 || $count == 0) //se siamo nella prima pagina oppure non vi sono record
    {
           
        echo "&lt;&lt; Precedente";
    }
    else
    {
        $pagina_precedente = ($pagina_corrente - 1);
        ?>
        <a href ="javascript:invia()" onclick="document.loginform4.pagina.value=<?php echo $pagina_precedente?>"><?php echo "<< Precedente"?></a>
        <?php
    }
   
    echo ' Pagine: ';
   
    for($i = 1; $i <= $tot_pagine; $i++)
    {
        if($i == $pagina_corrente)
        {
            echo "[$i]";
        }
        else
        {
        ?>   
        <a href ="javascript:invia()" onclick="document.loginform4.pagina.value=<?php echo $i?>"><?php echo $i ?></a>
        <?php
        }
    }
    if($pagina_corrente == $tot_pagine) // se siamo nell'ultima pagina
    {
        echo "Successiva >>";
    }
    else
    {
        $prossima_pagina = ($pagina_corrente + 1);
        ?>
        <a href ="javascript:invia()" onclick="document.loginform4.pagina.value=<?php echo $prossima_pagina?>"><?php echo "Successiva >>"?></a>
        <?php
    }
    ?>
    </p>
    </div>

Enjoy!

15:48 Scritto da: nazarenolatella in Web Editing | Link permanente | Commenti (0) | Segnala | Tag: php, javascript, paginazione, post, get | OKNOtizie |  Facebook

27/02/2012

Tipi di attacco CSRF

In questo post ho descritto il concetto su cui si basa l'attacco CSRF, mentre in quest'altro post ho provato ad elencare alcuni rimedi da utilizzare per mitigare tale tipologia di attacco.

 

csrf,refrected,login,stored,token,html,form,javascript,xss

Adesso vedremo quali sono i diversi tipi di attacco CSRF.

Login CSRF

L'attaccante invia una URL trappola alla vittima, contenente le proprie credenziali di accesso sul sito vulnerabile. In questo modo, appena la vittima effettuerà il login e se il sito lo consente, l'attaccante riuscirà a tenere traccia dei suoi comportamenti (sezioni visitate, link cliccati et similia), semplicemente accedendo al proprio profilo in un secondo momento (vedi YouTube).

Stored CSRF

Il sito vulnerabile consente l'inserimento di codice lato client (Javascript e/o HTML) da parte degli utenti autenticati. Questa in realtà è una vulnerabilità agli attacchi XSS che però può essere utilizzata per creare delle richieste CSRF. Supponiamo che l'attaccante utilizzi i campi di input di un form per iniettare del codice HTML contenente un ulteriore form caratterizzato da diversi campi hidden. Tali campi verranno popolati ad-hoc in modo da creare le giuste variabili da inviare al server tramite HTTP POST.

Ad esempio si potrebbe avere un form del tipo:

<form name="csrf" id="csrf" method="post" action="pagina.php">
<input type="hidden" name="nome" value="Mario" />
<input type="hidden" name="cognome" value="Rossi" />
<input type="hidden" name="telefono" value="06676785" />
</form>

e la seguente immagine "trappola":

<img src="images/immagine.jpg" alt="immagine" onclick="javascript:document.forms['csrf'].submit()" />

L'utente vittima, cliccando sull'immagine, invierebbe i dati al server, i quali verrebbero così processati (si pensi alla classica transazione finanziaria).

Tale tipologia di attacco CSRF è quella che ha un ottimo margine di riuscita, in quanto l'attaccante è certo che l'utente vittima sia effettivamente loggato al sito vulnerabile (altrimenti non potrebbe accedere al form precedentemente forgiato).

Reflected CSRF

L'attacco ha come sorgente "terze parti", ad esempio siti esterni, applicazioni di instant messaging, client di posta et similia. I margini di riuscita sono relativamente bassi, in quanto l'attaccante non può sapere a priori se la vittima è loggata o meno sul sito vulnerabile nel momento in cui viene sferrato l'attacco vero e proprio.

Le metodologie di attacco sono quelle classiche, ovvero creazione di una URL "trappola" oppure l'uso di un form creato ad hoc.

Il form che l'attaccante potrebbe creare è simile a quello visto in precedenza, eccezion fatta per l'attributo action:

<form name="csrf" id="csrf" method="post" action="http://www.sitovulnerabile.it/pagina.php">
<input type="hidden" name="nome" value="Mario" />
<input type="hidden" name="cognome" value="Rossi" />
<input type="hidden" name="telefono" value="06676785" />
</form>

<img src="images/immagine.jpg" alt="immagine" onclick="javascript:document.forms['csrf'].submit()" />

Dai miei esempi si evince come l'HTTP POST offra dei margini di sicurezza migliori rispetto al GET, ma è comunque soggetto ad attacchi CSRF. Per questo, è opportuno utilizzare il token anche se il vostro sito accetta solo dati inviati mediante POST.

Inoltre, nell'ambito degli stored CSRF, se il sito non presenta vulnerabilità XSS (grazie a politiche di input sanitization), il metodo POST associato al controllo del referer HTTP, rappresenta una buona contromisura al CSRF, anche se non ottimale.

Proprio per questo motivo, consiglio di utilizzare i token sempre e comunque.

A presto.

10:00 Scritto da: nazarenolatella in Sicurezza | Link permanente | Commenti (0) | Segnala | Tag: csrf, refrected, login, stored, token, html, form, javascript, xss | OKNOtizie |  Facebook

08/02/2012

Pulsante "like" di Facebook: alcuni trucchetti utili

Ormai il pulsante "like" di Facebook è diventato una moda ed in quanto tale sono sempre di più i siti che usufruiscono di questo gadget. L'inserimento del suddetto pulsante all'interno del codice HTML del proprio sito è praticamente un gioco da ragazzi (basta copiare ed incollare il sorgente autogenerato mediante questa interfaccia user-friendly). I problemi, però, iniziano quando si vuole customizzare pesantemente il "like" di Facebook, ad esempio implementando un evento on click oppure "nascondendo" la barra dei commenti.

fb-like.jpg

Nel primo caso è sufficiente utilizzare un codice javascript simile al seguente

<!--
window.fbAsyncInit = function() {
FB.Event.subscribe('edge.create', function(href, widget) {
//action
});
 };
//-->

Se ad esempio si volesse implementare l'apertura di una finestra pop-up immediatamente dopo il click sul "like", il codice diventerebbe:

<!--
window.fbAsyncInit = function() {
FB.Event.subscribe('edge.create', function(href, widget) {
window.open('vostraurl', '_blank');
});
 };
//-->

Nel caso in cui, invece, si volesse nascondere la barra dei commenti, è necessario lavorare di CSS. Nella fattispecie, occorre attribuire un display:none alla classe .fb_edge_widget_with_comment, utilizzando la keyword !important per evitare possibili sovrascritture di tali impostazioni all'interno della pagina HTML (attraverso il tag style):

.fb_edge_widget_with_comment span.fb_edge_comment_widget iframe.fb_ltr {
display: none !important;}

Ed il gioco è fatto.

A presto.