Safari has a built in XSS auditor that tries to prevent reflective XSS attacks – where the attacker submits content through a POST request and it is immediately displayed back in the response. To do this it looks for tags, including <script>
and <iframe>
, in the POST params. If it finds any, it looks in the response to see if they are being displayed. If they are, it considers this a security risk and prevents the page from being shown and redirects the user to data:,
(no idea why!).
This tripped me up when I had a WYSIWYG editor that let users embed YouTube and Vimeo videos. When they saved their content we showed them their updated page, complete with embedded videos.
The workaround
There are a couple of solutions
- Don’t display the content in the response.
- Set the
X-XSS-Protection
header to tell Safari you know what you’re doing and disable the auditor.
To set the header you simply need to add the following line to your controller action. The header should be set on the response that renders the content, so if you redirect from your create
/update
action to a show
action, the header needs to be set on the show
action.
response.headers['X-XSS-Protection'] = "0"
No more data colon comma redirects!