0

Sorry in advance if this is a bit lengthy - but I have dived quite a bit into it, so I want to provide what I know :-)

I have a solution (developed in IBM XPages) that we provide for customers e.g. via an iframe. We have now started seeing issues where the iframe does not load the content. This happens on Safari and Chrome in a private session. The reason is this little Javascript is injected into the header of the iframe'd page:

<head>
<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="http://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open\u0026assoc=49F1767931B31CD0C1258398007953C0\u0026type=1\u0026SessionID=77610D163AE659EC8C2C63FAF5E8BBA05E8C120D";
</script>
</head>

The iframe it self looks like this:

<iframe src="https://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&amp;assoc=02F2DD0AA9133BDCC1258618004A6B48&amp;type=1" width="100%" height="2100"></iframe>

As you can see there is a discrepancy in the iframe link and the one in the Javascript (which uses http instead https).

In the browser's console I see this message:

[blocked] The page at https://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&assoc=49F1767931B31CD0C1258398007953C0&type=1 was not allowed to display insecure content from http://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&assoc=49F1767931B31CD0C1258398007953C0&type=1&SessionID=9C21D5AF363C262E3CC37D0CDFBDFBCB35528ECC.

Which obviously is a fair reason.

But what is adding the "wrong" content - and how could I solve this?

Our test system is not 100% equal to our production system. The Nginx in production is on the same server (different server in test) and in test we use LetsEncrypt for SSL - but in production we get the cert. from the hosting center. We have ssl_session_cache set up in production only - and some other minor (I think) differences...

The config of the nginx server in production looks like this (with some details for other servers left out):

server {
        listen 443;
        server_name fangstjournalen.dtu.dk;
 
        client_max_body_size 25m;
 
        ssl on;
        ssl_certificate /etc/nginx/ssl/fangstjournalen.dtu.dk.pem;
        ssl_certificate_key /etc/nginx/ssl/fangstjournalen.dtu.dk.key;
        ssl_session_cache shared:le_nginx_SSL:1m;
        ssl_session_timeout 1440m;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "ECDHE-....";
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;

        # 2020.05.20/Jda - added Sync Gateway
        # Use a specific url pattern to identify sync requests - and remove that part before redirecting to the db server
        location /_sync {
              rewrite                 /_sync/(.*) /$1  break;
              proxy_pass              http://sync_gateway;
              :
              :
        }

        # 2019.11.04/Jda - Added keepalive_timeout, proxy_read_timeout: 600 --> 900
        # 2020.08.12/Jda - Added SameSite=none; Secure to cookies...
        location / {
                proxy_pass              http://fangstjournalen.dtu.dk:8088;
                proxy_redirect          off;
                proxy_buffering         off;
                proxy_http_version      1.1;
                keepalive_timeout       720s;
                proxy_read_timeout      900s;
                proxy_set_header        X-Forwarded-Port     8088;
                proxy_set_header        X-Forwarded-Host     $host;
                proxy_set_header        X-Forwarded-Server   $host;
                proxy_set_header        X-Real-IP            $remote_addr;
                proxy_set_header        Host                 $host;
                proxy_set_header        X-Forwarded-For      $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto    $scheme;
                proxy_set_header        $WSRA                $remote_addr;
                proxy_set_header        $WSRH                $remote_addr;
                proxy_set_header        $WSSN                $host;
                proxy_set_header        $WSIS                True;
                proxy_cookie_path       /                    "/; SameSite=none; Secure";
        }
}

Any ideas much appreciated!

Thanks in advance ;-)

/John

Edit: The link to the test page has been removed as that page has now been removed also :-)

John Dalsgaard
  • 2,797
  • 1
  • 14
  • 26

2 Answers2

2

You can try to use the sub_filter module to rewrite the content:

sub_filter_once on;
sub_filter_types text/html;
sub_filter '<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="http://' '<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="https://';
Per Henrik Lausten
  • 21,331
  • 3
  • 29
  • 76
  • You might also need proxy_set_header Accept-Encoding ""; The last line, but shorter: sub_filter 'http://fangstjournalen.dtu.dk' 'https://fangstjournalen.dtu.dk' – D.Bugger Dec 30 '20 at 09:09
  • 1
    Bingo! I also needed to add the 'proxy_set_header Accept-Encoding' suggested by D.Bugger - I had already tried to minimise the replacement string as there seemed to be some differences in how whitespace (spaces and/or line breaks) were shown in the source. But now it works perfectly well. Thanks gents!! – John Dalsgaard Dec 30 '20 at 09:33
  • ... and I guess the problem arose as the Domino server wanted to add the session to the request - and it is behind the Nginx that handles all SSL so it "doesn't know...". That was my understanding of it anyway ;-) – John Dalsgaard Dec 30 '20 at 09:35
  • did you check to change the URL from http://.... to //... -> which would imply: use whatever protocol the site was loaded before.Requires https configured everywhere – stwissel Jan 04 '21 at 17:35
  • @stwissel it’s Domino that auto inserts the code and not something that can be controlled, unfortunately. – Per Henrik Lausten Jan 04 '21 at 18:24
  • Exactly! @stwissel I actually do exactly that in all places I can get away with it. That also solves the issue where my local dev. server does not use TLS and the test/prod. servers do. - or if we refer to another server (e.g. with some services we use). So it is a very good practice - but as Per Henrik says, it cannot be changed here... – John Dalsgaard Jan 15 '21 at 17:58
0

I had the same issue. Using a decompiler, I found the place in the code this is added. You can set a property on ExternalContextEx to avoid the script tag being added.

I do this in a custom ViewHandler (overloading the createView-method) for my application, but you might be able to do it in the beforePageLoad-event for an XPage also.

In my code, I only override this if the SessionID-cookie is not set, in case it does something else that I'm not aware of. So far there haven't been any issues.

HttpServletRequest httpServletRequest = (HttpServletRequest) facesContext.getExternalContext().getRequest();
if( !httpServletRequest.isRequestedSessionIdFromCookie() ) {
    ExternalContextEx externalContext = (ExternalContextEx) facesContext.getExternalContext();
    externalContext.setDonotEncodeUrl( false );
}
Tommy Valand
  • 868
  • 6
  • 10