Search code examples
node.jsiframeproxyhttp-headerssquid

I need to remove or ignore the X-Frame-Options header. Should I use a proxy?


Premise

I need a way to remove the X-Frame-Options header from the responses from a few websites before those responses reach my browser.

I am doing this so that I can properly render my custom kiosk webpage, which has iframes that point to websites that don't want to show up in frames.

What I have tried

I have tried setting up a proxy using squid and configuring its reply_header_access option to deny X-Frame-Options headers as the server receives them, but that is for some reason not working as anticipated. I have verified that I am indeed going through the Squid proxy, and I have verified that the X-Frame-Options header persists despite my squid.conf file containing the following:

reply_header_access X-Frame-Options deny all

and having built squid (using Homebrew on my Mac) with the --enable-http-violations option.

Having chased down a lot of what might have gone wrong with this approach, I have decided that the reply_header_access option must not do exactly what I thought it does (modify headers before returning them to the client).

So, I tried using another proxy server. After reading a Stack Overflow question asking about a situation roughly similar to mine, I decided I might try using the node-http-proxy library. However, I have never used Node before, so I got lost pretty quickly and am stuck at a point where I am not sure how to implement the library for my specific purpose.

Question

Using Node seems like a potentially very easy solution, so how can I set up a proxy using Node that removes the X-Frame-Options header from responses?

Alternatively, why is Squid not removing the header even though I tried to set it up to do so?

Final alternative: Is there an easier way to reach my ultimate goal of rendering any page I want within an iframe?


Solution

  • I used a proxy, specifically mitmproxy with the following script:

    drop_unwanted_headers.py:

    import mitmproxy
    
    def requestheaders(flow: mitmproxy.http.HTTPFlow) -> None:
        for each_key in flow.request.headers:
            if each_key.casefold().startswith("sec-".casefold()):
                flow.request.headers.pop(each_key)
    
    def responseheaders(flow: mitmproxy.http.HTTPFlow) -> None:
        if "x-frame-options" in flow.response.headers:
            flow.response.headers.pop("x-frame-options")
        if "content-security-policy" in flow.response.headers:
            flow.response.headers.pop("content-security-policy")
    

    To run it, do: mitmproxy --script drop_unwanted_headers.py

    Also ensure that your proxy settings point to the computer where the proxy server is running (maybe localhost) and the correct port is used.