• User

    Sql injection

    Salve, ho un problema enorme. Il mio sito è stato attaccato da un hacker attraverso un sql injection effettuata tramite una pagina di dettaglio il cui parametro id viene passato dalla link posto sulla pagina precedente. Se qualcuno può aiutarmi a proteggere il codice della pagina in questione gli sarei molto grato.


  • Super User

    Mostra il codice e vediamo cosa si può fare.


  • User Attivo

    Eh infatti senza codice non possiamo sapere che tipo di vulnerabilità c'è


  • User

    questo è lo script della pagina attraverso la quale cliccando sul titolo mi si apre la pagina di dettaglio "dett.aspx"
    a target="_self"
    href="../html/dett.aspx?id=<%=news1.getFieldValue("id")%>"><font face="Arial"
    color="#740000" size="-2"><%=news1.getFieldValue("titolo")

    questo è lo script sql della pagina dett.aspx da dove è partito l'attacco sql injection:
    var norewwsQuery : String = "SELECT id,utente,news,data,titolo,image FROM av_news WHERE id = " + NOF_PrepareSQLParameter(Request.QueryString("id"), true) + "";
    var norewwsSortOrder : String = Request.QueryString("NOF_SORT_ORDER_norewws");
    var norewwsSortDir : String = Request.QueryString("NOF_SORT_DIR_norewws");
    if (!NOF_IsEmpty(norewwsSortOrder)) {
    if (norewwsQuery.toLowerCase().indexOf("order by") != -1) {
    norewwsQuery = norewwsQuery.substr(0, norewwsQuery.toLowerCase().lastIndexOf("order by"));
    }
    norewwsQuery += " ORDER BY " + norewwsSortOrder + " " + norewwsSortDir;
    }
    var norewws = (new NOF_ASPDB_STATEMENT()).executeQuery(norewwsQuery, -1);


  • Super User

    La pagina che serve è dett.aspx...


  • User

    ;)<%@ Page debug=true Language=JScript %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SQL" %> <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Data.Odbc" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>dettnews</title>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <meta name="Generator" content="NetObjects Fusion 10 for Windows">
    <SCRIPT SRC="../assets/lib/aspnet/nof_db_misc.js"></SCRIPT>
    <!--#INCLUDE VIRTUAL="/assets/lib/aspnet/nof_db_misc.aspx"-->
    <%
    var NOF_DB_CONN : OdbcConnection = new OdbcConnection("DRIVER={SQL SERVER};SERVER=XX.XXX.XXX.XXX;DATABASE=;Uid=;PWD=;");
    NOF_DB_CONN.Open();%>
    <%
    var norewwsQuery : String = "SELECT id,utente,news,data,titolo,image FROM av_news WHERE id = " + NOF_PrepareSQLParameter(Request.QueryString("id"), true) + "";
    var norewwsSortOrder : String = Request.QueryString("NOF_SORT_ORDER_norewws");
    var norewwsSortDir : String = Request.QueryString("NOF_SORT_DIR_norewws");
    if (!NOF_IsEmpty(norewwsSortOrder)) {
    if (norewwsQuery.toLowerCase().indexOf("order by") != -1) {
    norewwsQuery = norewwsQuery.substr(0, norewwsQuery.toLowerCase().lastIndexOf("order by"));
    }
    norewwsQuery += " ORDER BY " + norewwsSortOrder + " " + norewwsSortDir;
    }
    var norewws = (new NOF_ASPDB_STATEMENT()).executeQuery(norewwsQuery, -1);
    %>
    <script type="text/javascript" src="../assets/jquery.js">
    </script>
    <script type="text/javascript" src="../assets/jmedia.js">
    </script>
    <link rel="stylesheet" type="text/css" href="../html/fusion.css">
    <link rel="stylesheet" type="text/css" href="../html/style.css">
    <link rel="stylesheet" type="text/css" href="../html/site.css">
    <script type="text/javascript" src="./dettnews.js">
    </script>
    </head>
    <body style="background-image: url('../assets/images/norm1.gif'); margin: 0px;">
    <table border="0" cellspacing="0" cellpadding="0" width="987">
    <tr valign="top" align="left">
    <td width="28" height="52"><img src="../assets/images/autogen/clearpixel.gif" width="28" height="1" border="0" alt=""></td>
    <td></td>
    </tr>
    <tr valign="top" align="left">
    <td height="201"></td>
    <td width="959">
    <table border="0" cellspacing="0" cellpadding="0" width="959" style="background-color: rgb(255,255,255); background-image: url('../assets/images/top.jpg'); height: 201px;">
    <tr align="left" valign="top">
    <td> </td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    <table border="0" cellspacing="0" cellpadding="0" width="987">
    <tr valign="top" align="left">
    <td width="28" height="19"><img src="../assets/images/autogen/clearpixel.gif" width="28" height="1" border="0" alt=""></td>
    <td width="959">
    <a id="Flash12" href="../assets/applets/primo.swf"></a></td>
    </tr>
    </table>
    <table border="0" cellspacing="0" cellpadding="0" width="987">
    <tr valign="top" align="left">
    <td width="35" height="13"><img src="../assets/images/autogen/clearpixel.gif" width="35" height="1" border="0" alt=""></td>
    <td></td>
    </tr>
    <tr valign="top" align="left">
    <td height="149"></td>
    <td width="952">
    <table border="0" cellspacing="0" cellpadding="0" width="952" style="background-image: url('../assets/images/bg.gif'); height: 149px;">
    <tr align="left" valign="top">
    <td>
    <table border="0" cellspacing="0" cellpadding="0">
    <tr valign="top" align="left">
    <td width="23" height="17"><img src="../assets/images/autogen/clearpixel.gif" width="23" height="1" border="0" alt=""></td>
    <td></td>
    </tr>
    <tr valign="top" align="left">
    <td></td>
    <td width="915">
    <table id="Table13" border="0" cellspacing="2" cellpadding="2" width="100%" style="height: 117px;">
    <tr style="height: 22px;">
    <td width="222">
    <p style="margin-bottom: 0px;"><!-- <img id="Connector1" height="18" width="18" src="../assets/images/Connector.gif" vspace="0" hspace="0" align="top" border="0"> --></p>
    </td>
    <td width="1"></td>
    <td width="444"></td>
    <td width="222"></td>
    </tr>
    <tr style="height: 22px;">
    <td colspan="2">
    <p style="text-align: center; margin-bottom: 0px;"><!-- <img id="Label108" height="18" width="18" src="../assets/images/Label.gif" vspace="0" hspace="0" align="top" border="0"> --><b><font face="Arial" color="#C62929" size="-1"><%=norewws.getFieldValue("data")%></font></b>          </p>
    </td>
    <td colspan="2">
    <p style="text-align: center; margin-bottom: 0px;"><!-- <img id="Label105" height="18" width="18" src="../assets/images/Label.gif" vspace="0" hspace="0" align="top" border="0"> --><b><font face="Arial" color="#8F8484" size="-1"><%=norewws.getFieldValue("titolo")%></font></b>         <b><span style="color: rgb(182,20,17);">(<!-- <img id="Label107" height="18" width="18" src="../assets/images/Label.gif" vspace="0" hspace="0" align="top" border="0"> --><b><font face="Arial" color="#B61411" size="-1"><%=norewws.getFieldValue("utente")%></font></b>)</span></b></p>
    </td>
    </tr>
    <tr style="height: 22px;">
    <td>
    <p style="margin-bottom: 0px;"><!-- <img id="Image1" height="18" width="18" src="../assets/images/Image.gif" vspace="0" hspace="0" align="top" border="0"> --><img src="<%=norewws.getFieldValue("image")%>" height="150" width="150" border="1"></p>
    </td>
    <td colspan="3">
    <p style="margin-bottom: 0px;"><!-- <img id="Label1" height="18" width="18" src="../assets/images/Label.gif" vspace="0" hspace="0" align="top" border="0"> --><font face="Arial" size="-1"><%=norewws.getFieldValue("news")%></font></p>
    </td>
    </tr>
    <tr style="height: 22px;">
    <td colspan="4"></td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    <table cellpadding="0" cellspacing="0" border="0" width="888">
    <tr valign="top" align="left">
    <td>
    <table border="0" cellspacing="0" cellpadding="0" width="632">
    <tr valign="top" align="left">
    <td width="341" height="43"><img src="../assets/images/autogen/clearpixel.gif" width="341" height="1" border="0" alt=""></td>
    <td width="291"><img src="../assets/images/autogen/clearpixel.gif" width="291" height="1" border="0" alt=""></td>
    </tr>
    <tr valign="top" align="left">
    <td></td>
    <td width="291" class="TextObject">
    <p style="margin-bottom: 0px;"><span style="font-size: 12px; color: rgb(195,242,11);">? 2007-2008 tutti i diritti riservati a <b></b></span></p>
    </td>
    </tr>
    </table>
    </td>
    <td>
    <table border="0" cellspacing="0" cellpadding="0" width="256">
    <tr valign="top" align="left">
    <td width="12" height="37"><img src="../assets/images/autogen/clearpixel.gif" width="12" height="1" border="0" alt=""></td>
    <td></td>
    </tr>
    <tr valign="top" align="left">
    <td height="18"></td>
    <td width="244"><script src="google-analytics.com/urchin.js" type="text/javascript">
    </script>
    <script type="text/javascript">
    _uacct = "UA-1480647-1";
    urchinTracker();
    </script></td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    <table cellpadding="0" cellspacing="0" border="0" width="969">
    <tr valign="top" align="left">
    <td>
    <table border="0" cellspacing="0" cellpadding="0" width="788">
    <tr valign="top" align="left">
    <td width="377" height="16"><img src="../assets/images/autogen/clearpixel.gif" width="377" height="1" border="0" alt=""></td>
    <td width="411"><img src="../assets/images/autogen/clearpixel.gif" width="411" height="1" border="0" alt=""></td>
    </tr>
    <tr valign="top" align="left">
    <td></td>
    <td width="411" class="TextObject">
    <p style="margin-bottom: 0px;"><b><span style="font-size: 12px;">le ditte richiamate nel testo o in banner sono citate a titolo gratuto.  </span></b></p>
    </td>
    </tr>
    </table>
    </td>
    <td>
    <table border="0" cellspacing="0" cellpadding="0" width="181">
    <tr valign="top" align="left">
    <td width="27" height="2"><img src="../assets/images/autogen/clearpixel.gif" width="27" height="1" border="0" alt=""></td>
    <td width="154"><img src="../assets/images/autogen/clearpixel.gif" width="154" height="1" border="0" alt=""></td>
    </tr>
    <tr valign="top" align="left">
    <td></td>
    <td width="154" class="TextObject"> <!-- Histats.com START -->

    <script type="text/javascript" language="javascript">

    var s_sid = 47452;var st_dominio = 4;
    var cimg = 296;var cwi =112;var che =35;
    </script>
    <script type="text/javascript" language="javascript" src="histats.com/js9.js"></script>
    <noscript><a href="it/" target="_blank">
    <img src="histatsstats/0.gif?47452&1" alt="statistiche" border="0"></a>
    </noscript>

    <!-- Histats.com END -->
    <p style="margin-bottom: 0px;"> </p>
    </td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    </body>
    </html>


  • Super User

    Bisogna vedere cosa fa NOF_PrepareSQLParameter, visto il nome mi sembra starno che non controlli il parametro per evitare la SQL injection, comunque se non lo fa prima di richiamarlo va controllato, quindi se ci si aspetta un int va controllato che l'id sia un int, magari facendone il parsing.


  • User

    inanzitutto grazie, ecco il controllo che effettua la funzione NOF_PrepareSQLParameter. Potrebbe essere migliorata o integrata?

    function NOF_PrepareSQLParameter(value, isNumeric) {
    if (!isNumeric) {
    if (value != null) {
    var re = /'/gi;
    value = value.replace(re, "''");
    value = "'" + value +"'";

    Ciao


  • Super User

    Non credo sia tutta la funzione, cosa fa nel caso che isnumeric è true, ovvero nel tuo caso?


  • User

    ti posto tutto il file che effettua i controlli

    <%
    function NOF_ASPDB_RecordSet(dataTable, recsCount, maxRows) {
    this.rs = dataTable;
    this.recsCount = recsCount || -1;
    this.maxRows = maxRows;
    this.hasMore = true;
    this.currentPointer = 0;
    this.Move = function Move(rowNo) {
    this.currentPointer = rowNo;
    }
    this.getCurrentPosition = function getCurrentPosition() {
    return this.currentPointer;
    }
    this.MoveNext = function MoveNext() {
    if (this.rs != null) {
    this.Move(++this.currentPointer);
    }
    }
    this.MovePrevious = function MovePrevious() {
    if (this.rs != null) {
    this.rs.Move(--this.currentPointer);
    }
    }
    this.getRecordsCount = function getRecordsCount() {
    return this.recsCount;
    }
    this.clone = function clone() {
    if (this.rs != null) {
    //return new NOF_ASPDB_RecordSet(this.rs.Clone(1), this.recsCount); //adLockReadOnly
    var rs = new NOF_ASPDB_RecordSet(this.rs, this.recsCount); //adLockReadOnly
    rs.Move(0);
    return rs;
    }
    }
    this.close = function close() {
    /*
    if (this.rs != null) {
    this.rs.Close();
    this.rs = null;
    }
    */
    }
    this.EOF = function EOF() {
    if (this.rs != null) {
    if (this.maxRows > 0 && this.currentPointer > this.maxRows -1) {
    return true;
    } else if (this.recsCount > 0 && this.currentPointer < this.recsCount) {
    return false;
    }
    }
    return true;
    }
    this.BOF = function BOF() {
    if (this.rs != null) {
    return (this.rs.GetEnumerator().Current == null);
    }
    }
    this.getFields = function getFields() {
    if (this.rs != null) {
    return this.rs.Columns;
    }
    }
    this.getField = function getField(name) {
    if (this.rs != null && this.currentPointer < this.recsCount) {
    var x = this.rs.Rows[this.currentPointer];
    return x.Item(name);
    }
    }
    this.getFieldValue = function getFieldValue(name) {
    var field = this.getField(name);
    if (field != null) {
    return field;
    } else {
    return "";
    }
    }
    }
    function NOF_ASPDB_STATEMENT() {
    this.executeQuery = function executeQuery(sql, maxRows) {
    if (sql == null || sql == "") {
    return;
    }
    var dataSet : DataSet = new DataSet();
    var dataAdapter : OdbcDataAdapter = new OdbcDataAdapter(sql, NOF_DB_CONN);
    dataAdapter.Fill(dataSet, sql);
    var table = dataSet.Tables[0];
    return new NOF_ASPDB_RecordSet(table, table.Rows.Count, maxRows);
    }
    this.executeUpdate = function executeUpdate(sql) {
    if (sql == null || sql == "") {
    return;
    }
    var recAffected = -1;
    try {
    var cmd = NOF_DB_CONN.CreateCommand();
    cmd.CommandText = sql;
    cmd.ExecuteNonQuery();
    }
    catch (e) {
    var errMsg = e.message;
    if (sql.match("''")) {//retry w/ a different quoting
    sql = sql.replace("''", "'");
    try {
    var cmd = NOF_DB_CONN.CreateCommand();
    cmd.CommandText = sql;
    cmd.ExecuteNonQuery();
    }
    catch (se){
    errMsg += se.message;
    }
    Response.Write(errMsg);
    } else {
    Response.Write(errMsg);
    }
    }
    return recAffected;
    }
    this.executeInsert = function executeInsert(sql) {
    return this.executeUpdate(sql);
    }
    this.getErrors = function getErrors() {
    return new Array();//NOF_DB_CONN.Errors;
    }
    this.displayErrors = function displayErrors() {
    var errs = this.getErrors();
    for (var i=0; i<errs.Count; i++){
    var error = errs.Item(i);
    Response.Write("<p>")
    Response.Write("Description: ")
    Response.Write(error.Description + "<br />")
    Response.Write("Help context: ")
    Response.Write(error.HelpContext + "<br />")
    Response.Write("Help file: ")
    Response.Write(error.HelpFile + "<br />")
    Response.Write("Native error: ")
    Response.Write(error.NativeError + "<br />")
    Response.Write("Error number: ")
    Response.Write(error.Number + "<br />")
    Response.Write("Error source: ")
    Response.Write(error.Source + "<br />")
    Response.Write("SQL state: ")
    Response.Write(error.SQLState + "<br />")
    Response.Write("</p>")
    }
    }
    }
    function NOF_IsEmpty(varRef) {
    if (typeof varRef == 'undefined' || varRef == "") {
    return true;
    } else {
    return false;
    }
    }
    function NOF_IsDefined(varName) {
    return true;
    }
    function NOF_PrepareSQLParameter(value, isNumeric) {
    if (!isNumeric) {
    if (value != null) {
    var re = /'/gi;
    value = value.replace(re, "''");
    value = "'" + value +"'";
    }
    }
    return value;
    }
    %>


  • Super User

    Ok non fa altri controlli. Devi farli tu, quindi se sai che uel valore deve essere un intero fai la conversione in intero e poi usi nella select il valore ocnvertito.


  • User

    l'unico intero che passa è il valore dell'ID. Da quello che ne capisco (poco) mi sembra che l'ID venga già controllato dalla funzione NOF_PrepareSQLParameter. Nel caso che non è così potresti suggerirmi come convertire un valore in intero e come faccio a passarlo poi nella query string? Lo so che ti chiedo troppo ma anche un piccolo esempio potrebbe aiutarmi, ancora grazie


  • Super User

    Ciao, non fa il controllo che ciò che viene passato sia intero, va fatto dopo o prima. In ogni caso, non uso VB, ma solo c#, in questo caso non posso aiutarti. Comunque, mi pare che c'è una funzione IsNumeric che faccia questo controllo, se è false fai il redirect all'home o restituisci un errore.


  • User

    proverò a guardare su altri siti, comunque veramente grazie, adesso so cosa fare, il come lo troverò. Ciao