วิธีป้องกันไม่ให้ IFRAME เปลี่ยนเส้นทางหน้าต่างระดับบนสุด


135

บางเว็บไซต์มีรหัสที่จะ "หยุดออก" ของIFRAMEเปลือกซึ่งหมายความว่าถ้าหน้าAจะโหลดเป็นIFRAMEภายในเพจPบางจาวาสคริปต์ในการเปลี่ยนเส้นทางหน้าต่างนอกAA

โดยทั่วไป Javascript นี้จะมีลักษณะดังนี้:

<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;
</script>

คำถามของฉันคือในฐานะผู้เขียนเพจหลักPและไม่ได้เป็นผู้เขียนเพจด้านในAฉันจะป้องกันไม่ให้Aทำการแบ่งออกได้อย่างไร

ปล. สำหรับฉันแล้วดูเหมือนว่ามันควรจะเป็นการละเมิดความปลอดภัยข้ามไซต์ แต่ก็ไม่ใช่


ฉันไม่คิดว่าคุณจะทำอะไรได้มากเลย ... ถ้าคุณไม่ใช่คนเขียนเนื้อหาเฟรม
scunliffe

คำตอบ:


43

ลองใช้คุณสมบัติ onbeforeunload ซึ่งจะให้ผู้ใช้เลือกว่าต้องการออกจากหน้าหรือไม่

ตัวอย่าง: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

ใน HTML5 คุณสามารถใช้คุณสมบัติ sandbox โปรดดูคำตอบของ Pankrat ด้านล่าง http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/


1
iFrames ทำpostMessageช่วยให้การสื่อสารข้ามโดเมนแม้ว่าการใช้ นี่ไม่ใช่ความเสี่ยงด้านความปลอดภัย แต่อาจมีบางคนอยากรู้ว่าความสามารถนี้มีอยู่จริงเมื่อเห็นความคิดเห็นของคุณ :)
coreyward

ไม่สามารถทำได้ในขณะที่เขียนคำตอบนี้ ขอบคุณที่ชี้ให้ดู
fasih.rana

@SirDarius คุณช่วยแสดงตัวอย่างได้ไหมชื่นชมมาก
user198989

ผู้ใช้จะไม่ทราบว่าเหตุใดการยืนยันนี้จึงปรากฏขึ้นและอาจเลือกตอบกลับแบบสุ่ม ฉันไม่แนะนำให้ใช้มัน มีวิธีแก้ปัญหาอื่น ๆ - sandbox.
oriadam

1
@ fasih.rana บทความที่สองช่วยฉันได้มาก ขอบคุณครับ;)
MrD

127

ด้วย HTML5 คุณลักษณะiframe sandboxถูกเพิ่มเข้ามา ในขณะที่เขียนสิ่งนี้ใช้งานได้บน Chrome, Safari, Firefox และ IE และ Opera เวอร์ชันล่าสุดแต่ทำได้ในสิ่งที่คุณต้องการ:

<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

หากคุณต้องการที่จะช่วยให้sandbox="allow-top-navigation"การเปลี่ยนเส้นทางระดับบนสุดระบุ


รออะไร? พวกเขาปล่อยให้คุณทำเช่นนี้? ฉันคิดว่าถ้าเว็บไซต์ต้องการแยกออกเบราว์เซอร์ทั้งหมดก็ยอม ผู้คนควรจะป้องกันไม่ให้เว็บไซต์ของตนหลุดจาก iframe ได้อย่างไร? ฉันไม่บ่นหรอกน่ากลัว
Farzher

3
นี่คือยาแก้พิษ: blogs.msdn.com/b/ieinternals/archive/2010/03/30/…
ปานรัตน์

1
@StephenSarcsamKamenar หากคุณต้องการป้องกันไม่ให้ไซต์ของคุณแสดงใน iframe จะมีส่วนหัวX-Frame-Optionsพร้อมค่าSAMEORIGIN เบราว์เซอร์สมัยใหม่ส่วนใหญ่จะไม่แสดงไซต์ใน iframe ด้วยส่วนหัวนี้
Grzegorz

4
น่าเสียดายที่sandboxไม่อนุญาตให้ใช้ Flash หรือวัตถุประเภทอื่นในเฟรมแซนด์บ็อกซ์ทำให้sandboxคุณลักษณะนี้ไม่มีประโยชน์ในหลาย ๆ กรณี
oriadam

1
เว็บไซต์ไม่ควร "แยก" เพื่อประท้วงการรวมอยู่ใน iframe พวกเขาสามารถแสดงข้อความหรือว่างเปล่า น่าเสียดายที่การอนุญาตให้สคริปต์ทำงานใน iframe ยังคงเปิดโอกาสให้คุณได้รับ iframe ที่หลอกลวงซึ่งทำในขณะที่ (1) {} และลูปแบบไม่สิ้นสุด ฉันหวังว่าแต่ละ iframe จะมีเธรดของตัวเอง
Gregory Magarshak

51

ฉันใช้ sandbox = "... "

  • อนุญาตให้ส่งแบบฟอร์ม
  • อนุญาตป๊อปอัปอนุญาตให้ป๊อปอัป
  • allow-pointer-lock ช่วยให้สามารถล็อคตัวชี้ได้
  • allow-same-origin อนุญาตให้เอกสารรักษาต้นทาง
  • allow-scripts อนุญาตให้เรียกใช้ JavaScript และยังช่วยให้คุณสมบัติต่างๆเรียกใช้โดยอัตโนมัติ
  • allow-top-navigation ทำให้เอกสารสามารถแยกออกจากกรอบได้โดยไปที่หน้าต่างระดับบนสุด

การนำทางยอดนิยมคือสิ่งที่คุณต้องการป้องกันดังนั้นอย่าปล่อยให้เป็นเช่นนั้นและจะไม่ได้รับอนุญาต สิ่งที่เหลืออยู่จะถูกปิดกั้น

เช่น

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>

3
โปรดทราบว่า Flash (และวัตถุอื่น ๆ ) จะถูกบล็อกด้วยโดยไม่มีตัวเลือกในการอนุญาต "คุณลักษณะความปลอดภัย" นี้ป้องกันไม่ให้ฉันใช้แซนด์บ็อกซ์ร่วมกัน
oriadam

9

หลังจากที่ได้อ่านw3.org ข้อมูลจำเพาะ ฉันพบคุณสมบัติแซนด์บ็อกซ์

คุณสามารถตั้งค่าsandbox=""ซึ่งป้องกันไม่ให้ iframe เปลี่ยนเส้นทาง ที่ถูกกล่าวว่าจะไม่เปลี่ยนเส้นทาง iframe ด้วย คุณจะสูญเสียการคลิกเป็นหลัก

ตัวอย่างที่นี่: http://jsfiddle.net/ppkzS/1/
ตัวอย่างที่ไม่มี Sandbox: http://jsfiddle.net/ppkzS/


5

ฉันรู้ว่ามันเป็นคำถามมานานแล้ว แต่นี่คือเวอร์ชันที่ปรับปรุงแล้วของฉันซึ่งจะรอ 500ms สำหรับการโทรครั้งต่อไปเมื่อโหลด iframe เท่านั้น

<script type="text/javasript">
var prevent_bust = false ;
    var from_loading_204 = false;
    var frame_loading = false;
    var prevent_bust_timer = 0;
    var  primer = true;
    window.onbeforeunload = function(event) {
        prevent_bust = !from_loading_204 && frame_loading;
        if(from_loading_204)from_loading_204 = false;
        if(prevent_bust){
            prevent_bust_timer=500;
        }
    }
    function frameLoad(){
        if(!primer){
            from_loading_204 = true;
            window.top.location = '/?204';
            prevent_bust = false;
            frame_loading = true;
            prevent_bust_timer=1000;
        }else{
            primer = false;
        }
    }
    setInterval(function() {  
        if (prevent_bust_timer>0) {  
            if(prevent_bust){
                from_loading_204 = true;
                window.top.location = '/?204';
                prevent_bust = false;
            }else if(prevent_bust_timer == 1){
                frame_loading = false;
                prevent_bust = false;
                from_loading_204 = false;
                prevent_bust_timer == 0;
            }



        }
        prevent_bust_timer--;
        if(prevent_bust_timer==-100) {
            prevent_bust_timer = 0;
        }
    }, 1);
</script>

และonload="frameLoad()"และ onreadystatechange="frameLoad();"ต้องเพิ่มลงในเฟรมหรือ iframe


3

2

เนื่องจากหน้าที่คุณโหลดภายใน iframe สามารถรันโค้ด "break out" ด้วย setInterval ได้ดังนั้น onbeforeunload จึงอาจไม่สามารถใช้งานได้จริงเนื่องจากอาจทำให้ผู้ใช้ไม่พอใจด้วย "คุณแน่ใจหรือไม่ว่าต้องการออก" ไดอะล็อก

นอกจากนี้ยังมีแอตทริบิวต์ความปลอดภัย iframe ซึ่งใช้งานได้กับ IE & Opera เท่านั้น

:(


2

ในกรณีของฉันฉันต้องการให้ผู้ใช้ไปที่หน้าด้านในเพื่อให้เซิร์ฟเวอร์เห็น ip ของพวกเขาในฐานะผู้เยี่ยมชม หากฉันใช้เทคนิค php proxy ฉันคิดว่าหน้าภายในจะเห็นเซิร์ฟเวอร์ ip ของฉันในฐานะผู้เยี่ยมชมดังนั้นจึงไม่ดี ทางออกเดียวที่ฉันได้รับจนถึงตอนนี้คือก่อนที่จะโหลด วางสิ่งนี้ไว้ในเพจของคุณ:

<script type="text/javascript">
    window.onbeforeunload = function () {                       
         return "This will end your session";
    }
</script>

สิ่งนี้ใช้ได้ทั้งใน firefox และนั่นคือสิ่งที่ฉันทดสอบ คุณจะพบเวอร์ชันที่ใช้บางอย่างเช่น evt.return (อะไรก็ได้) อึ ... ที่ใช้ไม่ได้ใน firefox


0

ด้วยการทำเช่นนี้คุณจะสามารถควบคุมการกระทำใด ๆ ของหน้าที่ถูกเฟรมซึ่งคุณไม่สามารถทำได้ ใช้นโยบายต้นทางโดเมนเดียวกัน


20
ฉันไม่ได้ขอให้ควบคุมสิ่งที่อยู่ใน IFRAME ฉันขอให้ป้องกันไม่ให้สิ่งที่อยู่ใน IFRAME ควบคุมฉัน
Jason Cohen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.