iFrame 'same-origin issue' with Load Balancer

I’m trying to re-route my bot’s traffic using load balancers but keep getting the 'refused to display … in a frame because it set ‘x-frame-options’ to ‘sameorigin’ which prevents the iframe from being loaded in.

This is the structure of my bot:


and this is the error I get:

I’ve changed the host in my html page to reflect this load balancer link

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>ChatBot</title> 
    <script src="http://internal-DEV1-ELBPLWS-LOADBALANCERKEYS.us-east-1.elb.amazonaws.com/assets/modules/channel-web/inject.js"></script>
</head>
  <!----------------------\/\/\/\/\/\/\/----BOTPRESS----\/\/\/\/\/\/\/------------------------------------------>
<body>
  <script>
    window.botpressWebChat.init({
      host: 'http://internal-DEV1-ELBPLWS-LOADBALANCERKEYS.us-east-1.elb.amazonaws.com',
      botId: 'Qbot',
      });
  </script>
  <script>
      window.addEventListener('message', function(event) {
    if (event.data.name === 'webchatOpened') {
      window.botpressWebChat.sendEvent({
        type: 'proactive-trigger',
        channel: 'web',
        payload: { text: 'fake message' }
      })
    }
  })
  </script>
</body>
</html>

Also changed the external url to reflect this load balancer

{
 "$schema": "../botpress.config.schema.json",
 "httpServer": {
   "host": "10.123.456.789",
   "port": 3000,
   "backlog": 0,
   "bodyLimit": "100kb",
   "cors": {
     "enabled": true,
   "ExternalUrl": "http://internal-DEV1-ELBPLWS-LOADBALANCERKEYS.us-east-1.elb.amazonaws.com/"

Any help on this? How can I get past this iframe issue whilst still directing traffic to my load balancers?

Hey @av_botpress !

I understand that your bot cannot be embedded in your web page, due to the webchat’s iframe refusing to load. This refusal to load is caused by the x-frame-options header set to sameorigin.

My hypothesis is this header is set by your Nginx reverse proxy. Could you share your Nginx config?

See Nginx configuration examples for the x-frame-options header here https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

Yes I know it’s due to the Nginx configuration that is set as ‘same-origin’ however, I cannot find a way around this which is what I need help with. Note: This NGINX config is used across all stacks that are connected to the portal

user nginx;
worker_processes auto;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for" '
                '$request_time $upstream_response_time $pipe';
    access_log  /var/log/nginx/access.log  main;
    error_log /var/log/nginx/error.log;
    root        /usr/share/nginx/html;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    underscores_in_headers on;
    keepalive_timeout   60s;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    # DISA STIGs
    client_header_timeout 10;
    add_header X-Frame-Options SAMEORIGIN;  <--------------------------------------
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    real_ip_header X-Forwarded-For;
    
    server {
    listen       10.123.456.78:80;
    # server_name  _;
    client_max_body_size 1025M;
    charset utf-8;
        
    # Force resolve DNS everytime
    set $backend "http://DevLayer.us-east-1.elb.amazonaws.com:8001 (changed for security reasons)";           
    set $frontend "portalwebsite (changed due to security reasons)";         
    location /prweb {
                # proxy_set_header X-Forwarded-Host     portalwebsite (changed for security reasons);
                # proxy_set_header X-Forwarded-Proto    https;
                # proxy_set_header X-Forwarded-Port     443;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_connect_timeout   600;
                proxy_read_timeout      600; 
                proxy_send_timeout      600;
                send_timeout            300;
                proxy_intercept_errors off;
                proxy_ignore_client_abort on;
                proxy_http_version 1.1;
                proxy_set_header Connection "";                       
                fastcgi_ignore_client_abort on;
                proxy_pass $backend;
                # proxy_redirect $backend $frontend;
            
        }
        location / {
                # proxy_set_header X-Forwarded-Host     portalwebsite (changed for security reasons);
                # proxy_set_header X-Forwarded-Proto    https;
                # proxy_set_header X-Forwarded-Port     443;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_connect_timeout   600;
                proxy_read_timeout      600;
                proxy_send_timeout      600;
                send_timeout            300;
                proxy_intercept_errors off;
                proxy_ignore_client_abort on;
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                fastcgi_ignore_client_abort on;
                                proxy_pass $backend;
                                # proxy_redirect $backend $frontend;
                }
        
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

Can you simply remove the add_header X-Frame-Options SAMEORIGIN; directive from the Nginx config?

Yeah that didn’t change anything. Still got the same error.

Fixed. I ran it the html page locally when I should’ve ran it from the same server that it was hosted on. Everything makes sense now.

1 Like

You cannot display a lot of websites inside an iFrame. Reason being that they send an “X-Frame-Options: SAMEORIGIN” response header. This option prevents the browser from displaying iFrames that are not hosted on the same domain as the parent page.

I faced the same error when displaying YouTube links. For example:

https://www.youtube.com/watch?v=8WkuChVeL0s

I replaced watch?v= with embed/ so the valid link will be:

https://www.youtube.com/embed/8WkuChVeL0s

It works well.

Try to apply the same rule on your case.