session_id = '5f5513f8822fdbe5145af33b64d8d970dcf95c6e' ajax_endpoint_secret = 'this is a super secret!'
token = hmac.new( ajax_endpoint_secret, session_id, hashlib.sha1 ).hexdigest()
- or -
token = '3815c118a9e3e663215adba5e0ca626e8bdd5125'
then when your server emits the html page, your AJAX link looks like: https://example.com/ajax_api/3815c118a9e3e663215adba5e0ca626...
Here, we have cryptographically bound the AJAX url to the user's cookies, so the <script> trick won't work any longer as they don't have access to the token.
Second, you can have your server endpoint checking for the 'X-Requested-With: XmlHttpRequest' if you anticipate this to only be accessed via XHR. This is a pretty effective thwart of the <script> attack as well.
Lastly, ensure that your JSON response always is wrapped in curly braces {}. Never respond with [] From my experiments, all browsers interpret this as a code block and breaks processing when <script src=> runs.