Heim  >  Artikel  >  Web-Frontend  >  Einführung in die JavaScript-Ursprungsrichtlinie und den domänenübergreifenden Zugriff

Einführung in die JavaScript-Ursprungsrichtlinie und den domänenübergreifenden Zugriff

不言
不言Original
2018-07-03 17:19:111976Durchsuche

Dieser Artikel stellt hauptsächlich die JavaScript-Richtlinie für den gleichen Ursprung und den domänenübergreifenden Zugriff vor. Er analysiert die Prinzipien, die Implementierung, die Verwendung und die damit verbundenen Vorsichtsmaßnahmen der JavaScript-Richtlinie für den gleichen Ursprung und den domänenübergreifenden Zugriff im Detail es kann Als Referenz:

Die Beispiele in diesem Artikel beschreiben die JavaScript-Same-Origin-Richtlinie und den domänenübergreifenden Zugriff. Teilen Sie es allen als Referenz mit. Die Einzelheiten lauten wie folgt:

1. Was ist die Same-Origin-Richtlinie?

Um Cross zu verstehen -Domäne müssen Sie zunächst die Strategie der Same-Origin-Richtlinie verstehen. Die Same Origin Policy ist eine sehr wichtige Sicherheitsrichtlinie, die aus Sicherheitsgründen in Browsern implementiert wird.

Was ist der gleiche Ursprung:

URL besteht aus Protokoll, Domänenname, Port und Pfad, wenn Protokoll, Domänenname und Port zweier URLs identisch sind , es bedeutet, dass sie den gleichen Ursprung haben.

Same-Origin-Richtlinie:

Die Same-Origin-Richtlinie des Browsers verhindert, dass „Dokumente“ oder Skripte aus verschiedenen Quellen bestimmte Eigenschaften des aktuellen „Dokuments“ lesen oder festlegen. (White Hats sprechen über Web-Sicherheit [1])

Skripte, die von einer Domäne geladen werden, dürfen nicht auf Dokumentattribute einer anderen Domäne zugreifen.

Zum Beispiel:

Zum Beispiel bettet die Seite einer bösartigen Website die Anmeldeseite einer Bank über einen Iframe ein (beide haben unterschiedliche Ursprünge, das Javascript-Skript). Auf der bösartigen Webseite werden Benutzername und Passwort abgerufen, wenn sich der Benutzer bei der Bank anmeldet.

Tags wie 3f1c4e4b6b16bbbd69b2ee476dc4f83a, a1f02c36ba31691bcfe87b2722de723b, d5ba1642137c3f32f4f4493ae923989c, 2cdf5bf648cf2f33323966d7f58a7f3f können domänenübergreifende Ressourcen laden, ohne durch denselben Ursprung eingeschränkt zu werden, sind aber durch eingeschränkt Die JavaScript-Berechtigungen sind deaktiviert, sodass der geladene Inhalt nicht gelesen oder geschrieben werden kann.

Darüber hinaus beschränkt die Same-Origin-Richtlinie nur die HTML-Dokumente von Webseiten, und andere geladene statische Ressourcen wie Javascript, CSS, Bilder usw. gelten weiterhin als zum selben Ursprung gehörend.

Codebeispiel (http://localhost:8080/ und http://localhost:8081 haben unterschiedliche Quellen aufgrund unterschiedlicher Ports):

http://localhost:8080/test. html

<html>
  <head><title>test same origin policy</title></head>
  <body>
    <iframe id="test" src="http://localhost:8081/test2.html"></iframe>
    <script type="text/javascript">
      document.getElementById("test").contentDocument.body.innerHTML = "write somthing";
    </script>
  </body>
</html>

http://localhost:8081/test2.html

<html>
  <head><title>test same origin policy</title></head>
  <body>
    Testing.
  </body>
</html>

at Sie erhalten in Firefox die folgende Fehlermeldung:

Fehler: Berechtigung zum Zugriff auf die Eigenschaft „body“ verweigert

Das Domänenattribut des Dokumentobjekts speichert den Hostnamen von Der Server, der das Dokument lädt, kann eingestellt werden.

Wenn beispielsweise Seiten von „blog.php.cn“ und „bbs.php.cn“ beide document.domain auf „php.cn“ setzen, können die Skripte der beiden Subdomains miteinander interagieren Sonstiges.

Aus Sicherheitsgründen kann es nicht auf andere Hauptdomänen eingestellt werden. Beispielsweise kann //www.php.cn/ nicht auf sina.com eingestellt werden

2 . Ajax-Cross-Domain-Domäne

Ajax-Anfragen (XMLHttpRequest) sind durch die Same-Origin-Richtlinie eingeschränkt.

Ajax kann über XMLHttpRequest mit Remote-Servern interagieren. Darüber hinaus ist XMLHttpRequest ein reines Javascript-Objekt und wird von Benutzern nicht leicht bemerkt.

Daher hat XMLHTTP tatsächlich die Sicherheitsbeschränkungen des ursprünglichen Javascript durchbrochen.

Zum Beispiel:

Angenommen, eine Website referenziert das Javascript anderer Websites und fügt Javascript hinzu, um Benutzereingaben zu erhalten und diese über Ajax an andere Websites weiterzuleiten beschafft werden. Sammeln Sie kontinuierlich Informationen.

Oder eine Website kann aufgrund einer Sicherheitslücke XSS in ein Javascript-Skript einfügen. Dieses Skript kann Benutzerinformationen über Ajax abrufen und über Ajax an andere Websites übermitteln, sodass kontinuierlich Informationen gesammelt werden können.

Wenn wir die aktualisierungsfreie asynchrone Interaktionsfähigkeit von XMLHTTP nutzen möchten, aber nicht bereit sind, die Sicherheitsrichtlinien von Javascript offensichtlich zu brechen, besteht die Alternative darin, strenge Same-Origin-Einschränkungen zu XMLHTTP hinzuzufügen.

Diese Sicherheitsrichtlinie ist der Sicherheitsrichtlinie von Applet sehr ähnlich. Die Einschränkung von IFrame besteht darin, dass es nicht auf Daten im domänenübergreifenden HTML-DOM zugreifen kann, während XMLHTTP die Übermittlung domänenübergreifender Anforderungen grundsätzlich einschränkt. (Tatsächlich wird unten erwähnt, dass CORS die Beschränkungen gelockert hat)

Mit der Entwicklung der Ajax-Technologie und Netzwerkdienste werden die Anforderungen für domänenübergreifendes Arbeiten immer stärker. Im Folgenden wird die domänenübergreifende Technologie von Ajax vorgestellt.

2.1 JSONP

Die JSONP-Technologie hat eigentlich nichts mit Ajax zu tun. Wir wissen, dass das 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Tag domänenübergreifende Javascript-Skripte laden kann und die geladenen Skripte und das aktuelle Dokument zur selben Domäne gehören. So können die Daten und Funktionen im Skript im Dokument aufgerufen bzw. darauf zugegriffen werden. Wenn die Daten im JavaScript-Skript dynamisch generiert werden, kann die Dateninteraktion mit dem Server durch dynamisches Erstellen eines 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Tags im Dokument erreicht werden.

JSONP nutzt die domänenübergreifende Fähigkeit des 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Tags, um einen domänenübergreifenden Datenzugriff zu erreichen, indem es ein dynamisch generiertes JavaScript-Skript mit einem Callback-Funktionsnamen als Parameter anfordert. Unter diesen ist die Rückruffunktion eine JavaScript-Funktion des lokalen Dokuments. Das dynamisch generierte Skript auf der Serverseite generiert Daten, und die Rückruffunktion wird im Code mit den generierten Daten als Parameter aufgerufen. Wenn dieses Skript in das lokale Dokument geladen wird, wird die Callback-Funktion aufgerufen.

Testseite der ersten Seite (http://localhost:8080/test.html):

<script src="http://localhost:8081/test_data.js">
  <script>
    function test_handler(data) {
      console.log(data);
    }
</script>

服务器端的Javascript脚本(http://localhost:8081/test_data.js):

test_handler(&#39;{"data": "something"}&#39;);

为了动态实现JSONP请求,可以使用Javascript动态插入3f1c4e4b6b16bbbd69b2ee476dc4f83a标签:

<script type="text/javascript">
    // this shows dynamic script insertion
    var script = document.createElement(&#39;script&#39;);
    script.setAttribute(&#39;src&#39;, url);
    // load the script
    document.getElementsByTagName(&#39;head&#39;)[0].appendChild(script);
</script>

JSONP协议封装了上述步骤,jQuery中统一是现在AJAX中(其中data type为JSONP):

http://localhost:8080/test?callback=test_handler

为了支持JSONP协议,服务器端必须提供特别的支持[2],另外JSONP只支持GET请求。

2.2 Proxy

使用代理方式跨域更加直接,因为SOP的限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。

使用本方法跨域步骤如下:

1. 把访问其它域的请求替换为本域的请求

2. 本域的请求是服务器端的动态脚本负责转发实际的请求

各种服务器的Reverse Proxy功能都可以非常方便的实现请求的转发,如Apache httpd + mod_proxy。

Eg.

为了通过Ajax从http://localhost:8080访问http://localhost:8081/api,可以将请求发往http://localhost:8080/api。

然后利用Apache Web服务器的Reverse Proxy功能做如下配置:

ProxyPass /api http://localhost:8081/api

2.3 CORS

2.3.1 Cross origin resource sharing

“Cross-origin resource sharing (CORS) is a mechanism that allows a web page to make XMLHttpRequests to another domain. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request. It is more powerful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.” ----Wikipedia[3]

通过在HTTP Header中加入扩展字段,服务器在相应网页头部加入字段表示允许访问的domain和HTTP method,客户端检查自己的域是否在允许列表中,决定是否处理响应。

实现的基础是JavaScript不能够操作HTTP Header。某些浏览器插件实际上是具有这个能力的。

服务器端在HTTP的响应头中加入(页面层次的控制模式):

Access-Control-Allow-Origin: example.com
Access-Control-Request-Method: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin
Access-Control-Expose-Headers: Content-Range
Access-Control-Max-Age: 3600

多个域名之间用逗号分隔,表示对所示域名提供跨域访问权限。"*"表示允许所有域名的跨域访问。

客户端可以有两种行为:

1. 发送OPTIONS请求,请求Access-Control信息。如果自己的域名在允许的访问列表中,则发送真正的请求,否则放弃请求发送。

2. 直接发送请求,然后检查response的Access-Control信息,如果自己的域名在允许的访问列表中,则读取response body,否则放弃。

本质上服务端的response内容已经到达本地,JavaScript决定是否要去读取。

Support: [Javascript Web Applications]
* IE >= 8 (需要安装caveat)
* Firefox >= 3
* Safari 完全支持
* Chrome 完全支持
* Opera 不支持

 2.3.2 测试

测试页面http://localhost:8080/test3.html使用jquery发送Ajax请求。

<html>
    <head><title>testing cross sop</title></head>
    <body>
      Testing.
      <script src="jquery-2.0.0.min.js"></script>
      <script type=&#39;text/javascript&#39;>
        $.ajax({
          url: &#39;http://localhost:8000/hello&#39;,
          success: function(data) {
            alert(data);
          },
          error: function() {
            alert(&#39;error&#39;);
          }
        });
      </script>
    </body>
</html>

测试Restful API(http://localhost:8000/hello/{name})使用bottle.py来host。

from bottle import route, run, response
@route(&#39;/hello&#39;)
def index():
  return &#39;Hello World.&#39;
run(host=&#39;localhost&#39;, port=8000)

测试1:

测试正常的跨域请求的行为。

测试结果:

1. 跨域GET请求已经发出,请求header中带有

    Origin    http://localhost:8080

2. 服务器端正确给出response

3. Javascript拒绝读取数据,在firebug中发现reponse为空,并且触发error回调

测试2:

测试支持CORS的服务器的跨域请求行为。

对Restful API做如下改动,在response中加入header:

def index():
  #Add CORS header#
  response.set_header("Access-Control-Allow-Origin", "http://localhost:8080")
  return &#39;Hello World.&#39;

测试结果:

1. 跨域GET请求已经发出,请求header中带有

Origin    http://localhost:8080

2. 服务器端正确给出response

3. 客户端正常获取数据

测试3:

测试OPTIONS请求获取CORS信息。
对客户端的Ajax请求增加header:

$.ajax({
 url: &#39;http://localhost:8000/hello&#39;,
 headers: {&#39;Content-Type&#39;: &#39;text/html&#39;},
 success: function(data) {
   alert(data);
 },
 error: function() {
   alert(&#39;error&#39;);
 }
});

对Restful API做如下改动:

@route(&#39;/hello&#39;, method = [&#39;OPTIONS&#39;, &#39;GET&#39;])
def index():
  if request.method == &#39;OPTIONS&#39;:
    return &#39;&#39;
  return &#39;Hello World.&#39;

测试结果:

1. Ajax函数会首先发送OPTIONS请求
2. 针对OPTIONS请求服务器
3. 客户端发现没有CORS header后不会发送GET请求

测试4:

增加服务器端对OPTIONS方法的处理。

对Restful API做如下改动:

@route(&#39;/hello&#39;, method = [&#39;OPTIONS&#39;, &#39;GET&#39;])
def index():
    response.headers[&#39;Access-Control-Allow-Origin&#39;] = &#39;http://localhost:8080&#39;
    response.headers[&#39;Access-Control-Allow-Methods&#39;] = &#39;GET, OPTIONS&#39;
    response.headers[&#39;Access-Control-Allow-Headers&#39;] = &#39;Origin, Accept, Content-Type&#39;
    if request.method == &#39;OPTIONS&#39;:
      return &#39;&#39;
    return &#39;Hello World.&#39;

测试结果:

1. Ajax函数会首先发送OPTIONS请求
2. 针对OPTIONS请求服务器
3. 客户端匹配CORS header中的allow headers and orgin后会正确发送GET请求并获取结果

测试发现,Access-Control-Allow-Headers是必须的。

CORS协议提升了Ajax的跨域能力,但也增加了风险。一旦网站被注入脚本或XSS攻击,将非常方便的获取用户信息并悄悄传递出去。

4. Cookie 同源策略

Cookie中的同源只关注域名,忽略协议和端口。所以https://localhost:8080/和http://localhost:8081/的Cookie是共享的。

5. Flash/SilverLight跨域

浏览器的各种插件也存在跨域需求。通常是通过在服务器配置crossdomain.xml[4],设置本服务允许哪些域名的跨域访问。

客户端会首先请求此文件,如果发现自己的域名在访问列表里,就发起真正的请求,否则不发送请求。

<?xml version="1.0"?>
  <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
  <cross-domain-policy>
  <allow-access-from domain="*"/>
  <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

通常crossdomain.xml放置在网站根目录。

6. 总结

互联网的发展催生了跨域访问的需求,各种跨域方法和协议满足了需求但也增加了各种风险。尤其是XSS和CSRF等攻击的盛行也得益于此。

了解这些技术背景有助于在实际项目中熟练应用并规避各种安全风险。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

Javascript实现商品秒杀倒计时(时间与服务器时间同步)的解析

JS实现的JSON序列化操作

Das obige ist der detaillierte Inhalt vonEinführung in die JavaScript-Ursprungsrichtlinie und den domänenübergreifenden Zugriff. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn