X-Frame-Options อนุญาตจากหลายโดเมน


100

ฉันมีไซต์ ASP.NET 4.0 IIS7.5 ซึ่งฉันต้องการความปลอดภัยโดยใช้ส่วนหัว X-Frame-Options

ฉันต้องเปิดใช้งานหน้าเว็บไซต์ของฉันให้เป็น iframed จากโดเมนเดียวกันและจากแอพ facebook ของฉัน

ขณะนี้ฉันได้กำหนดค่าไซต์ของฉันด้วยไซต์ที่มุ่งหน้าไปที่:

Response.Headers.Add("X-Frame-Options", "ALLOW-FROM SAMEDOMAIN, www.facebook.com/MyFBSite")

เมื่อฉันดูหน้า Facebook ของฉันด้วย Chrome หรือ Firefox หน้าเว็บไซต์ของฉัน (อยู่ใน iframed กับหน้า Facebook ของฉัน) จะแสดงผลได้ แต่ภายใต้ IE9 ฉันได้รับข้อผิดพลาด:

"ไม่สามารถแสดงหน้านี้ได้ ... " (เนื่องจากX-Frame_Optionsข้อ จำกัด )

ฉันจะตั้งค่าX-Frame-Options: ALLOW-FROMให้รองรับมากกว่าโดเมนเดียวได้อย่างไร

X-FRAME-OPTION การเป็นคุณลักษณะใหม่ดูเหมือนจะมีข้อบกพร่องโดยพื้นฐานหากสามารถกำหนดได้เพียงโดเมนเดียว


2
นี่ดูเหมือนจะเป็นข้อ จำกัด ที่ทราบกันดี: owasp.org/index.php/…
Pierre Ernst

คำตอบ:


111

X-Frame-Optionsเลิกใช้แล้ว จากMDN :

คุณลักษณะนี้ถูกลบออกจากมาตรฐานเว็บ แม้ว่าบางเบราว์เซอร์อาจยังรองรับอยู่ แต่ก็อยู่ในระหว่างการลดลง อย่าใช้ในโครงการเก่าหรือใหม่ เพจหรือเว็บแอพที่ใช้อาจพังได้ตลอดเวลา

ทางเลือกที่ทันสมัยคือContent-Security-Policyส่วนหัวซึ่งตามนโยบายอื่น ๆ อีกมากมายสามารถระบุ URL ที่อนุญาตให้โฮสต์เพจของคุณในเฟรมโดยใช้frame-ancestorsคำสั่ง
frame-ancestorsรองรับหลายโดเมนและแม้กระทั่งสัญลักษณ์แทนตัวอย่างเช่น:

Content-Security-Policy: frame-ancestors 'self' example.com *.example.net ;

น่าเสียดายที่ตอนนี้Internet Explorer ไม่สนับสนุนนโยบายเนื้อหา - ความปลอดภัยอย่างสมบูรณ์

อัปเดต: MDN ได้ลบความคิดเห็นเกี่ยวกับการเลิกใช้งาน นี่คือความคิดเห็นที่คล้ายกันจากระดับนโยบายการรักษาความปลอดภัยเนื้อหาของ W3C

frame-ancestorsสั่งobsoletesX-Frame-Optionsส่วนหัว หากทรัพยากรมีทั้งนโยบายframe-ancestorsนโยบายควรถูกบังคับใช้และX-Frame-Optionsนโยบายควรถูกละเว้น


14
เฟรมบรรพบุรุษถูกทำเครื่องหมายเป็น "API ทดลองและไม่ควรใช้ในรหัสการผลิต" บน MDN + X-Frame-Options ไม่ได้เลิกใช้งาน แต่ "ไม่ได้มาตรฐาน" แต่ "ได้รับการสนับสนุนอย่างกว้างขวางและสามารถใช้ร่วมกับ CSP ได้"
Jonathan Muller

1
@JonathanMuller - ถ้อยคำที่X-Frame-Optionsเปลี่ยนแปลงและรุนแรงน้อยลงในขณะนี้ เป็นจุดที่ดีที่มีความเสี่ยงที่จะใช้ข้อมูลจำเพาะที่ไม่ได้สรุป ขอบคุณ!
Kobi

2
ฉันไม่พบคำเตือนที่แก้ไขแล้วใน MDN อีกต่อไป Mozilla เปลี่ยนความคิดเห็นหรือไม่?
thomaskonrad

2
@ to0om - ขอบคุณ! ฉันอัปเดตคำตอบด้วยความคิดเห็นอื่น ฉันอาจจะพูดแรงเกินไปในคำตอบของฉัน ไม่ว่าจะด้วยวิธีX-Frame-Optionsใดก็ตามไม่สนับสนุนหลายแหล่ง
Kobi

4
@ Kobi ฉันคิดว่าคำตอบต้องการการจัดระเบียบใหม่ ประโยคแรกบอกว่าเลิกใช้แล้วตาม MDN จะทำให้เข้าใจผิดน้อยลงหากคุณเพิ่มการอัปเดตที่ด้านบนสุด (โดยมี "UPDATE:" เป็นตัวหนา) ขอบคุณ.
Kasun Gajasinghe

39

จากRFC 7034 :

ไม่อนุญาตให้ใช้สัญลักษณ์แทนหรือรายการเพื่อประกาศหลายโดเมนในคำสั่ง ALLOW-FROM เดียว

ดังนั้น,

ฉันจะตั้งค่า X-Frame-Options: ALLOW-FROM ให้รองรับมากกว่าโดเมนเดียวได้อย่างไร

คุณทำไม่ได้ วิธีแก้ปัญหาชั่วคราวคุณสามารถใช้ URL ที่แตกต่างกันสำหรับพันธมิตรที่แตกต่างกัน สำหรับแต่ละ URL คุณสามารถใช้X-Frame-Optionsค่าของมันเองได้ ตัวอย่างเช่น:

partner   iframe URL       ALLOW-FROM
---------------------------------------
Facebook  fb.yoursite.com  facebook.com
VK.COM    vk.yoursite.com  vk.com

สำหรับyousite.comคุณสามารถใช้X-Frame-Options: deny.

BTWสำหรับตอนนี้ Chrome (และเบราว์เซอร์ที่ใช้ webkit ทั้งหมด) ไม่สนับสนุน ALLOW-FROMข้อความใด


1
ดูเหมือนว่าตอนนี้ webkit จะรองรับALLOW-FROMโดยใช้ลิงค์ที่คุณให้มา
Jimi

3
@Jimi ไม่มัน - ความคิดเห็นสุดท้ายในลิงก์ที่เป็นปัญหาบอกว่าคุณต้องใช้นโยบาย CSP แทน ตัวเลือกนี้ยังใช้ไม่ได้ใน Chrome
NickG

9

เนโครแมนซิ่ง.
คำตอบที่ให้มาไม่สมบูรณ์

อย่างแรกตามที่ได้กล่าวไปแล้วว่าคุณไม่สามารถเพิ่มโฮสต์ที่อนุญาตหลายรายการซึ่งไม่ได้รับการสนับสนุน
ประการที่สองคุณต้องดึงค่านั้นออกจากผู้อ้างอิง HTTP แบบไดนามิกซึ่งหมายความว่าคุณไม่สามารถเพิ่มค่าให้กับ Web.config ได้เนื่องจากไม่ใช่ค่าเดียวกันเสมอไป

จำเป็นต้องทำการตรวจจับเบราว์เซอร์เพื่อหลีกเลี่ยงการเพิ่ม allow-from เมื่อเบราว์เซอร์เป็น Chrome (จะทำให้เกิดข้อผิดพลาดในคอนโซล debug ซึ่งสามารถเติมเต็มคอนโซลได้อย่างรวดเร็วหรือทำให้แอปพลิเคชันช้า) นั่นหมายความว่าคุณต้องแก้ไขการตรวจจับเบราว์เซอร์ ASP.NET เนื่องจากระบุ Edge เป็น Chrome อย่างไม่ถูกต้อง

สิ่งนี้สามารถทำได้ใน ASP.NET โดยการเขียนโมดูล HTTP ซึ่งทำงานในทุกคำขอที่ต่อท้าย http-header สำหรับทุกการตอบสนองขึ้นอยู่กับผู้อ้างอิงของคำขอ สำหรับ Chrome จำเป็นต้องเพิ่ม Content-Security-Policy

// /programming/31870789/check-whether-browser-is-chrome-or-edge
public class BrowserInfo
{

    public System.Web.HttpBrowserCapabilities Browser { get; set; }
    public string Name { get; set; }
    public string Version { get; set; }
    public string Platform { get; set; }
    public bool IsMobileDevice { get; set; }
    public string MobileBrand { get; set; }
    public string MobileModel { get; set; }


    public BrowserInfo(System.Web.HttpRequest request)
    {
        if (request.Browser != null)
        {
            if (request.UserAgent.Contains("Edge")
                && request.Browser.Browser != "Edge")
            {
                this.Name = "Edge";
            }
            else
            {
                this.Name = request.Browser.Browser;
                this.Version = request.Browser.MajorVersion.ToString();
            }
            this.Browser = request.Browser;
            this.Platform = request.Browser.Platform;
            this.IsMobileDevice = request.Browser.IsMobileDevice;
            if (IsMobileDevice)
            {
                this.Name = request.Browser.Browser;
            }
        }
    }


}


void context_EndRequest(object sender, System.EventArgs e)
{
    if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
    {
        System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;

        try
        {
            // response.Headers["P3P"] = "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"":
            // response.Headers.Set("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
            // response.AddHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
            response.AppendHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");

            // response.AppendHeader("X-Frame-Options", "DENY");
            // response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
            // response.AppendHeader("X-Frame-Options", "AllowAll");

            if (System.Web.HttpContext.Current.Request.UrlReferrer != null)
            {
                // "X-Frame-Options": "ALLOW-FROM " Not recognized in Chrome 
                string host = System.Web.HttpContext.Current.Request.UrlReferrer.Scheme + System.Uri.SchemeDelimiter
                            + System.Web.HttpContext.Current.Request.UrlReferrer.Authority
                ;

                string selfAuth = System.Web.HttpContext.Current.Request.Url.Authority;
                string refAuth = System.Web.HttpContext.Current.Request.UrlReferrer.Authority;

                // SQL.Log(System.Web.HttpContext.Current.Request.RawUrl, System.Web.HttpContext.Current.Request.UrlReferrer.OriginalString, refAuth);

                if (IsHostAllowed(refAuth))
                {
                    BrowserInfo bi = new BrowserInfo(System.Web.HttpContext.Current.Request);

                    // bi.Name = Firefox
                    // bi.Name = InternetExplorer
                    // bi.Name = Chrome

                    // Chrome wants entire path... 
                    if (!System.StringComparer.OrdinalIgnoreCase.Equals(bi.Name, "Chrome"))
                        response.AppendHeader("X-Frame-Options", "ALLOW-FROM " + host);    

                    // unsafe-eval: invalid JSON https://github.com/keen/keen-js/issues/394
                    // unsafe-inline: styles
                    // data: url(data:image/png:...)

                    // https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
                    // https://www.ietf.org/rfc/rfc7034.txt
                    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
                    // https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

                    // /programming/10205192/x-frame-options-allow-from-multiple-domains
                    // https://content-security-policy.com/
                    // http://rehansaeed.com/content-security-policy-for-asp-net-mvc/

                    // This is for Chrome:
                    // response.AppendHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: *.msecnd.net vortex.data.microsoft.com " + selfAuth + " " + refAuth);


                    System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();
                    ls.Add("default-src");
                    ls.Add("'self'");
                    ls.Add("'unsafe-inline'");
                    ls.Add("'unsafe-eval'");
                    ls.Add("data:");

                    // http://az416426.vo.msecnd.net/scripts/a/ai.0.js

                    // ls.Add("*.msecnd.net");
                    // ls.Add("vortex.data.microsoft.com");

                    ls.Add(selfAuth);
                    ls.Add(refAuth);

                    string contentSecurityPolicy = string.Join(" ", ls.ToArray());
                    response.AppendHeader("Content-Security-Policy", contentSecurityPolicy);
                }
                else
                {
                    response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
                }

            }
            else
                response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
        }
        catch (System.Exception ex)
        {
            // WTF ? 
            System.Console.WriteLine(ex.Message); // Suppress warning
        }

    } // End if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)

} // End Using context_EndRequest


private static string[] s_allowedHosts = new string[] 
{
     "localhost:49533"
    ,"localhost:52257"
    ,"vmcompany1"
    ,"vmcompany2"
    ,"vmpostalservices"
    ,"example.com"
};


public static bool IsHostAllowed(string host)
{
    return Contains(s_allowedHosts, host);
} // End Function IsHostAllowed 


public static bool Contains(string[] allowed, string current)
{
    for (int i = 0; i < allowed.Length; ++i)
    {
        if (System.StringComparer.OrdinalIgnoreCase.Equals(allowed[i], current))
            return true;
    } // Next i 

    return false;
} // End Function Contains 

คุณต้องลงทะเบียนฟังก์ชัน context_EndRequest ในฟังก์ชัน HTTP-module Init

public class RequestLanguageChanger : System.Web.IHttpModule
{


    void System.Web.IHttpModule.Dispose()
    {
        // throw new NotImplementedException();
    }


    void System.Web.IHttpModule.Init(System.Web.HttpApplication context)
    {
        // /programming/441421/httpmodule-event-execution-order
        context.EndRequest += new System.EventHandler(context_EndRequest);
    }

    // context_EndRequest Code from above comes here


}

ถัดไปคุณต้องเพิ่มโมดูลลงในแอปพลิเคชันของคุณ คุณสามารถดำเนินการทางโปรแกรมได้ใน Global.asax โดยการแทนที่ฟังก์ชัน Init ของ HttpApplication ดังนี้:

namespace ChangeRequestLanguage
{


    public class Global : System.Web.HttpApplication
    {

        System.Web.IHttpModule mod = new libRequestLanguageChanger.RequestLanguageChanger();

        public override void Init()
        {
            mod.Init(this);
            base.Init();
        }



        protected void Application_Start(object sender, System.EventArgs e)
        {

        }

        protected void Session_Start(object sender, System.EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, System.EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, System.EventArgs e)
        {

        }

        protected void Application_Error(object sender, System.EventArgs e)
        {

        }

        protected void Session_End(object sender, System.EventArgs e)
        {

        }

        protected void Application_End(object sender, System.EventArgs e)
        {

        }


    }


}

หรือคุณสามารถเพิ่มรายการใน Web.config หากคุณไม่ได้เป็นเจ้าของซอร์สโค้ดของแอปพลิเคชัน:

      <httpModules>
        <add name="RequestLanguageChanger" type= "libRequestLanguageChanger.RequestLanguageChanger, libRequestLanguageChanger" />
      </httpModules>
    </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>

    <modules runAllManagedModulesForAllRequests="true">
      <add name="RequestLanguageChanger" type="libRequestLanguageChanger.RequestLanguageChanger, libRequestLanguageChanger" />
    </modules>
  </system.webServer>
</configuration>

รายการใน system.webServer ใช้สำหรับ IIS7 + อีกรายการใน system.web ใช้สำหรับ IIS 6
โปรดทราบว่าคุณต้องตั้งค่า runAllManagedModulesForAllRequests เป็น true เพื่อให้ทำงานได้อย่างถูกต้อง

"Namespace.Class, Assembly"สตริงในชนิดที่อยู่ในรูปแบบ โปรดทราบว่าถ้าคุณเขียนแอสเซมบลีของคุณใน VB.NET แทน C # VB จะสร้างเนมสเปซเริ่มต้นสำหรับแต่ละโปรเจ็กต์ดังนั้นสตริงของคุณจะมีลักษณะดังนี้

"[DefaultNameSpace.Namespace].Class, Assembly"

หากคุณต้องการหลีกเลี่ยงปัญหานี้ให้เขียน DLL ใน C #


ฉันคิดว่าคุณอาจต้องการลบ 'vmswisslife' และ 'vmraiffeisen' ออกจากคำตอบเพื่อที่จะไม่ได้รับความสัมพันธ์ที่ผิดพลาด
quetzalcoatl

@quetzalcoatl: ฉันปล่อยพวกเขาไว้ที่นั่นเป็นตัวอย่างไม่ใช่การกำกับดูแล แต่ก็ไม่ได้เป็นความลับ แต่อย่างใด แต่จริงอาจจะดีกว่าลบออก เสร็จแล้ว
Stefan Steiger

7

วิธีการเกี่ยวกับวิธีการที่ไม่เพียง แต่อนุญาตหลายโดเมน แต่ยังอนุญาตโดเมนแบบไดนามิก

กรณีการใช้งานที่นี่เป็นส่วนของแอป Sharepoint ซึ่งโหลดไซต์ของเราภายใน Sharepoint ผ่าน iframe ปัญหาคือแชร์พอยต์มีโดเมนย่อยแบบไดนามิกเช่นhttps://yoursite.sharepoint.com https://yoursite.sharepoint.comดังนั้นสำหรับ IE เราต้องระบุ ALLOW-FROM https: //.sharepoint.com

ธุรกิจที่ยุ่งยาก แต่เราสามารถทำให้สำเร็จได้โดยรู้ข้อเท็จจริงสองประการ:

  1. เมื่อโหลด iframe จะตรวจสอบความถูกต้องของ X-Frame-Options ในคำขอแรกเท่านั้น เมื่อโหลด iframe แล้วคุณสามารถนำทางภายใน iframe และส่วนหัวจะไม่ถูกตรวจสอบในคำขอที่ตามมา

  2. นอกจากนี้เมื่อโหลด iframe ตัวอ้างอิง HTTP คือ URL หลักของ iframe

คุณสามารถใช้ประโยชน์จากฝั่งเซิร์ฟเวอร์ข้อเท็จจริงทั้งสองนี้ได้ ในทับทิมฉันใช้รหัสต่อไปนี้:

  uri = URI.parse(request.referer)
  if uri.host.match(/\.sharepoint\.com$/)
    url = "https://#{uri.host}"
    response.headers['X-Frame-Options'] = "ALLOW-FROM #{url}"
  end

ที่นี่เราสามารถอนุญาตโดเมนตามโดเมนแม่แบบไดนามิก ในกรณีนี้เราตรวจสอบให้แน่ใจว่าโฮสต์ลงท้ายด้วย sharepoint.com ทำให้ไซต์ของเราปลอดภัยจากการคลิกแจ็ค

ฉันชอบที่จะรับฟังความคิดเห็นเกี่ยวกับแนวทางนี้


2
ข้อควรระวัง: สิ่งนี้จะแตกหากโฮสต์คือ "fakesharepoint.com" regex ควรจะเป็น:/\.sharepoint\.com$/
nitsas

@StefanSteiger ถูกต้อง แต่ Chrome ก็ไม่พบปัญหานี้เช่นกัน Chrome และเบราว์เซอร์ที่เข้ากันได้กับมาตรฐานอื่น ๆ จะเป็นไปตามรูปแบบนโยบายความปลอดภัยของเนื้อหา (CSP) ที่ใหม่กว่า
Peter P.

4

ตามข้อกำหนดของ MDN ,X-Frame-Options: ALLOW-FROMไม่ได้รับการสนับสนุนใน Chrome และการสนับสนุนเป็นที่รู้จักในขอบและ Opera

Content-Security-Policy: frame-ancestorsแทนที่X-Frame-Options(ตามข้อกำหนด W3 นี้ ) แต่frame-ancestorsมีความเข้ากันได้ จำกัด ตามข้อกำหนด MDNเหล่านี้ไม่รองรับใน IE หรือ Edge


1

RFC สำหรับHTTP Header Field X-Frame-Optionsระบุว่าฟิลด์ "ALLOW-FROM" ในค่าส่วนหัว X-Frame-Options สามารถมีได้เพียงโดเมนเดียว ไม่อนุญาตให้ใช้หลายโดเมน

RFC แนะนำวิธีแก้ไขปัญหานี้ วิธีแก้ไขคือระบุชื่อโดเมนเป็นพารามิเตอร์ url ใน iframe src url เซิร์ฟเวอร์ที่โฮสต์ url iframe src สามารถตรวจสอบชื่อโดเมนที่กำหนดในพารามิเตอร์ url หากชื่อโดเมนตรงกับรายชื่อโดเมนที่ถูกต้องเซิร์ฟเวอร์จะสามารถส่งส่วนหัว X-Frame-Options ที่มีค่า: "ALLOW-FROM domain-name" โดยที่ชื่อโดเมนคือชื่อของโดเมนที่พยายามจะ ฝังเนื้อหาระยะไกล หากไม่ได้ระบุชื่อโดเมนหรือไม่ถูกต้องคุณสามารถส่งส่วนหัว X-Frame-Options ด้วยค่า: "ปฏิเสธ"


1

พูดไม่ได้อย่างเคร่งครัดคุณทำไม่ได้

แต่คุณสามารถระบุX-Frame-Options: mysite.comและดังนั้นจึงอนุญาตให้มีและsubdomain1.mysite.com subdomain2.mysite.comแต่ใช่นั่นยังคงเป็นโดเมนเดียว มีวิธีแก้ปัญหาบางอย่างสำหรับสิ่งนี้ แต่ฉันคิดว่ามันง่ายที่สุดที่จะอ่านตรงข้อกำหนดของ RFC: https://tools.ietf.org/html/rfc7034

นอกจากนี้ยังควรชี้ให้เห็นว่าframe-ancestorคำสั่งของส่วนหัว Content-Security-Policy (CSP) ล้าสมัย X-Frame-Options อ่านเพิ่มเติมได้ที่นี่


0

ไม่เหมือนกันทุกประการ แต่สามารถใช้ได้ในบางกรณี: มีอีกทางเลือกหนึ่งALLOWALLที่จะลบข้อ จำกัด ได้อย่างมีประสิทธิภาพซึ่งอาจเป็นสิ่งที่ดีสำหรับสภาพแวดล้อมการทดสอบ / ก่อนการผลิต


ไม่มีเอกสารนี้ใน MDN
andig

0

ฉันต้องเพิ่ม X-Frame-Options สำหรับ IE และ Content-Security-Policy สำหรับเบราว์เซอร์อื่น ๆ ดังนั้นฉันจึงทำบางสิ่งดังต่อไปนี้

if allowed_domains.present?
  request_host = URI.parse(request.referer)
  _domain = allowed_domains.split(" ").include?(request_host.host) ? "#{request_host.scheme}://#{request_host.host}" : app_host
  response.headers['Content-Security-Policy'] = "frame-ancestors #{_domain}"
  response.headers['X-Frame-Options'] = "ALLOW-FROM #{_domain}"
else
  response.headers.except! 'X-Frame-Options'
end

-4

วิธีแก้ปัญหาที่เป็นไปได้อย่างหนึ่งคือการใช้สคริปต์ "frame-breaker" ตามที่อธิบายไว้ที่นี่

คุณเพียงแค่ต้องแก้ไขคำสั่ง "if" เพื่อตรวจสอบโดเมนที่คุณอนุญาต

   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       //your domain check goes here
       if(top.location.host != "allowed.domain1.com" && top.location.host == "allowed.domain2.com")
         top.location = self.location;
   }

ฉันคิดว่าวิธีแก้ปัญหานี้จะปลอดภัย เนื่องจากไม่ได้เปิดใช้งานจาวาสคริปต์คุณจะไม่มีข้อกังวลด้านความปลอดภัยเกี่ยวกับเว็บไซต์ที่เป็นอันตรายซึ่งจัดกรอบหน้าเว็บ


1
วิธีนี้ใช้ไม่ได้เนื่องจากนโยบายต้นทางเดียวกันเมื่อโทรไปที่ top.location
Eric R.

-8

ใช่. วิธีนี้อนุญาตหลายโดเมน

VB.NET

response.headers.add("X-Frame-Options", "ALLOW-FROM " & request.urlreferer.tostring())

9
ดูเหมือนว่าจะเอาชนะจุดประสงค์ของ X-Frame-Options เนื่องจากอนุญาตให้ไซต์ใด ๆ จัดเฟรมได้
Andrey Shchekin

5
คำตอบนี้ดูเหมือนจะเป็นฐานที่ดีในการแก้ปัญหา แต่ต้องใช้ตรรกะเพิ่มเติมเพื่อให้รันโค้ดนี้ได้ก็ต่อเมื่อ request.urlreferer.tostring () เป็นหนึ่งในต้นกำเนิดที่คุณต้องการอนุญาต
Zergleb

หากคุณกำลังทำเช่นนี้ทำไมคุณถึงแม้จะใช้ X-Frame ตัวเลือกส่วนหัว ... เพียงแค่ไม่สนใจมัน
vs4vijay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.