SlideShare une entreprise Scribd logo
1  sur  39
Trouvez la faille!
                            Antonio Fontes / Confoo 2012 - Montréal

Notice 1: cette présentation contient des références à Common Weakness Enumeration:
http://cwe.mitre.org/data/index.html
Notice 2: aucun chat n'a été maltraité durant la préparation de cette séance.
Notice 3: cette présentation contient des références au
document "Test your Security IQ", par M. Howard et B. Sullivan
Notice 4: Un grand merci à Sébastien pour ses idées & propositions!
• Règles de jeu:
   – Lire l’exemple de code affiché à l'écran
   – Trouver la ou les éléments pouvant constituer un risque pour la sécurité du S.I.
   – Tenir une comptabilité analytique des points obtenus!
   02.03.2012                Confoo Conference 2012 - Antonio Fontes            2
Antonio Fontes
      Genève (Suisse)
      Consultant indépendant Infosécurité logicielle:
            Sécurité des applications web
            Visibilité et gestion du risque sur Internet
            Formation / accompagnement durant les projets de développement
      Bulletin d'information"cybermenaces et sécurité Internet":
            http://cddb.ch
      OWASP:
            Membre du Comité - OWASP Suisse
            Leader - OWASP Genève



A propos du conférencier…



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes        3
• Le site d’actualité permet la création de comptes personnels, la
  publication de réactions à l’actualité, l’échange de messages entre
  membres.
• 1 point
   02.03.2012            Confoo Conference 2012 - Antonio Fontes    4
Envoi des éléments
                                                 d'authentification en
                                                 clair.




• Le site d’actualité permet la création de comptes personnels, la
  publication de réactions à l’actualité, l’échange de messages entre
  membres.
• 1 point
   02.03.2012            Confoo Conference 2012 - Antonio Fontes         5
• Idem.



   02.03.2012   Confoo Conference 2012 - Antonio Fontes   6
function printFile($username,$filename){
          //read file into string
          $file = file_get_contents($filename);

             if ($file && isOwnerOf($username,$filename)){
               echo $file;
               return true;
             } else {
               echo 'You are not authorized to view this file';
             }
             return false;
         }

• 1 point



   02.03.2012                  Confoo Conference 2012 - Antonio Fontes   7
function printFile($username,$filename){
          //read file into string
          $file = file_get_contents($filename);
                                         Le chargement du
             if ($file && isOwnerOf($username,$filename)){
                                         fichier a lieu avant
               echo $file;
                                         le contrôle d'accès.
               return true;
             } else {
               echo 'You are not authorized to view this file';
             }
             return false;
         }


• 1 point
   – Identification du risque pour la disponibilité du S.I.


   02.03.2012                 Confoo Conference 2012 - Antonio Fontes   8
protected void Page_Load(object sender, EventArgs e)
         {
           string lastLogin = Request["LastLogin"];
           if (String.IsNullOrEmpty(lastLogin)) {
             HttpCookie lastLoginCookie = new HttpCookie("LastLogin",
              DateTime.Now.ToShortDateString());
             lastLoginCookie.Expires = DateTime.Now.AddYears(1);
             Response.Cookies.Add(lastLoginCookie);
           }
           else {
             Response.Write("Welcome back! You last logged in on " +
         lastLogin);
             Response.Cookies["LastLogin"].Value =
              DateTime.Now.ToShortDateString();
           }
         }

• 1 point



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes   9
protected void Page_Load(object sender, EventArgs e)
         {
           string lastLogin = Request["LastLogin"];
           if (String.IsNullOrEmpty(lastLogin)) { Appel vers la
             HttpCookie lastLoginCookie = new HttpCookie("LastLogin",
                                                    collection parente
              DateTime.Now.ToShortDateString());
                                                    "Request"
             lastLoginCookie.Expires = DateTime.Now.AddYears(1);
             Response.Cookies.Add(lastLoginCookie);
           }
           else {
             Response.Write("Welcome back! You last logged in on " +
         lastLogin);
             Response.Cookies["LastLogin"].Value Transfert du contenu
                                                  =
              DateTime.Now.ToShortDateString(); vers le client, sans
           }                                      encodage approprié.
         }

• 1 point
   – Cas de type "XSS" (Cross-site scripting)


   02.03.2012                Confoo Conference 2012 - Antonio Fontes     10
$role = $_COOKIES['role'];
  if (!$role) {
    $role = getRole('user');
    if ($role) {
      // save the cookie to send out in future responses
      setcookie("role", $role, time()+60*60*2);
    } else {
      ShowLoginScreen();
      die("n");
    }
  }
  if ($role == 'Reader') {
    DisplayMedicalHistory($_POST['patient_ID']);
  } else {
    die("You are not Authorized to view this recordn");
  }

• 1 point



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes   11
$role = $_COOKIES['role'];
  if (!$role) {                       Absence de contrôle
    $role = getRole('user');          d'intégrité du
    if ($role) {
                                      cookie.
      // save the cookie to send out in future responses
      setcookie("role", $role, time()+60*60*2);
    } else {
                                                      Contournement du
      ShowLoginScreen();                              mécanisme
      die("n");                                      d'authentification
    }
  }
  if ($role == 'Reader') {                             Contournement du
    DisplayMedicalHistory($_POST['patient_ID']);       contrôle d'accès
  } else {
    die("You are not Authorized to view this recordn");
  }

• 1 point



   02.03.2012             Confoo Conference 2012 - Antonio Fontes     12
• 1 + 1 point



   02.03.2012   Confoo Conference 2012 - Antonio Fontes   13
Transfert de
                                                                 confiance à un
                                                                 tiers




• 1 + 1 + 1 points
   – 1 point: identification du risque d'injection de contenu par un tiers
   – 1 point: identification du risque sur la confidentialité (fuite des referrers)
   – 1 point: identification du risque de déni de service sur le tiers
   02.03.2012                  Confoo Conference 2012 - Antonio Fontes                14
• 1 + 1 + 1 points
   – Faire attention aux recommandations sur le web: elles vont souvent à
     l'encontre de la sécurité et visent à faciliter la collecte de données par des tiers.
   – Vérifier qui est l'auteur d'une recommandation de codage.
   02.03.2012                  Confoo Conference 2012 - Antonio Fontes             15
// API flag, output JSON if set
  $json = $_GET['json'];
  $username = $_GET['user'];
  if($json)
  {
    $record = getUserRecord($username);
    echo(json_encode($record));
  } else {

   $record = getUserRecord($username);
   foreach($record as $fieldName => $fieldValue) {
     // never disclose user email addresses to the public (privacy req.)
     if(!($fieldName == "email_address"))
       renderToHtmlTable ($fieldName,$fieldValue);
     }}}


• 1 point



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes      16
// API flag, output JSON if set
  $json = $_GET['json'];                          Dans le cas json,
  $username = $_GET['user'];
                                                  l'adresse email n'est
  if($json)
  {                                               plus protégée contre les
    $record = getUserRecord($username);           fuites.
    echo(json_encode($record));
  } else {

   $record = getUserRecord($username);
   foreach($record as $fieldName => $fieldValue) {
     // never disclose user email addresses to the public (privacy req.)
     if(!($fieldName == "email_address"))
       renderToHtmlTable ($fieldName,$fieldValue);
     }}}


• 1 point
   – Identification de la fuite d'adresses email


   02.03.2012                 Confoo Conference 2012 - Antonio Fontes      17
byte[] GetKey(UInt32 keySize)
         {
           byte[] key = null;
           try
           {
             key = new byte[keySize];
             RNGCryptoServiceProvider.Create().GetBytes(key);
           }
           catch (Exception e)
           {
             Math.Random r = new Math.Random();
             r.NextBytes(key);
           }
           return key;
         }

1 + 1 + 1 point



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes   18
byte[] GetKey(UInt32 keySize)
         {
           byte[] key = null;
           try
           {
             key = new byte[keySize];
             RNGCryptoServiceProvider.Create().GetBytes(key);
           }
           catch (Exception e)
           {                      Exception générique?
             Math.Random r = new Math.Random();
             r.NextBytes(key);
           }                                  Math.Random?
                              Fail-safe?
           return key;
         }

1 + 1 + 1 point
   – Exception générique: privilégier l'exception typée
   – Principe de conception "Fail-safe": le code n'échoue pas en haute sécurité
   – La classe Math.Random ne fournit pas d'entropie de niveau cryptographique
   02.03.2012               Confoo Conference 2012 - Antonio Fontes         19
private decimal? lookupPrice(XmlDocument doc)
 {
     string query = @"//products/product[id/text()='" + Request["itemId"] +
 "']/price"
      XmlNode node = doc.SelectSingleNode(query);
      if (node == null)
         return null;
      else
         return(Convert.ToDecimal(node.InnerText));
 }



• 1 point



   02.03.2012                Confoo Conference 2012 - Antonio Fontes          20
private decimal? lookupPrice(XmlDocument doc)
 {
     string query = @"//products/product[id/text()='" + Request["itemId"] +
 "']/price"
      XmlNode node = doc.SelectSingleNode(query); Validation?
      if (node == null)
         return null;
      else
         return(Convert.ToDecimal(node.InnerText));
 }



• 1 point
   – Injection de type Xpath (il n'y a pas que des injections SQL!!)
   – Marche aussi sur: commandes système, LDAP, APIs ORM, etc.

   02.03.2012                Confoo Conference 2012 - Antonio Fontes          21
public class MySessionIDManager : System.Web.Session State.SessionIDManager
 {
   private static object lockObject = new object();

   public override string CreateSessionID(HttpContext context)
   {
     lock (lockObject)
     {
       Int32? lastSessionId = (int?)context.Application ["LastSessionId"];
       if (lastSessionId == null)
          lastSessionId = 1;
       else
          lastSessionId++;
       context.Application["LastSessionId"] = lastSessionId;
       return lastSessionId.ToString();
     }}}
• 1 + 1 point



   02.03.2012                 Confoo Conference 2012 - Antonio Fontes        22
public class MySessionIDManager : System.Web.Session State.SessionIDManager
 {
   private static object lockObject = new object();

   public override string CreateSessionID(HttpContext context)
   {
     lock (lockObject)       Multi-serveur?
     {
       Int32? lastSessionId = (int?)context.Application ["LastSessionId"];
       if (lastSessionId == null)
          lastSessionId = 1;          ID de session prédictibles
       else
          lastSessionId++;
       context.Application["LastSessionId"] = lastSessionId;
       return lastSessionId.ToString();
     }}}
• 1 + 1 point
   – Identification de l'identifiant de session prédictible
   – Collision des identifiants de session si le serveur est répliqué!

   02.03.2012                 Confoo Conference 2012 - Antonio Fontes        23
bool login(SqlConnection connection, out string errorMessage)
 {
   string uname = Request.Form["username"];
   string pword = Request.Form["password"];
   SqlCommand selectUserAndPassword = new SqlCommand( "SELECT pwd FROM Users WHERE uname =
 @username", connection);
   selectUserAndPassword.Parameters.Add( new SqlParameter("@username", uname));

      string validPassword = (string)selectUserAndPassword.ExecuteScalar();
      if (validPassword == null)
      {
          // the user doesn't exist in the database
         errorMessage = "The username is invalid.";
         return false;
      }
      else if (validPassword != pword)
      {
          // the given password doesn't match
         errorMessage = "The password is incorrect.";
         return false;
     }
     else
     {
          // success
Bug #9   errorMessage = String.Empty;
         return true;
      }
 }                                                                            1 + 1 + 1 points
       – 1 point + bonus point
       02.03.2012                           Confoo Conference 2012 - Antonio Fontes              24
bool login(SqlConnection connection, out string errorMessage)
 {                                  Requête paramétrée, ça, c'est juste!
   string uname = Request.Form["username"];
   string pword = Request.Form["password"];
   SqlCommand selectUserAndPassword = new SqlCommand( "SELECT pwd FROM Users WHERE uname =
 @username", connection);
   selectUserAndPassword.Parameters.Add( new SqlParameter("@username", uname));

      string validPassword = (string)selectUserAndPassword.ExecuteScalar();
      if (validPassword == null)
      {
          // the user doesn't exist in the database    Rapatriement inutile du
         errorMessage = "The username is invalid.";
         return false;
                                                       mot de passe!
      }
      else if (validPassword != pword)
      {                                        Stockage du mot de passe en
          // the given password doesn't match
                                               clair.
         errorMessage = "The password is incorrect.";
         return false;
     }
     else                         Message d'erreur variable lorsque le
     {
          // success
                                  login ou le mdp est faux (fuite)
Bug #9   errorMessage = String.Empty;
         return true;
      }
 }                                                                            1 + 1 + 1 points
       – 1 point + bonus point
       02.03.2012                           Confoo Conference 2012 - Antonio Fontes              25
// SilverLight code module review
bool verifyCode(string discountCode)
{
   // We store the hash of the secret code instead of the plaintext of the secret code for security.
   // We hash the incoming value and compare it against the stored hash.
   byte[] codeHash = SecurityUtils.ComputeHash(discountCode, "MD5");
   byte[] secretCode = new byte[] { 116, 46, 130, 122, 36, 234, 158, 125, 163, 122, 157, 186, 64, 142, 51,
                        153, 113, 79, 1, 42 };

    // This should never happen, but we check it anyway
    if (codeHash.Length != secretCode.Length)
        return false;

    // perform an element-by-element comparison of the arrays
    for (int i = 0; i < codeHash.Length; i++)
    {
       if (codeHash[i] != secretCode[i])
          return false; // the hashes don't match
    } // all the elements match, so the strings match

    // the discount code is valid, inform the server
    WebServiceSoapClient client = new WebServiceSoapClient();
    client.ApplyDiscountCode();
    return true;                                                               1 + 1 + 2 points
}

     02.03.2012                      Confoo Conference 2012 - Antonio Fontes                         26
// SilverLight code module review
bool verifyCode(string discountCode)      Algorithme déconseillé (+1)
{
   // We store the hash of the secret code instead of the plaintext of the secret code for security.
   // We hash the incoming value and compare it against the stored hash.
   byte[] codeHash = SecurityUtils.ComputeHash(discountCode, "MD5");
   byte[] secretCode = new byte[] { 116, 46, 130, 122, 36, 234, 158, 125, 163, 122, 157, 186, 64, 142, 51,
                        153, 113, 79, 1, 42 };

    // This should never happen, but we check it anyway
                                                               A-t-on besoin d'un
    if (codeHash.Length != secretCode.Length)                  sel? (seed) +1
        return false;

    // perform an element-by-element comparison of the arrays
    for (int i = 0; i < codeHash.Length; i++)
    {
       if (codeHash[i] != secretCode[i])              Défense côté client                          
          return false; // the hashes don't match
    } // all the elements match, so the strings match totalement inutile!                          (+2
                                                             points)
    // the discount code is accepted, inform the server
    WebServiceSoapClient client = new WebServiceSoapClient();
    client.ApplyDiscountCode();
    return true;                                                               1 + 1 + 2 points
}

     02.03.2012                      Confoo Conference 2012 - Antonio Fontes                         27
• 1 point
   02.03.2012   Confoo Conference 2012 - Antonio Fontes   28
Injection SQL
                                 (absence de
                                 validation)




• 1 point
   02.03.2012   Confoo Conference 2012 - Antonio Fontes   29
$MessageFile = "messages/messages.out";

 if ($_GET["action"] == "NewMessage") {
    $name = $_GET["name"];
    $message = $_GET["message"];
    $handle = fopen($MessageFile, "a+");
    fwrite($handle, "<b>$name</b> says '$message'<hr>n");
    fclose($handle);
    echo "Message Saved!<p>n";
 } else if ($_GET["action"] == "ViewMessages") {
    include($MessageFile);
 }


• 1 + 1 point



   02.03.2012           Confoo Conference 2012 - Antonio Fontes   30
$MessageFile = "messages/messages.out";

 if ($_GET["action"] == "NewMessage") {
    $name = $_GET["name"];
    $message = $_GET["message"];
    $handle = fopen($MessageFile, "a+");
    fwrite($handle, "<b>$name</b> says '$message'<hr>n");
                                Et s'il y a du script
    fclose($handle);
                                client?
    echo "Message Saved!<p>n";
 } else if ($_GET["action"] == "ViewMessages") {
    include($MessageFile);     include == eval()
 }                             ?


• 1 + 1 point
   – Identification de l'injection de code côté-serveur (via la fonction "include")
   – Identification de l'injection de code côté-client (via l'affichage du fichier)

   02.03.2012                 Confoo Conference 2012 - Antonio Fontes             31
// anti SQL-injection filter for user input
      string SQliProtect(string formValue)
      {
        string tmp = formValue.ToUpperCase();

      return(tmp.Replace("SELECT", "").Replace("INSERT
      ", "").Replace("UPDATE", "").Replace("UNION","")
      .Replace("BENCHMARK, "").Replace("--
      ", "").Replace("OR
      1=1", "").Replace("DROP", "").Replace("@@version
      ", "").Replace("WAITFOR", "").Replace("OUTFILE",
       "")
      ...
        return(tmp)
      }
• 1 point



   02.03.2012         Confoo Conference 2012 - Antonio Fontes   32
// anti SQL-injection filter for user input
      string SQliProtect(string formValue)
      {
        string tmp = formValue.ToUpperCase();

      return(tmp.Replace("SELECT", table" ?
                        "DRDROPOP "").Replace("INSERT
      ", "").Replace("UPDATE", "").Replace("UNION","")
      .Replace("BENCHMARK, "").Replace("--
      ", "").Replace("OR
      1=1", "").Replace("DROP", "").Replace("@@version
      ", "").Replace("WAITFOR", "").Replace("OUTFILE",
       "")
      ...
        return(tmp)
      }
• 1 point
   – Identification de la technique de contournement du filtre


   02.03.2012                Confoo Conference 2012 - Antonio Fontes   33
<?
      $reqId = 0;
      if(isset($_GET[“account_id"]))
        $reqId = (int)(htmlentities($_GET[“account_id"]));

      if($reqId == 0)
      {
        // no account selected, show the list of authorized accounts
        $sql = " SELECT * FROM accounts a "
         ." INNER JOIN account_managers am "
         ." ON a.id = am.account_id "
         ." WHERE am.manager_id = ".$currentUserID;
        echo(RenderHTMLTable($sql));
      } else {
        // docucment is clicked -> show statement
        $sql = " SELECT * FROM accounts a WHERE a.id = ".$reqId;
        RenderHTMLAccount($sql);
      }
• 2 points



   02.03.2012            Confoo Conference 2012 - Antonio Fontes   34
<?
      $reqId = 0;
      if(isset($_GET[“account_id"]))
        $reqId = (int)(htmlentities($_GET[“account_id"]));

      if($reqId == 0)
                                  Références internes?
      {
        // no account selected, show the list of authorized accounts
        $sql = " SELECT * FROM accounts a "
                                          Contrôle d’accès. Bien!
         ." INNER JOIN account_managers am "
         ." ON a.id = am.account_id "
         ." WHERE am.manager_id = ".$currentUserID;
        echo(RenderHTMLTable($sql));
      } else {
        // docucment is clicked -> show statement
        $sql = " SELECT * FROM accounts a WHERE a.id = ".$reqId;
        RenderHTMLAccount($sql);
      }                                 Mais ici?
• 2 points
   – Identification de l'exposition de références internes
   – Identification de l'absence de contrôle d'accès lors de l'affichage du document

   02.03.2012                Confoo Conference 2012 - Antonio Fontes           35
bool verifyPassword(string formPwd, int userId)
       {
         byte[] formHash = Tools.ComputeSHA1Hash(formPwd);
         byte[] dbHash = B64.Decode(User.GetPasswordHash(userId));

           if (formHash.Length != dbHash.Length)
                 return false;

           for (int i = 0; i < formHash.Length; i++)
           {
             if (formHash[i] != dbHash[i])
               return false; // the hashes don't match
           }
           // we are still here, so the passwords matched
           return true;
       }



• 1+1+1+1+1 points



   02.03.2012               Confoo Conference 2012 - Antonio Fontes   36
bool verifyPassword(string formPwd, int userId)
  {                                                 Sel?
    byte[] formHash = Tools.ComputeSHA1Hash(formPwd);
    byte[] dbHash = B64.Decode(User.GetPasswordHash(userId));
Rappatriement du mode
de passe?
     if (formHash.Length != dbHash.Length)             Algorithme fort?
             return false;

      for (int i = 0; i < formHash.Length; i++)
      {
        if (formHash[i] != dbHash[i])    Longueurs variables
          return false; // the hashes don't match
                                         possibles?
      }
      // we are still here, so the passwords matched
      return true;
  }
                      Stratégie Fail safe?

– Absence probable de sel +1
– S'interroger sur la nature de l'algorithme choisi +1
– Rapatriement inutile du mot de passe +1
– Identification de l'absence de mécanisme fail-safe +1
– Présence de signes indiquant une méconnaissance des fonctions de hachage +1
02.03.2012                    Confoo Conference 2012 - Antonio Fontes           37
Quel a été votre score?

                20 points et plus: changez de carrière, ça embauche!

                De 13 à 19 points: Très bien! Vous vous y intéressez et ça
                se voit. Vous devriez songer à appliquer vos
                connaissances aussi au code de vos collègues si ce n'est
                déjà fait, pensez aussi à joindre une association ou
                communauté traitant du sujet. Sensibilisez les gens
                autour de vous!

                De 8 à 12 points: Vous avez clairement identifié la notion
                de risque dans le code mais vous ne savez probablement
                pas encore où regarder. Il faut à présent consolider les
                bases simplement en…pratiquant!

                De 4 à 7 points: Demandez à vos chefs de vous faire
                suivre un cours! 

                Moins de 4 points: Si vous êtes développeur(ou
                développeuse), votre code est probablement dangereux
                pour la survie de l'organisation. Assurez-vous qu'il soit
                relu par une personne expérimentée dans l'attente
                d'avoir un peu plus d'expérience!
02.03.2012   Confoo Conference 2012 - Antonio Fontes                   38
Common Weakness Enumeration database:
  http://cwe.mitre.org/data/index.html


  OWASP Secure Coding Checklist:
  https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_-
  _Quick_Reference_Guide


  OWASP ASVS:
  https://www.owasp.org/index.php/Category:OWASP_Application_Security_Ve
  rification_Standard_Project



Merci de votre attention!
Si vous souhaitez me contacter:
    – antonio.fontes@L7securite.ch ou @starbuck3000
    – Newsletter: http://cddb.ch
    02.03.2012                Confoo Conference 2012 - Antonio Fontes      39

Contenu connexe

Tendances

Développement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkDéveloppement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkMickael Perraud
 
Code Demo NFC on Android - Olivier Gonthier - PAUG
Code Demo NFC on Android - Olivier Gonthier - PAUGCode Demo NFC on Android - Olivier Gonthier - PAUG
Code Demo NFC on Android - Olivier Gonthier - PAUGParis Android User Group
 
PHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesPHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesJean Michel
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Kristen Le Liboux
 
PKI Android : Installer, gérer, sécuriser et utiliser un secret
PKI Android : Installer, gérer, sécuriser et utiliser un secretPKI Android : Installer, gérer, sécuriser et utiliser un secret
PKI Android : Installer, gérer, sécuriser et utiliser un secretOCTO Technology
 
Présentation de DBAL en PHP (Nantes)
Présentation de DBAL en PHP (Nantes)Présentation de DBAL en PHP (Nantes)
Présentation de DBAL en PHP (Nantes)Mickael Perraud
 
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...Emeric Kamleu Noumi
 
Présentation de DBAL en PHP
Présentation de DBAL en PHPPrésentation de DBAL en PHP
Présentation de DBAL en PHPMickael Perraud
 

Tendances (9)

Développement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkDéveloppement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend Framework
 
Code Demo NFC on Android - Olivier Gonthier - PAUG
Code Demo NFC on Android - Olivier Gonthier - PAUGCode Demo NFC on Android - Olivier Gonthier - PAUG
Code Demo NFC on Android - Olivier Gonthier - PAUG
 
PHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesPHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulaires
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5
 
PKI Android : Installer, gérer, sécuriser et utiliser un secret
PKI Android : Installer, gérer, sécuriser et utiliser un secretPKI Android : Installer, gérer, sécuriser et utiliser un secret
PKI Android : Installer, gérer, sécuriser et utiliser un secret
 
Python avancé : Qualité de code et convention de codage
Python avancé : Qualité de code et convention de codagePython avancé : Qualité de code et convention de codage
Python avancé : Qualité de code et convention de codage
 
Présentation de DBAL en PHP (Nantes)
Présentation de DBAL en PHP (Nantes)Présentation de DBAL en PHP (Nantes)
Présentation de DBAL en PHP (Nantes)
 
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...
Annexes du Document sur l'Auto provisioning, contacts, presence et streaming ...
 
Présentation de DBAL en PHP
Présentation de DBAL en PHPPrésentation de DBAL en PHP
Présentation de DBAL en PHP
 

En vedette

Acumar en Movimiento Número 4
Acumar en Movimiento Número 4Acumar en Movimiento Número 4
Acumar en Movimiento Número 4LaAcumar
 
How to increase e mail newsletter subscribers by 200% 2
How to increase e mail newsletter subscribers by 200% 2How to increase e mail newsletter subscribers by 200% 2
How to increase e mail newsletter subscribers by 200% 2razorsocial
 
G 1 sns-new era of cnt sensing technology
G 1  sns-new era of cnt sensing technologyG 1  sns-new era of cnt sensing technology
G 1 sns-new era of cnt sensing technologyChung Da-woon
 
Hay vida en las tic’s
Hay vida en las tic’sHay vida en las tic’s
Hay vida en las tic’sayuntamiento
 
HECTOR ROMERO ALVA
HECTOR ROMERO ALVA HECTOR ROMERO ALVA
HECTOR ROMERO ALVA carmen1558
 
Karuselli 50years_Booklet-N
Karuselli 50years_Booklet-NKaruselli 50years_Booklet-N
Karuselli 50years_Booklet-NTamin Tanzil
 
Reading Group Presentation: Web Attacks on Host-Proof Encrypted Storage
Reading Group Presentation: Web Attacks on Host-Proof Encrypted StorageReading Group Presentation: Web Attacks on Host-Proof Encrypted Storage
Reading Group Presentation: Web Attacks on Host-Proof Encrypted StorageMichael Rushanan
 
Brochure comercial del Máster en Dirección de Marketing Digital
Brochure comercial del Máster en Dirección de Marketing DigitalBrochure comercial del Máster en Dirección de Marketing Digital
Brochure comercial del Máster en Dirección de Marketing DigitalJesús Crespo Fernández
 
Boletin FIESTA II enero 2016
Boletin FIESTA II enero 2016Boletin FIESTA II enero 2016
Boletin FIESTA II enero 2016Fiesta II
 
Pedang roh edisi_57
Pedang roh edisi_57Pedang roh edisi_57
Pedang roh edisi_57alkitabiah
 
Pyme Innova. Coaching ejecutivo.
Pyme Innova. Coaching ejecutivo. Pyme Innova. Coaching ejecutivo.
Pyme Innova. Coaching ejecutivo. Imadeinnova
 
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...Michael Brandvold
 
Ptt electronica 1
Ptt electronica 1Ptt electronica 1
Ptt electronica 1FRM FRM
 
Ernst cassirer
Ernst cassirerErnst cassirer
Ernst cassirermaribrondo
 
2016 Brandentrepreneurs Business Boot Camps Speakers
2016 Brandentrepreneurs Business Boot Camps Speakers2016 Brandentrepreneurs Business Boot Camps Speakers
2016 Brandentrepreneurs Business Boot Camps SpeakersChristine Souffrant Ntim
 

En vedette (20)

Acumar en Movimiento Número 4
Acumar en Movimiento Número 4Acumar en Movimiento Número 4
Acumar en Movimiento Número 4
 
How to increase e mail newsletter subscribers by 200% 2
How to increase e mail newsletter subscribers by 200% 2How to increase e mail newsletter subscribers by 200% 2
How to increase e mail newsletter subscribers by 200% 2
 
Cris de lara
Cris de laraCris de lara
Cris de lara
 
G 1 sns-new era of cnt sensing technology
G 1  sns-new era of cnt sensing technologyG 1  sns-new era of cnt sensing technology
G 1 sns-new era of cnt sensing technology
 
Hay vida en las tic’s
Hay vida en las tic’sHay vida en las tic’s
Hay vida en las tic’s
 
HECTOR ROMERO ALVA
HECTOR ROMERO ALVA HECTOR ROMERO ALVA
HECTOR ROMERO ALVA
 
Karuselli 50years_Booklet-N
Karuselli 50years_Booklet-NKaruselli 50years_Booklet-N
Karuselli 50years_Booklet-N
 
Reading Group Presentation: Web Attacks on Host-Proof Encrypted Storage
Reading Group Presentation: Web Attacks on Host-Proof Encrypted StorageReading Group Presentation: Web Attacks on Host-Proof Encrypted Storage
Reading Group Presentation: Web Attacks on Host-Proof Encrypted Storage
 
Brochure comercial del Máster en Dirección de Marketing Digital
Brochure comercial del Máster en Dirección de Marketing DigitalBrochure comercial del Máster en Dirección de Marketing Digital
Brochure comercial del Máster en Dirección de Marketing Digital
 
targeta madre de una pc
targeta madre de una pctargeta madre de una pc
targeta madre de una pc
 
Boletin FIESTA II enero 2016
Boletin FIESTA II enero 2016Boletin FIESTA II enero 2016
Boletin FIESTA II enero 2016
 
Pedang roh edisi_57
Pedang roh edisi_57Pedang roh edisi_57
Pedang roh edisi_57
 
Pyme Innova. Coaching ejecutivo.
Pyme Innova. Coaching ejecutivo. Pyme Innova. Coaching ejecutivo.
Pyme Innova. Coaching ejecutivo.
 
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...
Rock Stars & Porn Stars, Effective Social Networking and Fan Engagement Techn...
 
Ptt electronica 1
Ptt electronica 1Ptt electronica 1
Ptt electronica 1
 
Ernst cassirer
Ernst cassirerErnst cassirer
Ernst cassirer
 
Curso de truficultura
Curso de truficulturaCurso de truficultura
Curso de truficultura
 
2016 Brandentrepreneurs Business Boot Camps Speakers
2016 Brandentrepreneurs Business Boot Camps Speakers2016 Brandentrepreneurs Business Boot Camps Speakers
2016 Brandentrepreneurs Business Boot Camps Speakers
 
Gestion conflictos en educación
Gestion conflictos en educaciónGestion conflictos en educación
Gestion conflictos en educación
 
Res judicata
Res judicataRes judicata
Res judicata
 

Plus de Antonio Fontes

Sécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseSécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseAntonio Fontes
 
Owasp ottawa training-day_2012-secure_design-final
Owasp ottawa training-day_2012-secure_design-finalOwasp ottawa training-day_2012-secure_design-final
Owasp ottawa training-day_2012-secure_design-finalAntonio Fontes
 
Securing your web apps before they hurt the organization
Securing your web apps before they hurt the organizationSecuring your web apps before they hurt the organization
Securing your web apps before they hurt the organizationAntonio Fontes
 
Modéliser les menaces d'une application web
Modéliser les menaces d'une application webModéliser les menaces d'une application web
Modéliser les menaces d'une application webAntonio Fontes
 
Confoo 2012 - Web security keynote
Confoo 2012 - Web security keynoteConfoo 2012 - Web security keynote
Confoo 2012 - Web security keynoteAntonio Fontes
 
Threat Modeling web applications (2012 update)
Threat Modeling web applications (2012 update)Threat Modeling web applications (2012 update)
Threat Modeling web applications (2012 update)Antonio Fontes
 
Rapid Threat Modeling : case study
Rapid Threat Modeling : case studyRapid Threat Modeling : case study
Rapid Threat Modeling : case studyAntonio Fontes
 
Sécurité dans les contrats d'externalisation de services de développement et ...
Sécurité dans les contrats d'externalisation de services de développement et ...Sécurité dans les contrats d'externalisation de services de développement et ...
Sécurité dans les contrats d'externalisation de services de développement et ...Antonio Fontes
 
IT Security Days - Threat Modeling
IT Security Days - Threat ModelingIT Security Days - Threat Modeling
IT Security Days - Threat ModelingAntonio Fontes
 
Threat modeling web application: a case study
Threat modeling web application: a case studyThreat modeling web application: a case study
Threat modeling web application: a case studyAntonio Fontes
 
The top 10 web application intrusion techniques
The top 10 web application intrusion techniquesThe top 10 web application intrusion techniques
The top 10 web application intrusion techniquesAntonio Fontes
 
Cyber-attaques: mise au point
Cyber-attaques: mise au pointCyber-attaques: mise au point
Cyber-attaques: mise au pointAntonio Fontes
 
Web application security: how to start?
Web application security: how to start?Web application security: how to start?
Web application security: how to start?Antonio Fontes
 

Plus de Antonio Fontes (15)

Sécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseSécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défense
 
Owasp ottawa training-day_2012-secure_design-final
Owasp ottawa training-day_2012-secure_design-finalOwasp ottawa training-day_2012-secure_design-final
Owasp ottawa training-day_2012-secure_design-final
 
Securing your web apps before they hurt the organization
Securing your web apps before they hurt the organizationSecuring your web apps before they hurt the organization
Securing your web apps before they hurt the organization
 
Modéliser les menaces d'une application web
Modéliser les menaces d'une application webModéliser les menaces d'une application web
Modéliser les menaces d'une application web
 
Confoo 2012 - Web security keynote
Confoo 2012 - Web security keynoteConfoo 2012 - Web security keynote
Confoo 2012 - Web security keynote
 
Threat Modeling web applications (2012 update)
Threat Modeling web applications (2012 update)Threat Modeling web applications (2012 update)
Threat Modeling web applications (2012 update)
 
Rapid Threat Modeling : case study
Rapid Threat Modeling : case studyRapid Threat Modeling : case study
Rapid Threat Modeling : case study
 
Sécurité dans les contrats d'externalisation de services de développement et ...
Sécurité dans les contrats d'externalisation de services de développement et ...Sécurité dans les contrats d'externalisation de services de développement et ...
Sécurité dans les contrats d'externalisation de services de développement et ...
 
Meet the OWASP
Meet the OWASPMeet the OWASP
Meet the OWASP
 
IT Security Days - Threat Modeling
IT Security Days - Threat ModelingIT Security Days - Threat Modeling
IT Security Days - Threat Modeling
 
Threat modeling web application: a case study
Threat modeling web application: a case studyThreat modeling web application: a case study
Threat modeling web application: a case study
 
The top 10 web application intrusion techniques
The top 10 web application intrusion techniquesThe top 10 web application intrusion techniques
The top 10 web application intrusion techniques
 
Cyber-attaques: mise au point
Cyber-attaques: mise au pointCyber-attaques: mise au point
Cyber-attaques: mise au point
 
Web application security: how to start?
Web application security: how to start?Web application security: how to start?
Web application security: how to start?
 
Owasp Top10 2010 rc1
Owasp Top10 2010 rc1Owasp Top10 2010 rc1
Owasp Top10 2010 rc1
 

Trouvez la faille! - Confoo 2012

  • 1. Trouvez la faille! Antonio Fontes / Confoo 2012 - Montréal Notice 1: cette présentation contient des références à Common Weakness Enumeration: http://cwe.mitre.org/data/index.html Notice 2: aucun chat n'a été maltraité durant la préparation de cette séance. Notice 3: cette présentation contient des références au document "Test your Security IQ", par M. Howard et B. Sullivan Notice 4: Un grand merci à Sébastien pour ses idées & propositions!
  • 2. • Règles de jeu: – Lire l’exemple de code affiché à l'écran – Trouver la ou les éléments pouvant constituer un risque pour la sécurité du S.I. – Tenir une comptabilité analytique des points obtenus! 02.03.2012 Confoo Conference 2012 - Antonio Fontes 2
  • 3. Antonio Fontes Genève (Suisse) Consultant indépendant Infosécurité logicielle: Sécurité des applications web Visibilité et gestion du risque sur Internet Formation / accompagnement durant les projets de développement Bulletin d'information"cybermenaces et sécurité Internet": http://cddb.ch OWASP: Membre du Comité - OWASP Suisse Leader - OWASP Genève A propos du conférencier… 02.03.2012 Confoo Conference 2012 - Antonio Fontes 3
  • 4. • Le site d’actualité permet la création de comptes personnels, la publication de réactions à l’actualité, l’échange de messages entre membres. • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 4
  • 5. Envoi des éléments d'authentification en clair. • Le site d’actualité permet la création de comptes personnels, la publication de réactions à l’actualité, l’échange de messages entre membres. • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 5
  • 6. • Idem. 02.03.2012 Confoo Conference 2012 - Antonio Fontes 6
  • 7. function printFile($username,$filename){ //read file into string $file = file_get_contents($filename); if ($file && isOwnerOf($username,$filename)){ echo $file; return true; } else { echo 'You are not authorized to view this file'; } return false; } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 7
  • 8. function printFile($username,$filename){ //read file into string $file = file_get_contents($filename); Le chargement du if ($file && isOwnerOf($username,$filename)){ fichier a lieu avant echo $file; le contrôle d'accès. return true; } else { echo 'You are not authorized to view this file'; } return false; } • 1 point – Identification du risque pour la disponibilité du S.I. 02.03.2012 Confoo Conference 2012 - Antonio Fontes 8
  • 9. protected void Page_Load(object sender, EventArgs e) { string lastLogin = Request["LastLogin"]; if (String.IsNullOrEmpty(lastLogin)) { HttpCookie lastLoginCookie = new HttpCookie("LastLogin", DateTime.Now.ToShortDateString()); lastLoginCookie.Expires = DateTime.Now.AddYears(1); Response.Cookies.Add(lastLoginCookie); } else { Response.Write("Welcome back! You last logged in on " + lastLogin); Response.Cookies["LastLogin"].Value = DateTime.Now.ToShortDateString(); } } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 9
  • 10. protected void Page_Load(object sender, EventArgs e) { string lastLogin = Request["LastLogin"]; if (String.IsNullOrEmpty(lastLogin)) { Appel vers la HttpCookie lastLoginCookie = new HttpCookie("LastLogin", collection parente DateTime.Now.ToShortDateString()); "Request" lastLoginCookie.Expires = DateTime.Now.AddYears(1); Response.Cookies.Add(lastLoginCookie); } else { Response.Write("Welcome back! You last logged in on " + lastLogin); Response.Cookies["LastLogin"].Value Transfert du contenu = DateTime.Now.ToShortDateString(); vers le client, sans } encodage approprié. } • 1 point – Cas de type "XSS" (Cross-site scripting) 02.03.2012 Confoo Conference 2012 - Antonio Fontes 10
  • 11. $role = $_COOKIES['role']; if (!$role) { $role = getRole('user'); if ($role) { // save the cookie to send out in future responses setcookie("role", $role, time()+60*60*2); } else { ShowLoginScreen(); die("n"); } } if ($role == 'Reader') { DisplayMedicalHistory($_POST['patient_ID']); } else { die("You are not Authorized to view this recordn"); } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 11
  • 12. $role = $_COOKIES['role']; if (!$role) { Absence de contrôle $role = getRole('user'); d'intégrité du if ($role) { cookie. // save the cookie to send out in future responses setcookie("role", $role, time()+60*60*2); } else { Contournement du ShowLoginScreen(); mécanisme die("n"); d'authentification } } if ($role == 'Reader') { Contournement du DisplayMedicalHistory($_POST['patient_ID']); contrôle d'accès } else { die("You are not Authorized to view this recordn"); } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 12
  • 13. • 1 + 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 13
  • 14. Transfert de confiance à un tiers • 1 + 1 + 1 points – 1 point: identification du risque d'injection de contenu par un tiers – 1 point: identification du risque sur la confidentialité (fuite des referrers) – 1 point: identification du risque de déni de service sur le tiers 02.03.2012 Confoo Conference 2012 - Antonio Fontes 14
  • 15. • 1 + 1 + 1 points – Faire attention aux recommandations sur le web: elles vont souvent à l'encontre de la sécurité et visent à faciliter la collecte de données par des tiers. – Vérifier qui est l'auteur d'une recommandation de codage. 02.03.2012 Confoo Conference 2012 - Antonio Fontes 15
  • 16. // API flag, output JSON if set $json = $_GET['json']; $username = $_GET['user']; if($json) { $record = getUserRecord($username); echo(json_encode($record)); } else { $record = getUserRecord($username); foreach($record as $fieldName => $fieldValue) { // never disclose user email addresses to the public (privacy req.) if(!($fieldName == "email_address")) renderToHtmlTable ($fieldName,$fieldValue); }}} • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 16
  • 17. // API flag, output JSON if set $json = $_GET['json']; Dans le cas json, $username = $_GET['user']; l'adresse email n'est if($json) { plus protégée contre les $record = getUserRecord($username); fuites. echo(json_encode($record)); } else { $record = getUserRecord($username); foreach($record as $fieldName => $fieldValue) { // never disclose user email addresses to the public (privacy req.) if(!($fieldName == "email_address")) renderToHtmlTable ($fieldName,$fieldValue); }}} • 1 point – Identification de la fuite d'adresses email 02.03.2012 Confoo Conference 2012 - Antonio Fontes 17
  • 18. byte[] GetKey(UInt32 keySize) { byte[] key = null; try { key = new byte[keySize]; RNGCryptoServiceProvider.Create().GetBytes(key); } catch (Exception e) { Math.Random r = new Math.Random(); r.NextBytes(key); } return key; } 1 + 1 + 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 18
  • 19. byte[] GetKey(UInt32 keySize) { byte[] key = null; try { key = new byte[keySize]; RNGCryptoServiceProvider.Create().GetBytes(key); } catch (Exception e) { Exception générique? Math.Random r = new Math.Random(); r.NextBytes(key); } Math.Random? Fail-safe? return key; } 1 + 1 + 1 point – Exception générique: privilégier l'exception typée – Principe de conception "Fail-safe": le code n'échoue pas en haute sécurité – La classe Math.Random ne fournit pas d'entropie de niveau cryptographique 02.03.2012 Confoo Conference 2012 - Antonio Fontes 19
  • 20. private decimal? lookupPrice(XmlDocument doc) { string query = @"//products/product[id/text()='" + Request["itemId"] + "']/price" XmlNode node = doc.SelectSingleNode(query); if (node == null) return null; else return(Convert.ToDecimal(node.InnerText)); } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 20
  • 21. private decimal? lookupPrice(XmlDocument doc) { string query = @"//products/product[id/text()='" + Request["itemId"] + "']/price" XmlNode node = doc.SelectSingleNode(query); Validation? if (node == null) return null; else return(Convert.ToDecimal(node.InnerText)); } • 1 point – Injection de type Xpath (il n'y a pas que des injections SQL!!) – Marche aussi sur: commandes système, LDAP, APIs ORM, etc. 02.03.2012 Confoo Conference 2012 - Antonio Fontes 21
  • 22. public class MySessionIDManager : System.Web.Session State.SessionIDManager { private static object lockObject = new object(); public override string CreateSessionID(HttpContext context) { lock (lockObject) { Int32? lastSessionId = (int?)context.Application ["LastSessionId"]; if (lastSessionId == null) lastSessionId = 1; else lastSessionId++; context.Application["LastSessionId"] = lastSessionId; return lastSessionId.ToString(); }}} • 1 + 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 22
  • 23. public class MySessionIDManager : System.Web.Session State.SessionIDManager { private static object lockObject = new object(); public override string CreateSessionID(HttpContext context) { lock (lockObject) Multi-serveur? { Int32? lastSessionId = (int?)context.Application ["LastSessionId"]; if (lastSessionId == null) lastSessionId = 1; ID de session prédictibles else lastSessionId++; context.Application["LastSessionId"] = lastSessionId; return lastSessionId.ToString(); }}} • 1 + 1 point – Identification de l'identifiant de session prédictible – Collision des identifiants de session si le serveur est répliqué! 02.03.2012 Confoo Conference 2012 - Antonio Fontes 23
  • 24. bool login(SqlConnection connection, out string errorMessage) { string uname = Request.Form["username"]; string pword = Request.Form["password"]; SqlCommand selectUserAndPassword = new SqlCommand( "SELECT pwd FROM Users WHERE uname = @username", connection); selectUserAndPassword.Parameters.Add( new SqlParameter("@username", uname)); string validPassword = (string)selectUserAndPassword.ExecuteScalar(); if (validPassword == null) { // the user doesn't exist in the database errorMessage = "The username is invalid."; return false; } else if (validPassword != pword) { // the given password doesn't match errorMessage = "The password is incorrect."; return false; } else { // success Bug #9 errorMessage = String.Empty; return true; } } 1 + 1 + 1 points – 1 point + bonus point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 24
  • 25. bool login(SqlConnection connection, out string errorMessage) { Requête paramétrée, ça, c'est juste! string uname = Request.Form["username"]; string pword = Request.Form["password"]; SqlCommand selectUserAndPassword = new SqlCommand( "SELECT pwd FROM Users WHERE uname = @username", connection); selectUserAndPassword.Parameters.Add( new SqlParameter("@username", uname)); string validPassword = (string)selectUserAndPassword.ExecuteScalar(); if (validPassword == null) { // the user doesn't exist in the database Rapatriement inutile du errorMessage = "The username is invalid."; return false; mot de passe! } else if (validPassword != pword) { Stockage du mot de passe en // the given password doesn't match clair. errorMessage = "The password is incorrect."; return false; } else Message d'erreur variable lorsque le { // success login ou le mdp est faux (fuite) Bug #9 errorMessage = String.Empty; return true; } } 1 + 1 + 1 points – 1 point + bonus point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 25
  • 26. // SilverLight code module review bool verifyCode(string discountCode) { // We store the hash of the secret code instead of the plaintext of the secret code for security. // We hash the incoming value and compare it against the stored hash. byte[] codeHash = SecurityUtils.ComputeHash(discountCode, "MD5"); byte[] secretCode = new byte[] { 116, 46, 130, 122, 36, 234, 158, 125, 163, 122, 157, 186, 64, 142, 51, 153, 113, 79, 1, 42 }; // This should never happen, but we check it anyway if (codeHash.Length != secretCode.Length) return false; // perform an element-by-element comparison of the arrays for (int i = 0; i < codeHash.Length; i++) { if (codeHash[i] != secretCode[i]) return false; // the hashes don't match } // all the elements match, so the strings match // the discount code is valid, inform the server WebServiceSoapClient client = new WebServiceSoapClient(); client.ApplyDiscountCode(); return true; 1 + 1 + 2 points } 02.03.2012 Confoo Conference 2012 - Antonio Fontes 26
  • 27. // SilverLight code module review bool verifyCode(string discountCode) Algorithme déconseillé (+1) { // We store the hash of the secret code instead of the plaintext of the secret code for security. // We hash the incoming value and compare it against the stored hash. byte[] codeHash = SecurityUtils.ComputeHash(discountCode, "MD5"); byte[] secretCode = new byte[] { 116, 46, 130, 122, 36, 234, 158, 125, 163, 122, 157, 186, 64, 142, 51, 153, 113, 79, 1, 42 }; // This should never happen, but we check it anyway A-t-on besoin d'un if (codeHash.Length != secretCode.Length) sel? (seed) +1 return false; // perform an element-by-element comparison of the arrays for (int i = 0; i < codeHash.Length; i++) { if (codeHash[i] != secretCode[i]) Défense côté client  return false; // the hashes don't match } // all the elements match, so the strings match totalement inutile! (+2 points) // the discount code is accepted, inform the server WebServiceSoapClient client = new WebServiceSoapClient(); client.ApplyDiscountCode(); return true; 1 + 1 + 2 points } 02.03.2012 Confoo Conference 2012 - Antonio Fontes 27
  • 28. • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 28
  • 29. Injection SQL (absence de validation) • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 29
  • 30. $MessageFile = "messages/messages.out"; if ($_GET["action"] == "NewMessage") { $name = $_GET["name"]; $message = $_GET["message"]; $handle = fopen($MessageFile, "a+"); fwrite($handle, "<b>$name</b> says '$message'<hr>n"); fclose($handle); echo "Message Saved!<p>n"; } else if ($_GET["action"] == "ViewMessages") { include($MessageFile); } • 1 + 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 30
  • 31. $MessageFile = "messages/messages.out"; if ($_GET["action"] == "NewMessage") { $name = $_GET["name"]; $message = $_GET["message"]; $handle = fopen($MessageFile, "a+"); fwrite($handle, "<b>$name</b> says '$message'<hr>n"); Et s'il y a du script fclose($handle); client? echo "Message Saved!<p>n"; } else if ($_GET["action"] == "ViewMessages") { include($MessageFile); include == eval() } ? • 1 + 1 point – Identification de l'injection de code côté-serveur (via la fonction "include") – Identification de l'injection de code côté-client (via l'affichage du fichier) 02.03.2012 Confoo Conference 2012 - Antonio Fontes 31
  • 32. // anti SQL-injection filter for user input string SQliProtect(string formValue) { string tmp = formValue.ToUpperCase(); return(tmp.Replace("SELECT", "").Replace("INSERT ", "").Replace("UPDATE", "").Replace("UNION","") .Replace("BENCHMARK, "").Replace("-- ", "").Replace("OR 1=1", "").Replace("DROP", "").Replace("@@version ", "").Replace("WAITFOR", "").Replace("OUTFILE", "") ... return(tmp) } • 1 point 02.03.2012 Confoo Conference 2012 - Antonio Fontes 32
  • 33. // anti SQL-injection filter for user input string SQliProtect(string formValue) { string tmp = formValue.ToUpperCase(); return(tmp.Replace("SELECT", table" ? "DRDROPOP "").Replace("INSERT ", "").Replace("UPDATE", "").Replace("UNION","") .Replace("BENCHMARK, "").Replace("-- ", "").Replace("OR 1=1", "").Replace("DROP", "").Replace("@@version ", "").Replace("WAITFOR", "").Replace("OUTFILE", "") ... return(tmp) } • 1 point – Identification de la technique de contournement du filtre 02.03.2012 Confoo Conference 2012 - Antonio Fontes 33
  • 34. <? $reqId = 0; if(isset($_GET[“account_id"])) $reqId = (int)(htmlentities($_GET[“account_id"])); if($reqId == 0) { // no account selected, show the list of authorized accounts $sql = " SELECT * FROM accounts a " ." INNER JOIN account_managers am " ." ON a.id = am.account_id " ." WHERE am.manager_id = ".$currentUserID; echo(RenderHTMLTable($sql)); } else { // docucment is clicked -> show statement $sql = " SELECT * FROM accounts a WHERE a.id = ".$reqId; RenderHTMLAccount($sql); } • 2 points 02.03.2012 Confoo Conference 2012 - Antonio Fontes 34
  • 35. <? $reqId = 0; if(isset($_GET[“account_id"])) $reqId = (int)(htmlentities($_GET[“account_id"])); if($reqId == 0) Références internes? { // no account selected, show the list of authorized accounts $sql = " SELECT * FROM accounts a " Contrôle d’accès. Bien! ." INNER JOIN account_managers am " ." ON a.id = am.account_id " ." WHERE am.manager_id = ".$currentUserID; echo(RenderHTMLTable($sql)); } else { // docucment is clicked -> show statement $sql = " SELECT * FROM accounts a WHERE a.id = ".$reqId; RenderHTMLAccount($sql); } Mais ici? • 2 points – Identification de l'exposition de références internes – Identification de l'absence de contrôle d'accès lors de l'affichage du document 02.03.2012 Confoo Conference 2012 - Antonio Fontes 35
  • 36. bool verifyPassword(string formPwd, int userId) { byte[] formHash = Tools.ComputeSHA1Hash(formPwd); byte[] dbHash = B64.Decode(User.GetPasswordHash(userId)); if (formHash.Length != dbHash.Length) return false; for (int i = 0; i < formHash.Length; i++) { if (formHash[i] != dbHash[i]) return false; // the hashes don't match } // we are still here, so the passwords matched return true; } • 1+1+1+1+1 points 02.03.2012 Confoo Conference 2012 - Antonio Fontes 36
  • 37. bool verifyPassword(string formPwd, int userId) { Sel? byte[] formHash = Tools.ComputeSHA1Hash(formPwd); byte[] dbHash = B64.Decode(User.GetPasswordHash(userId)); Rappatriement du mode de passe? if (formHash.Length != dbHash.Length) Algorithme fort? return false; for (int i = 0; i < formHash.Length; i++) { if (formHash[i] != dbHash[i]) Longueurs variables return false; // the hashes don't match possibles? } // we are still here, so the passwords matched return true; } Stratégie Fail safe? – Absence probable de sel +1 – S'interroger sur la nature de l'algorithme choisi +1 – Rapatriement inutile du mot de passe +1 – Identification de l'absence de mécanisme fail-safe +1 – Présence de signes indiquant une méconnaissance des fonctions de hachage +1 02.03.2012 Confoo Conference 2012 - Antonio Fontes 37
  • 38. Quel a été votre score? 20 points et plus: changez de carrière, ça embauche! De 13 à 19 points: Très bien! Vous vous y intéressez et ça se voit. Vous devriez songer à appliquer vos connaissances aussi au code de vos collègues si ce n'est déjà fait, pensez aussi à joindre une association ou communauté traitant du sujet. Sensibilisez les gens autour de vous! De 8 à 12 points: Vous avez clairement identifié la notion de risque dans le code mais vous ne savez probablement pas encore où regarder. Il faut à présent consolider les bases simplement en…pratiquant! De 4 à 7 points: Demandez à vos chefs de vous faire suivre un cours!  Moins de 4 points: Si vous êtes développeur(ou développeuse), votre code est probablement dangereux pour la survie de l'organisation. Assurez-vous qu'il soit relu par une personne expérimentée dans l'attente d'avoir un peu plus d'expérience! 02.03.2012 Confoo Conference 2012 - Antonio Fontes 38
  • 39. Common Weakness Enumeration database: http://cwe.mitre.org/data/index.html OWASP Secure Coding Checklist: https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_- _Quick_Reference_Guide OWASP ASVS: https://www.owasp.org/index.php/Category:OWASP_Application_Security_Ve rification_Standard_Project Merci de votre attention! Si vous souhaitez me contacter: – antonio.fontes@L7securite.ch ou @starbuck3000 – Newsletter: http://cddb.ch 02.03.2012 Confoo Conference 2012 - Antonio Fontes 39

Notes de l'éditeur

  1. En cas de distribution? Identifiant prévisible
  2. En cas de distribution? Identifiant prévisible
  3. Password a été rapatrié en local
  4. Password a été rapatrié en local
  5. En cas de distribution? Identifiant prévisible
  6. En cas de distribution? Identifiant prévisible