2

I am using Flask with Flask-Talisman. My CSP is configured currently, for all routes as:

SELF = '\'self\''
csp = {
    'default-src': [SELF, '*.gstatic.com'],
    'connect-src': [SELF, 'https://fonts.googleapis.com', 'https://cdnjs.cloudflare.com'],
    'frame-src': [SELF, 'https://js.stripe.com'],
    'script-src': [SELF, 'https://cdnjs.cloudflare.com', 'https://js.stripe.com', 'https://www.googletagmanager.com'],
    'style-src': [SELF, 'https://cdnjs.cloudflare.com', 'https://fonts.googleapis.com', '\'unsafe-inline\''],
    'img-src': [SELF, '*', 'blob:', 'data:']
}
talisman.init_app(app, content_security_policy=csp, content_security_policy_nonce_in=['script-src'])

Whenever an external site tries to load my pages via iframe they receive the error X-Frame-Options is SAMEORIGIN, which is generally OK.

However I would like a single route to be accessible by external iframes on load. To achieve this I have followed the advice to set:

@talisman(frame_options=ALLOW_FROM, frame_options_allow_from='*')

before my specific route.

However Chrome does not allow this and reports an error. I beleive instead the CSP should instead be set. How should I re-write or re-configure my route to allow it to be accessed by external iframes in all browsers?

Attack68
  • 4,437
  • 1
  • 20
  • 40

2 Answers2

1

Example on the flask-talisman route:

# Example of a route-specific talisman configuration

@app.route('/embeddable')
@talisman(

    frame_options='ALLOW-FROM',
    frame_options_allow_from='https://example.com/',

)

def embeddable():
    return "<html>I can be embedded.</html>"

https://github.com/GoogleCloudPlatform/flask-talisman/blob/master/example_app/main.py

J. Timm
  • 126
  • 4
  • I believe I can achieve this in my current setup replacing `'*'`, however Chrome does not allow `ALLOW FROM` so the solution is to affect `frame-ancestors` directly in the CSP set by talisman I think. i just dont know how to isolate it to a single route – Attack68 Sep 15 '19 at 14:29
  • I edited my answer after a made better research, give it a try, and let me know if it works for you. – J. Timm Sep 15 '19 at 14:52
  • Hi, thanks for the response, perhaps my post was poorly written - I can already do exactly what you have answered, and my question is related to firefox and chrome not permiiting `ALLOW FROM`. see here: https://stackoverflow.com/questions/10658435/x-frame-options-allow-from-in-firefox-and-chrome. I seek an alternative solution that involves editing the CSP for single routes. – Attack68 Sep 15 '19 at 15:47
  • @J.Timm can you please assist with a way to do this but for a whole flask blueprint? – Zaffer Feb 25 '22 at 10:05
1

The solution was to augment my csp directly on the route with a frame-ancestors header than takes precedence in some browsers (inc chrome).

# assume a csp dict exists
@talisman(frame_options=ALLOW_FROM,
          frame_options_allow_from='*',
          content_security_policy={**csp, 'frame-ancestors': ['*']})
def flask_route():
    # individualised route
Attack68
  • 4,437
  • 1
  • 20
  • 40