I successfully setup CSP on my flask app using Talisman, but the only item I haven't managed to get working is adding a nonce to the Google reCAPTCHA <style>
tag on my Contact form.
I've used the custom flask-wtf RECAPTCHA_HTML
Config option, and my rendered html now looks like this:
<script {{ csp_nonce() }} src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="aYSDvp4uev5dhAGsk6GbGRKEg7UFNmYc1JP9FSKf"></div>
How do I get Flask/Talisman/Flask-wtf to render the {{ csp_nonce() }}
so that my rendered html looks more like this:
<script nonce="RYcJMNtXC7nBC4iYECnzildNF6qBMnoT" src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="aYSDvp4uev5dhAGsk6GbGRKEg7UFNmYc1JP9FSKf"></div>
I've tried escaping the curly braces (ie. using \{\{
) and adding |safe
in the html template, but no luck there.
My actual template reads:
{{ form.recaptcha }}
Cheers.
Well, this one is pretty simple if you keep Flask's Contexts in mind. I simple inserted the CSP nonce from Talisman into the RECAPTCHA_HTML
within the route that loads my Contact form. But, I did have to put RECAPTCHA_HTML = ''
in my Config.
#!/usr/bin/env python3
'''webapp.links.routes'''
from flask import Blueprint, render_template, current_app
from webapp.routes.links.forms import ContactForm
from webapp import Config, talisman
links = Blueprint('links', __name__)
@links.route("/contact", methods=['GET', 'POST'])
def contact_route():
'''
Contact form
'''
## Construct HTML for Google reCAPTCHA with Talisman nonce
_RECAPTCHA_SRC = '"https://www.google.com/recaptcha/api.js"'
_RECAPTCHA_CLASS = 'g-recaptcha'
_RECAPTCHA_SNIPPET = 'data-sitekey="' + Config.RECAPTCHA_PUBLIC_KEY + '"'
_RECAPTCHA_HTML = '<script nonce="' + talisman._get_nonce() + \
'" src=' + _RECAPTCHA_SRC + ' async defer></script>' + \
'<div class="' + _RECAPTCHA_CLASS + '" ' + _RECAPTCHA_SNIPPET + '></div>'
current_app.config.update(RECAPTCHA_HTML = _RECAPTCHA_HTML)
form = ContactForm()
if form.validate_on_submit():
### Normal form validation/handling below here ....
This now renders the Google reCAPTCHA with the nonce in the tag in my HTML like this:
<script nonce="RfK9KoHnAipsTmRLFS5KmnaaYIV1we6b" src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="aYSDvp4uev5dhAGsk6GbGRKEg7UFNmYc1JP9FSKf"></div>
Hope this helps someone else in the future.