Asked  7 Months ago    Answers:  5   Viewed   36 times

How can I find out that my page is embedded as a frame to other site during page loading? I guess referrer request header can't help me here? Thanks.

 Answers

27

You cannot check it from the server's side, but you can use javascript to detect it after the page has loaded. Compare top and self, if they're not identical, you are in a frame.

Additionally, some modern browsers respect the X-FRAME-OPTIONS header, that can have two values:

  • DENY – prevents the page from being rendered if it is contained in a frame
  • SAMEORIGIN – same as above, unless the page belongs to the same domain as the top-level frameset holder.

Users include Google's Picasa, that cannot be embedded in a frame.

Browsers that support the header, with the minimum version:

  • IE8 and IE9
  • Opera 10.50
  • Safari 4
  • Chrome 4.1.249.1042
  • Firefox 3.6.9 (older versions with NoScript)
Wednesday, March 31, 2021
 
laurent
answered 7 Months ago
92

A first solution is to use X-Frame-Options header to prevent loading your page to an iframe. X-Frame-Options can specify one of two values: SAMEORIGIN, which only allows iframes from the same origin to display this content, and deny, which prevents any iframe from doing so. BUT this header is not part of HTTP specification and was introduced by Microsoft, so not all browsers support this header. An example of X-Frame-Options:

X-Frame-Options: SAMEORIGIN

In case some old browsers don't support the X-Frame-Options header. You could try a technique called FrameKiller. There are limitations, though, as pointed out in that link.

The user agent does not support JavaScript.

The user agent supports JavaScript but the user has turned support off.

The user agent's JavaScript support is flawed or partially implemented.

The idea is to use javascript to detect whether your page is loaded into an iframe. There are many ways to implement a frame killer script.

For your requirement, you could implement a frame killer script like this: try to access your parent window to read the window.location. If they include your page inside their iframe, the code would throw exception (cross-domain)

Example code:

window.onload = function(){
   try
   {
       if (window.parent && window.parent.location.hostname !== "www.abc.com"){
          throw new Error();
       }
   }
   catch (e){
      alert("Please visit www.abc.com to play this game.");
      //You could do whatever you want here
   }
}
Wednesday, March 31, 2021
 
Alix
answered 7 Months ago
12

This is an interesting question. There shouldn't be any reason for it to be a problem, but you should take a few things into account:

  1. The headers need to be unique to your application. Not just now, but forever. You should ensure you're prefixing them, e.g. X-MyApplication-Foo: Bar. Not doing this might cause conflicts in future.

  2. Firewalls are sometimes (rarely) a little overzealous with filtering unknown HTTP headers. This shouldn't be a problem, but it's something to keep in mind.

  3. Older browsers have smaller limitations on header field sizes than modern browsers, so you need to test across as many as you can get hold of.

Is there are reason you can't use the standard HTTP error codes? I understand that you might want to provide stack traces or other useful debugging information, but in the case of an error, wouldn't you just return a JSON blob that contains the error information, rather than the normal "result" JSON data? You could easily detect the difference based on the HTTP error code and handle the two cases differently.

The reason I'm concerned by your suggested approach is that headers are used to alter or cause browser behaviour - they're not intended to be a data storage mechanism.

Pseudo-code example:

switch(httpResponseCode)
{
    case 200:
        parseResult(json);
        break;
    case 403:
        parseForbidden(json);
        break;
    case 500:
        parseServerError(json);
        break;
    default:
        // bad response code, handle appropriately
}
Saturday, May 29, 2021
 
revive
answered 5 Months ago
45

You should remove quotes on assignment of postMessage in your:

postMessage = {"Info": {"ID": 1, "IP": "192.168.1.1"}}

And change your php code to:

<?php
$data = file_get_contents("php://input");
header('Content-type:application/json;charset=utf-8');
echo json_encode($data);
?>
Saturday, May 29, 2021
 
MDDY
answered 5 Months ago
96

The most compatible way to do this would be to create a user Profile model that includes a foreign key to the Site model, then write a custom auth backend that checks the current site against the value of that FK. Some sample code:

Define your profile model, let's say in app/models.py:

from django.db import models
from django.contrib.sites.models import Site
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    site = models.ForeignKey(Site)

Write your custom auth backend, inheriting from the default one, let's say in app/auth_backend.py:

from django.contrib.auth.backends import ModelBackend
from django.contrib.sites.models import Site

class SiteBackend(ModelBackend):
    def authenticate(self, **credentials):
        user_or_none = super(SiteBackend, self).authenticate(**credentials)
        if user_or_none and user_or_none.userprofile.site != Site.objects.get_current():
            user_or_none = None
        return user_or_none

    def get_user(self, user_id):
        try:
            return User.objects.get(
                pk=user_id, userprofile__site=Site.objects.get_current())
        except User.DoesNotExist:
            return None

This auth backend assumes all users have a profile; you'd need to make sure that your user creation/registration process always creates one.

The overridden authenticate method ensures that a user can only login on the correct site. The get_user method is called on every request to fetch the user from the database based on the stored authentication information in the user's session; our override ensures that a user can't login on site A and then use that same session cookie to gain unauthorized access to site B. (Thanks to Jan Wrobel for pointing out the need to handle the latter case.)

Sunday, July 11, 2021
 
Classified
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share