Overblog
Suivre ce blog Administration + Créer mon blog
21 septembre 2010 2 21 /09 /septembre /2010 08:38
Une faille de sécurité importante a été découverte sur les sites en ASP.NET permettant d’accéder à pratiquement toutes les données du site ciblé (utilisateurs, mots de passes etc..)

Pour protéger vos sites de ces attaques, voici comment procéder pour les instances 3.5 SP1  et 4 :

 

  1. 1- Créez une page error.aspx contenant un message d’erreur sans explications précises et mettez la à la racine du site.
  2. 2- Editez le web config et modifiez la section CustomErrors comme suit :
    1. <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
  3. 3- Redémarrez le service IIS

 

Pour les version antérieurs du Framework, je vous conseille fortement de migrer vos sites vers la version 4.

Partager cet article
Repost0
9 juin 2010 3 09 /06 /juin /2010 09:25

Pour que les sites utilisant le Framework 4 puissent cohabiter avec des sites utilisant le Framework 2 ou 3.5 vous devez créer plusieurs pool d’application. En effet, plusieurs version du Framework ne peuvent pas tourner dans le même pool d’application.

 

Voici les étapes à suivre pour installer le Framework 4.

 

1- Installez le Framework 4 à partir du site de Microsoft puis redémarrez le serveur.

2- Dans le Gestionnaire de IIS6, allez dans le nœud “Extensions du service Web” et assurez vous que l’extension ASP.NET v4 est autorisé.

3- Faites un clique droit sur le nœud “Pools d’applications” puis, dans le menu, cliquez sur “Nouveau” puis “Pool d’application”.

4- Créez autant de pools qu’il y a de Framework utilisé sur votre serveur IIS6. Exemple : appPoolF3, appPoolF4 etc..

5- Faites un clique droit sur le nœud de votre site utilisant le Framework 4 puis dans le menu cliquez sur “Propriétés”.

6- Dans l’onglet “ASP.NET” assurez vous que c’est bien le Framework 4 qui est utilisé.

7- Dans l’onglet répertoire de base, modifier le Pool d’application utilisé pour mettre celui du Framework 4.

8- Modifiez tous les pools d’applications des autres sites du serveur pour les mettre dans le pool correspondant a la version de leur Framework.

 

Remarque : Si un seul site n’est pas dans le bon pool les autres sites ne fonctionneront pas.

Partager cet article
Repost0
10 mars 2010 3 10 /03 /mars /2010 09:26

Il est parfois nécessaire d’empêcher la saisie d’une adresse e-mail ou d’un site internet dans un texte pour des raisons de sécurité, ou tout simplement pour que l’utilisateur ne saisissent ses informations qu’aux endroits prévus à cet effet.

 

Voici 2 fonctions qui permettent de savoir si une adresse email ou un site internet a été saisie dans un texte :

 

Code :

Private Function IsWebSiteInText(ByVal txt As String) As Boolean
        Dim regx As New Regex("http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", RegexOptions.IgnoreCase)

        Dim mactches As MatchCollection = regx.Matches(txt)

        If mactches.Count > 0 Then
            Return True
        End If

        Return False

End Function

 

Private Function IsEmailInText(ByVal txt As String) As Boolean

        Dim regx As New Regex("\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",RegexOptions.IgnoreCase)

        Dim mactches As MatchCollection = regx.Matches(txt)

        If mactches.Count > 0 Then
            Return True
        End If

        Return False
End Function

Dans le cas d’un formulaire ASP.NET vous pouvez utiliser un CustomValidator pour vérifier le texte.

Partager cet article
Repost0
12 septembre 2009 6 12 /09 /septembre /2009 09:49

Le code généré par le site PayPal pour les boutons ressemble à ceci :

 

Code du bouton “Afficher le panier”. (La partie crypté a été tronqué et remplacé par … )

<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7----- … -----END PKCS7-----">
<input type="image" src="https://www.paypal.com/fr_FR/FR/i/btn/btn_viewcart_LG.gif" border="0" name="submit" alt="PayPal - la solution de paiement en ligne la plus simple et la plus sécurisée !">
<img alt="" border="0" src="https://www.paypal.com/fr_FR/i/scr/pixel.gif" width="1" height="1">
</form>

Si nous mettons ce code directement sur une page ASP.NET on a de forte chance que rien ne se passe lorsque l’on clique sur le bouton.

Pour résoudre ce problème nous allons créer une classe qui va nous permettre de générer dynamiquement le form que nous allons envoyer à PayPal.

 

Code :

Public Class RemotePost

    Private Inputs As System.Collections.Specialized.NameValueCollection = New System.Collections.Specialized.NameValueCollection()

    Private _Url As String = String.Empty
    Private _Method As String = "post"
    Private _FormName As String = "form1"

    Public Sub Add(ByVal name As String, ByVal value As String)
        Inputs.Add(name, value)
    End Sub

    Public Sub Post()
        System.Web.HttpContext.Current.Response.Clear()

        System.Web.HttpContext.Current.Response.Write("<html><head>")

        System.Web.HttpContext.Current.Response.Write(String.Format("</head><body onload=document.{0}.submit()>", FormName))

        System.Web.HttpContext.Current.Response.Write(String.Format("<form name='{0}' method='{1}' action='{2}' >", FormName, Method, Url))
        For i As Integer = 0 To Inputs.Keys.Count - 1
            System.Web.HttpContext.Current.Response.Write(String.Format("<input name='{0}' type='hidden' value='{1}'>", Inputs.Keys(i), Inputs(Inputs.Keys(i))))

        Next
        System.Web.HttpContext.Current.Response.Write("</form>")
        System.Web.HttpContext.Current.Response.Write("</body></html>")
        System.Web.HttpContext.Current.Response.End()
    End Sub

    Property FormName() As String
        Get
            Return _FormName
        End Get
        Set(ByVal value As String)
            _FormName = value
        End Set
    End Property

    Property Method() As String
        Get
            Return _Method
        End Get
        Set(ByVal value As String)
            _Method = value
        End Set
    End Property

    Property Url() As String
        Get
            Return _Url
        End Get
        Set(ByVal value As String)
            _Url = value
        End Set
    End Property
End Class

 

Ensuite il suffit de créer votre propre bouton et d’utiliser votre classe RemotPost dans l’événement click du bouton.

 

Code :

Protected Sub ImageButtonPanier_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButtonPanier.Click
        Dim remote As New RemotePost
        remote.Url = "https://www.paypal.com/cgi-bin/webscr"
        remote.Add("cmd", "_s-xclick")
        remote.Add("encrypted", "-----BEGIN PKCS7----- … -----END PKCS7-----")
        remote.Post()
End Sub

 

La classe RemotPost peut être utilisée pour tous les autres boutons PayPal.

Partager cet article
Repost0
7 août 2009 5 07 /08 /août /2009 09:26

Pour mettre un FCKEditor dans un update panel sans obtenir d’erreur lors d’un postBack vous devez mettre le code suivant dans votre page.

 

Code :

 

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

       Me.ClientScript.RegisterOnSubmitStatement(Me.GetType, "AjaxHack", "for ( var i = 0; i < parent.frames.length; ++i ) if ( parent.frames[i].FCK) parent.frames[i].FCK.UpdateLinkedField();")

End Sub

N’oubliez pas de remplacer FCK par le nom de votre FCKEditor

Partager cet article
Repost0
20 juillet 2009 1 20 /07 /juillet /2009 11:19

 

Prenons pour exemple la chaîne de caractères suivante ayant des balises de formatage :

Code :

<p><span style="font-size: large">HELLO</span></p>

 

Pour obtenir uniquement le texte HELLO nous allons utiliser la fonction suivante :

 

Code :

Public Function HTMLParser(ByVal str As String) As String
        Return Regex.Replace(str, "(<[^>]+>)", " ")
End Function

Partager cet article
Repost0
20 juillet 2009 1 20 /07 /juillet /2009 08:17

Voici une fonction qui va vous permettre d’obtenir le chemin virtuel à partir du chemin physique :

Code :

Public Function GetVirtualPath(ByVal physicalPath As String) As String

       Dim rootpath As String = Server.MapPath("~/")
       physicalPath = physicalPath.Replace(rootpath, "")
       physicalPath = physicalPath.Replace("\\", "/")
       physicalPath = physicalPath.Replace("\", "/")
       Return "~/" & physicalPath
   End Function

Partager cet article
Repost0
30 juin 2009 2 30 /06 /juin /2009 17:30

L’utilisateur a souvent tendance à cliquer plusieurs fois sur le bouton de validation d’un formulaire, pensant que le premier clique n’a pas été pris en compte.

Par exemple, dans le cas d’un formulaire envoyant un email, il en résulte plusieurs envoies du même email.

Pour éviter ce désagrément et informer l’utilisateur que son premier clique a bien été pris en compte nous allons ajouter un peu de JavaScript dans notre code.

Dans cette exemple l’ID du bouton est “ButtonEnvoyer”. Vous devez remplacer cette ID par l’ID de votre bouton.

 

Voici notre bouton :

Code :

<asp:Button  id="ButtonEnvoyer" runat="server" Text="Envoyer" Width="125px" />

 

Et voici le code behind qui permet d’ajouter le JavaScript.

Code :

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim sbValid As System.Text.StringBuilder = New System.Text.StringBuilder

        sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ")

        sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ")

        sbValid.Append("this.value = 'Patientez svp...';")

        sbValid.Append("this.disabled = true;")

        sbValid.Append(ClientScript.GetPostBackEventReference(Me.ButtonEnvoyer, Nothing).ToString)

        sbValid.Append(";")

        ButtonEnvoyer.Attributes.Add("onclick", sbValid.ToString())

 

End Sub

 

Si le formulaire n’est pas valide le bouton est Enabled=True et affiche le texte “Envoyer”.

Si le formulaire est valide le bouton est Enabled=False et affiche “Patientez svp…”

Ce bouton peut être mis dans un UpdatePanel.

Partager cet article
Repost0
26 juin 2009 5 26 /06 /juin /2009 10:41

Voici la configuration du  Membership provider se trouvant dans le Web.config :

 

Code :

<membership>
            <providers>
                <remove name="AspNetSqlMembershipProvider"/>
                <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="myConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="true" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordFormat="Hashed" maxInvalidPasswordAttempts="100" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
            </providers>
        </membership>

 

D’après cette configuration, le mot de passe doit être de 6 caractères minimum et il est “Hashed” ce qui veut dire que l’on ne peut pas retrouver le mot de passe de l’utilisateur dans la base de données.

Si on utilise directement MembershipUser.ResetPassord, la méthode va générer un mot de passe qui est généralement très compliqué. La solution serait de Override la méthode, mais créer une nouvelle classe qui hérite de MemberShipUser juste pour Override une méthode c’est un peu lourd.

 

Voici comment procéder pour faire plus simple.

Tout d’abord nous allons créer une méthode qui va nous retourner le MemberShipUser à partir du nom de l’utilisateur.

Code :

Public Function GetMembershipUser(ByVal userName As String) As MembershipUser
        Dim mu As MembershipUser
        If userName = Nothing Then
            mu = Membership.GetUser()
        Else
            mu = Membership.GetUser(userName)
        End If
        Return mu
    End Function

Ensuite nous allons créer une méthode qui va générer notre nouveau mot de passe.

Code :

Public Function GenPassword(ByVal lenght As Integer) As String
        Dim strAlphaNum As String()
        Dim password As New StringBuilder
        Dim rnd As New Random
        strAlphaNum = New String(58) {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
        For iAlpha As Integer = 1 To lenght
            password.Append(strAlphaNum(rnd.Next(58)))
        Next
        Return password.ToString
    End Function

Vous remarquerez que la lettre O et le chiffre 0 ne seront pas utilisés car trop souvent confondu par les utilisateurs.

 

Et enfin nous allons créer notre propre méthode ResetUserPassword.

Code :

Public Function ResetUserPassword(ByVal userName As String) As String
        Dim mu As MembershipUser = GetMembershipUser(userName)
        Dim oldPassword As String = mu.ResetPassword
        Dim newPassword As String = GenPassword(Membership.MinRequiredPasswordLength)
        mu.ChangePassword(oldPassword, newPassword)
        Return newPassword
    End Function

L’astuce est simple. On utilise MembershipUser .ResetPassword qui va nous retourner un nouveau mot de passe, puis on utilise MembershipUser.ChangePassword pour modifier à nouveau le mot de passe, mais cette fois ci, en utilisant notre propre méthode GenPassword.

Partager cet article
Repost0
19 juin 2009 5 19 /06 /juin /2009 10:07

Vous pouvez forcer IE8 à se comporter comme IE7 en ajoutant un meta tag entres les balises <head> de votre page ou de votre MasterPage.

Ceci peut résoudre des problèmes de compatibilité avec IE8, qui sont courant, en particulier pour l’affichage des menus.

 

Code :

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

Partager cet article
Repost0