Allow a page to only load in an iframe

17,738

Solution 1

You wouldn't use PHP for that. Try javascript.

if(window==window.top) {
    // not in an iframe
}

Solution 2

Supposing that you have file file1.php that have an iframe within and this iframe point to file2.php

code supposed for the file file1.php:

<iframe src="file2.php" width="500" height="100"></iframe>

content of the file file2.php:

<?php
echo "This file exist in an iframe";
?>

So let update the file1.php to the following code :

<?php
session_start();
$_SESSION['iframe'] = md5(time()."random sentence");
?>
<iframe src="file2.php?internal=<?php echo $_SESSION['iframe'];?>" width="500" height="100"></iframe>

and also update the file2.php as following :

<?php
session_start();
if(!isset($_SESSION['iframe']) || !isset($_GET['internal']) || $_SESSION['iframe'] != $_GET['internal'])
    {
        die("This page can be accessed just from within an iframe");
    }
unset($_SESSION['iframe']);
//Continue processing using your own script
?>

Try this and tell me if this works or not :)

Solution 3

I know this topic is old, but I was searching for a way to do this myself.

So perhaps others in the future will find this post seeking a pure php method of forcing a page to only load inside an iframe.

My solution is as follows:

If you control both pages (the one calling the iframe and the one loaded inside the iframe) it can be done.

First verify the referring page. If the referring page is not correct, kill the page.

$referal_page = $_SERVER['HTTP_REFERER'];
if ($referal_page != $_SERVER['REQUEST_SCHEME']."://".$_SERVER['HTTP_HOST'].'/main/page/loading/iframe.php') {
    die;
}

As anyone can also spoof the HTTP_REFERER this is not an end all solution. So I use a load key that is stored in the database for each user of my site. On the page being iframed:

if (isset($_GET['key1'])) {
    $key1 = strip_tags($_GET['key1']);
    $stmt = $db->prepare('SELECT user_key FROM page_keys WHERE username = :username');
    $stmt->bindParam(':username', $username);
    $stmt->execute();
    $userkey = $stmt->fetchColumn();
    if ($userkey == $key1) {
        $bytes = random_bytes(12); //random. Increase input for more bytes
        $key2 = bin2hex($bytes);
        $stmt = $db->prepare('UPDATE page_keys SET user_key=:key WHERE username = :username');
        $stmt->bindParam(':username', $username);
        $stmt->bindParam(':key', $key2);
        $stmt->execute();
    } else {
        die;
    }
} else {
    die;
}

On the page that loads the iframe:

$stmt = $db->prepare('SELECT count(id) AS key_check FROM page_keys WHERE username = :username');
$stmt->bindParam(':username', $username);
$stmt->execute();
$key_check = $stmt->fetchColumn();
if ($key_check == 0) {
    $bytes = random_bytes(12); //random. Increase input for more bytes
    $userkey = bin2hex($bytes);
    $stmt = $db->prepare('INSERT into page_keys (username, user_key) VALUES (:username, :user_key)');
    $stmt->bindParam(':username', $username);
    $stmt->bindParam(':user_key', $userkey);
    $stmt->execute();
} else {
    $stmt = $db->prepare('SELECT user_key FROM page_keys WHERE username = :username');
    $stmt->bindParam(':username', $username);
    $stmt->execute();
    $userkey = $stmt->fetchColumn();
}

Finally on the iframe itself:

<iframe id="page" src="the_page.php?key1=<?php echo $userkey;?>">

One could also use header redirects to the page loading the iframe instead of die;

The reason not to do this with javascript, is a user can still disable javascript and load the page causing any php on the page to still be run.

Share:
17,738
hamid
Author by

hamid

Updated on June 14, 2022

Comments

  • hamid
    hamid almost 2 years

    How can I allow my PHP file to only load in an iframe?

    For example:

    • Prevent direct access: example.com/Loader.php
    • Allow iframe access: <iframe name="TEST" src="Example.com/Loader.php"></iframe>