web-dev-qa-db-fra.com

Une valeur Request.QueryString potentiellement dangereuse a été détectée par le client lors de l'envoi du balisage HTML à partir de jquery post call vers la page asp.net

Je fais un appel ajax en utilisant jQuery vers une page ASP.NET qui sert de page de serveur ajax pour enregistrer les données que je lui envoie dans la chaîne de requête. Dans la page ASP.NET, lorsque j'essaie de lire la chaîne de requête, j'obtiens cette erreur:

A potentially dangerous Request.QueryString value was detected from the client...

J'ai défini le ValidateRequest="false" dans ma page. Ne veux pas le définir pour toutes les pages. Il en a été ainsi au niveau de la page au lieu du niveau de configuration:

  var content = "<h3>Sample header</h3><p>sample para</p>"
  content = encodeURIComponent(content);
  var url = "../Lib/ajaxhandler.aspx?mode=savecontent&page=home&ltxt=" + content;

     $.post(url, function (data) { 
       //check return value and do something
   });

et dans ma page asp.net:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ajaxhandler.aspx.cs" ValidateRequest="false" Inherits="MyProject.Lib.ajaxhandler" %>

Mais lorsque j’envoie du texte brut au lieu du code HTML, cela fonctionne bien.

37
Shyju

S'il s'agit de ASP.NET 4, il y a eu un changement radical avec ValidateRequest. Voir cette question StackOverflow pour plus d’informations sur requestValidationMode.

35

Il y a déjà une bonne réponse à cela, et ici je vais vous donner les informations pour que vous n'ayez pas à cliquer sur les liens.

Lorsque vous exécutez ASP.NET 4.0, vous devez définir les éléments suivants dans votre fichier web.config RequestValidationMode="2.0".

A quoi sert cette propriété?

Une valeur qui indique quelle approche spécifique à la version ASP.NET pour la validation sera utilisée. La valeur par défaut est 4.0.

Alors, quelles sont les valeurs possibles?

  • 4.0 (par défaut). L’objet HttpRequest définit en interne un indicateur indiquant que la validation de la demande doit être déclenchée à tout moment.
    Les données de la requête HTTP sont consultées. Cela garantit que la demande
    la validation est déclenchée avant que des données telles que les cookies et les URL ne soient
    accédé pendant la demande. Les paramètres de validation de la demande du
    Élément pages (le cas échéant) dans le fichier de configuration ou de la @ page
    directive dans une page individuelle sont ignorés.

  • 2.0. La validation des demandes est activée uniquement pour les pages, pas pour toutes les demandes HTTP. En outre, les paramètres de validation de la demande des pages élément (le cas échéant) dans le fichier de configuration ou de la directive @ Page dans une page individuelle sont utilisés pour déterminer les demandes de page adressées à valider. </ li> </ ul> Informations citées sur ce site msdn.

8
Jim Aho

Si vous souhaitez ajouter une logique de validation personnalisée pour une page ASP.NET particulière ou pour un ou plusieurs paramètres de chaîne de requête sans définir ValidateRequest="false" pour la page entière, la solution "hacky" suivante peut s'avérer utile:

public partial class MyPage : System.Web.UI.Page
{
    private string SomeUnvalidatedValue { get; set; }

    public override void ProcessRequest(HttpContext context)
    {
        var queryString = context.Request.QueryString;

        var readOnly = queryString.GetType().GetProperty("IsReadOnly",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

        readOnly.SetValue(queryString, false);

        var unvalidatedValue = context.Request.Unvalidated.QueryString["SomeKey"];
        // for RequestValidationMode="2.0"
        //var unvalidatedValue = context.Request.QueryString["SomeKey"];

        // custom logic goes here

        // you could store unvalidated value here and then remove it from the query string
        SomeUnvalidatedValue = unvalidatedValue;
        queryString["SomeKey"] = string.Empty;
        // or just remove all "potentially dangerous" symbols, for example
        if (!string.IsNullOrEmpty(unvalidatedValue))
        {
            queryString["SomeKey"] = Regex.Replace(unvalidatedValue,
                "(\\<+[a-z!/\\?])|(&\\#)", new MatchEvaluator((m) =>
                {
                    return m.Value.Replace("<", string.Empty).Replace("&#", string.Empty);
                }), RegexOptions.IgnoreCase);
        }

        readOnly.SetValue(queryString, true);

        // keep other request validation logic as is
        base.ProcessRequest(context);
    }
}

L'expression régulière créée à la suite de cette méthode ASP.NET et analysant: CrossSiteScriptingValidation.IsDangerousString

Code testé avec .NET 4.5.2, mode intégré IIS, avec et sans RequestValidationMode="2.0".

2
VAV

J'ai créé quelques méthodes réutilisables basées sur La réponse de VAV

   public static string ExtractUnvalidatedValue(HttpRequest request, string key)
        {
            var unvalidatedValue =  HttpUtility.UrlDecode(request.Unvalidated.QueryString[key]);
            // for RequestValidationMode="2.0"
            //var unvalidatedValue = context.Request.QueryString["SomeKey"];

          // remove all "potentially dangerous" symbols
            return ReplacePotentiallyDangerousSymbols(unvalidatedValue, string.Empty);
        }

    public static string ReplacePotentiallyDangerousSymbols(string unvalidatedValue, string valueToReplace="")
        {
            if (!string.IsNullOrEmpty(unvalidatedValue))
            {
                //The regular expression made as result of this ASP.NET method analyzing: CrossSiteScriptingValidation.IsDangerousString http://referencesource.Microsoft.com/#System.Web/CrossSiteScriptingValidation.cs,3c599cea73c5293b
                unvalidatedValue = Regex.Replace(unvalidatedValue,
                    "(\\<+[a-z!/\\?])|(&\\#)",
                    new MatchEvaluator((m) => { return m.Value.Replace("<", valueToReplace).Replace("&#", valueToReplace); }), RegexOptions.IgnoreCase);
            }
            return unvalidatedValue;
        }
1