web-dev-qa-db-fra.com

HTTP_ORIGIN est-il sécurisé?

Je veux savoir si un appel HTTP_REQUEST entrant d'un site Web tiers provient de la liste des domaines que j'ai définis.

Je sais que HTTP_REFERER peut être utilisé pour savoir où se trouve le domaine tiers, mais il n'est pas suffisamment sécurisé. Les gens peuvent l'usurper ou utiliser Telnet pour le truquer.

Alors, qu'en est-il de HTTP_ORIGIN? Est-il envoyé depuis tous les navigateurs? Est-ce sécurisé?

De plus, les utilisateurs peuvent-ils simuler REMOTE_ADDR dans un appel HTTP_REQUEST?

29
murvinlai

HTTP_Origin est un moyen de se protéger contre les demandes CSRF (Cross Site Request Forgery). Actuellement, il n'est implémenté que par Chrome (en novembre 2011). J'ai testé Firefox et Opera - mais ils ont échoué. Son nom dans l'en-tête de la demande est "Origin ". Côté serveur dans mon script php, je le vois comme" HTTP_Origin "dans la variable $ _SERVER. Cet en-tête n'est envoyé que dans certains cas, lorsque la protection contre CSRF est requise (seulement POST devrait être Voici la liste de toutes les requêtes, qu'elles soient définies ou non:

https://wiki.mozilla.org/Security/Origin

Étiquette d'ancrage - NON

Navigation dans la fenêtre - NON

IMG - NON

iframe, embed, applet - OUI

Formulaire (GET et POST) - OUI

SCRIPT - OUI

feuilles de style - NON

charges dépendantes des feuilles de style - NON

Redirection - OUI

XHR - OUI

L'en-tête d'origine n'est implémenté que dans Chrome, malheureusement. Il a été annoncé pour la première fois en janvier 2010 sur le blog de Google Chrome:

http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html

Protection CSRF via l'en-tête d'origine

L'en-tête Origin est une nouvelle fonctionnalité HTML5 qui vous aide à défendre votre site contre les attaques de contrefaçon de demande intersite (CSRF). Dans une attaque CSRF, un site Web malveillant, par exemple attacker.com, demande au navigateur de l'utilisateur d'envoyer une demande HTTP à un serveur cible, par exemple example.com, qui incite le serveur example.com à effectuer une action. Par exemple, si example.com est un fournisseur de messagerie Web, l'attaque CSRF peut inciter example.com à transférer un e-mail à l'attaquant.

L'en-tête Origin aide les sites à se défendre contre les attaques CSRF en identifiant le site Web qui a généré la demande. Dans l'exemple ci-dessus, example.com peut voir que la demande provient du site Web malveillant car l'en-tête Origin contient la valeur http://attacker.com . Pour utiliser l'en-tête Origin comme défense CSRF, un site ne doit modifier l'état qu'en réponse aux demandes qui (1) n'ont pas d'en-tête Origin ou (2) ont un en-tête Origin avec une valeur en liste blanche.

J'implémente juste la protection CSRF dans mon script php, j'utilise personnellement Chrome donc cela me suffit, j'espère que d'autres navigateurs attraperont chrome bientôt).

Ce qui est drôle, c'est que Mozilla a inventé cette fonctionnalité de sécurité, car vous pouvez lire beaucoup de documentation de cet en-tête Origin sur son site Web, mais ils n'ont toujours pas eu le temps de l'implémenter ;-)

HTTP_Origin ne semble contenir que "protocole" et "domaine", sans barre oblique à la fin: " http://www.example.com " - même si vous avez envoyé le formulaire depuis " http://www.example.com/myform/ ".

Une protection simple contre CSRF dans PHP:

if ("POST" == $_SERVER["REQUEST_METHOD"]) {
    if (isset($_SERVER["HTTP_Origin"])) {
        $address = "http://".$_SERVER["SERVER_NAME"];
        if (strpos($address, $_SERVER["HTTP_Origin"]) !== 0) {
            exit("CSRF protection in POST request: detected invalid Origin header: ".$_SERVER["HTTP_Origin"]);
        }
    }
}

Ce script pourrait toujours être mis à niveau pour prendre en charge PORT autre que 80 (l'origine contient le port lorsqu'il est différent de 80), les connexions HTTPS et l'envoi des formulaires de différents sous-domaines (ex. Sub.example.com => publication de la demande sur www.example .com).

57
Czarek Tomczak

HTTP_Origin n'est ni envoyé par tous les navigateurs ni sécurisé.

Aucun élément envoyé par le navigateur ne peut être considéré comme sûr.

26
ceejayoz

HTTP est un protocole en texte brut. La structure d'en-tête/corps de la requête ENTIÈRE peut être truquée pour dire tout ce que vous voulez.

14
Marc B

Les gens ici pensent que tout cela est mal - la norme 'CORS' ne l'est pas pour que le serveur ne soit pas piraté, même si cela aide en plus de ce qu'il fait. Le but est de permettre au "NAVIGATEUR" d'avoir un moyen d'alléger les demandes qui vont à l'encontre de la même politique d'origine. Si le client et le serveur sont sur la même page, le "CLIENT" peut décider d'autoriser ou non la demande.

De toute évidence, en faisant participer le serveur à la décision, vous contribuez au processus de sécurité.

Mais cela ne protégera pas le serveur contre les accès non autorisés - c'est à cela que servent les mots de passe et les cookies.

Le client peut être (comme quelqu'un l'a mentionné) un outil telnet, où chaque chose conçue est fausse.

Mais l'un des arguments de vente de Chrome, FF, etc., est qu'ils vous aideront en ne permettant pas à Javascript d'aller en dehors du même bac à sable d'origine, ce qui signifie que la seule chose par défaut qui peut être compromise est ce qui se trouve sur le ' propre site Web des attaquants. Ou d'autres sites qui décident de ne pas être sécurisés.

CORS est la technologie qui vous permet de dire - hé, je veux que les utilisateurs puissent consommer mon service snazzy à partir du javascript sur cet autre site qu'ils utilisent. Je vais donc ajouter ce site à mes exceptions. Ce qui signifie que vous aidez vos utilisateurs autorisés à percer la sécurité de leur navigateur pour ce site particulier. Ce qui signifie un trou qu'un pirate peut exploiter. D'où le soin avec lequel vous avez mis en place le service, non?

Cela signifie que tout site qui n'a pas configuré CORS est par défaut sécurisé contre Cross Site Scripting à partir d'un navigateur compatible (sauf bugs et hacks bien sûr). Le navigateur vous demandera si ce service souhaite participer au javascript du site d'origine, et si le site croisé dit "Je ne sais rien de ce putain de site", alors le moteur javascript du navigateur fermera la connexion et videra les données.

Donc, pour résumer, CORS ne vous aide pas à sécuriser les choses. Il vous aide à percer la capacité de votre navigateur à sécuriser un utilisateur. Mais j'espère d'une manière gérée .. et seulement pour des sites particuliers ..

12
Gerard ONeill

mis à jour:

function isOriginAllowed($incomingOrigin, $allowOrigin)
{
    $pattern = '/^http:\/\/([\w_-]+\.)*' . $allowOrigin . '$/';

    $allow = preg_match($pattern, $incomingOrigin);
    if ($allow)
    {
        return true;
    }
    else
    {
        return false;
    }
}

$incomingOrigin = array_key_exists('HTTP_Origin', $_SERVER) ? $_SERVER['HTTP_Origin'] : NULL;
    $allowOrigin    = $_SERVER['HTTP_Host'];

    if ($incomingOrigin !== null && isOriginAllowed($incomingOrigin, $allowOrigin))
    {
        exit("CSRF protection in POST request: detected invalid Origin header: " . $incomingOrigin);
    }

Exemple:

  • http: // media.mydomain.com TRUE
  • http: // offline.mydomain.com TRUE
  • http: // domen1.mydomain.com TRUE
  • http: // domen_1.mydomain.com TRUE
  • http: // domen-1.mydomain.com TRUE
  • http: // ololomydomain.com FAUX
  • http: // mydomain.com TRUE
  • http: // pro.mydomain.com TRUE
  • http: // super.pro.mydomain.com TRUE
  • http: // super.pro.fakemydomain.com FAUX
  • http: // pro.fakemydomain.com FAUX
5
ahiipsa

Tout dans la requête HTTP peut être falsifié.

4
Andy Lester