Question

C’est bizarre, je me demandais si quelqu'un pourrait nous expliquer pourquoi cela s’est passé.

En gros, je me suis démené en essayant de tester JSONP afin de pouvoir mettre en œuvre un service Web JSON que d'autres sites peuvent utiliser. Je fais du développement sur localhost, en particulier Visual Studio 2008 et le serveur Web intégré de Visual Studio 2008.

Donc, en tant que test JSONP avec jQuery, j'ai implémenté les éléments suivants:

$().ready(function() {
  debugger;
  try {
    $.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
        alert(data.abc);
    });
  } catch (err) {
    alert(err);
  }
});

Et sur le serveur ..

<%= Request["callback"] %>({abc : 'def'})

Donc, ce qui finit par se produire, c’est que j’ai défini un point d’arrêt sur le serveur et que je l’obtiens à la fois sur le premier & "; debugger; &"; déclaration dans le script côté client ainsi que sur le serveur. L'URL JSONP est en effet appelée après le chargement de la page. Cela fonctionne très bien.

Le problème que je rencontrais était que le rappel ne s'exécuterait jamais. J'ai testé cela dans IE8 ainsi que Firefox 3.5. Ni l'un ni l'autre n'invoquerait le rappel. La capture (err) n'a jamais été atteinte non plus. Rien ne s'est passé du tout!

Cela faisait une semaine que je restais bloqué dessus, et même testé avec une demande HTTP à clé manuelle dans Telnet sur le port spécifié pour vérifier que le serveur retournait le format ...

callbackfn({abc : 'def'})

.. et c'est le cas.

Je me suis alors demandé si je changeais le nom d’hôte de localhost en localhost avec un globaliseur ('.'), c’est-à-dire http://localhost.:41559/ au lieu de http: // localhost: 41559 / (oui, L'ajout d'un point à n'importe quel nom d'hôte est légal, c'est au DNS ce que global:: représente les espaces de noms C #). Et puis ça a marché! Internet Explorer et Firefox 3.5 m'ont finalement montré un message d'alerte lorsque je venais d'ajouter un point.

Donc, cela me fait me demander ce qui se passe ici? Pourquoi la dernière génération de balises de script fonctionne-t-elle avec un nom d'hôte Internet et non avec plain localhost? Ou est-ce la bonne question?

Ceci est clairement mis en œuvre pour des raisons de sécurité, mais que tentent-ils de sécuriser? Et, en le faisant fonctionner avec un point, est-ce que je viens d'exposer une faille de sécurité dans cette fonctionnalité de sécurité?

Au fait, mon fichier hosts, bien que modifié pour les autres hôtes, n’a rien de spécial avec localhost; les valeurs par défaut 127.0.0.1 / :: 1 sont toujours en place et aucune substitution n'est effectuée en dessous.

SUIVI: J'ai surmonté cette difficulté à des fins de développement local en ajoutant:

127.0.0.1   local.mysite.com

.. dans mon fichier hosts, puis en ajoutant le code suivant à mon fichier global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.Headers["Host"].Split(':')[0] == "localhost")
    {
        Response.Redirect(
            Request.Url.Scheme
            + "://"
            + "local.mysite.com"
            + ":" + Request.Url.Port.ToString()
            + Request.Url.PathAndQuery
            , true);
    }
}
Était-ce utile?

La solution

Je vais lancer une réponse là-bas; après réflexion, j’ai tiré mes propres conclusions.

Il s’agit peut-être d’une fonctionnalité de sécurité implémentée pour tenter d’empêcher un site Web Internet d’appeler des services JSONP exécutés sur la machine cliente.

Un site Web peut simplement passer par une liste de ports et continuer à appeler localhost sur différents ports et chemins. 'Localhost' est l'un des rares noms d'hôte DNS dont le sens est dynamique, en fonction du moment et de l'emplacement de l'interrogation, ce qui rend les cibles potentielles vulnérables. Et oui, le fait d'ajouter un point (.) À 'localhost' ('localhost.') Produit une solution de contournement qui expose une vulnérabilité de sécurité, mais offre une solution de contournement [provisoire] pour les besoins du développement.

Une meilleure approche consiste à mapper l'adresse IP de bouclage sur une nouvelle entrée de nom d'hôte dans le fichier hosts afin qu'elle fonctionne localement, elle n'est pas susceptible d'être & "corrigée &"; mise à jour du navigateur et ne fonctionne nulle part ailleurs que sur le poste de travail de développement.

Autres conseils

Je rencontre un problème similaire. La plupart des solutions que j’ai essayées fonctionnent avec IE (7), mais j’ai du mal à faire jouer Firefox (3.5.2).

J'ai installé HttpFox afin de voir comment les réponses de mon serveur sont interprétées sur le client et j'obtiens NS_ERROR_DOM_BAD_URI. Ma situation est toutefois un peu différente de la vôtre, car j'essaie d'invoquer un appel JSONP vers le même site d'où provient la page d'hébergement, puis cet appel répond par une redirection 302 vers un autre site. (J'utilise la redirection comme un moyen pratique d'obtenir des cookies des deux domaines renvoyés au navigateur.)

J'utilise jQuery et j'avais initialement essayé de faire un appel AJAX standard via $ .ajax (). Je pensais que, puisque la demande initiale concernait le même site que la page d'hébergement, Firefox ne faisait que suivre la réponse 302 à un autre domaine. Mais non, il semblait tomber sous le coup des défenses XSS. (Notez que, contrairement à ce que renvoie une redirection en réponse à une demande XHR , jQuery suit la redirection 302 pour un appel standard dataType = & "json &"; une redirection vers le même domaine fonctionne correctement; une redirection vers un autre domaine génère NS_ERROR_DOM_BAD_URI dans le navigateur.) De plus, Je ne vois pas pourquoi les redirections 302 du même domaine vers d'autres domaines ne peuvent pas être simplement suivies - après tout, c'est le domaine de la page d'hébergement qui émet la redirection, alors pourquoi ne peut-on pas y faire confiance? Si les attaques par injection de scripts vous inquiètent, la route JSONP est ouverte aux abus de toute façon ...

$ .getJSON () de jQuery avec un? callback =? Le suffixe échoue également dans Firefox avec la même erreur. De même que l'utilisation de $ .getScript () pour lancer mon propre fichier JSONP & Lt; script & Gt; tag.

Ce qui semble fonctionner, c’est de posséder un & script existant = & "jsonp &"; type = " text / javascript " > < / script > dans le HTML et ensuite en utilisant $ (& "; jsonp &"). attr (& "; src &"; url + & ";? callback = myCallback &" ;) pour appeler l'appel JSONP. Si je le fais, la redirection inter-domaines 302 est suivie et ma réponse JSON est transmise à myCallback (que j'ai définie en même temps que la balise & Lt; script / & Gt;)).

Et oui, je développe tout cela en utilisant Cassini avec les URL localhost: port . Cassini ne répond pas aux URL non locales, donc je ne peux pas facilement essayer local.mysite.com pour voir si cela a un impact sur les solutions que j'ai essayées ci-dessus. Cependant, coller un point à la fin de localhost semble avoir résolu tous mes problèmes!

Je peux maintenant revenir à un appel standard $ .ajax ({... dataType: " jsonp "}} avec localhost __.__: port au lieu de localhost: port et tout va bien. Il est intéressant de noter que la modification de l'attribut src d'une balise de script préexistante dans le HTML de la page autorise à invoquer des URL d'hôte local ordinaires. Je suppose qu'en suivant votre processus de réflexion, cela pourrait constituer une autre faille de sécurité. .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top