Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Basic JSON/JSON-P service in PHP
// Prevent content sniffing attacks such as
header('X-Content-Type-Options: nosniff');
// Note: The user-provided callback name must be filtered to prevent attack
// vectors. This script simply removes any symbols other than `[a-zA-Z0-9$_]`
// from the input. Sadly, this blocks the use of some valid JavaScript
// identifiers, and also accepts a few invalid ones. See
// for details.
// The callback name is prefixed with an empty multi-line comment (`/**/`) to
// prevent content sniffing attacks in browsers without `nosniff` support.
$callback = isset($_GET['callback'])
? '/**/' . preg_replace('/[^a-zA-Z0-9$_.]/s', '', $_GET['callback'])
: false;
// Send the appropriate MIME type: JSON or JSON-P/JavaScript?
header('Content-Type: ' .
($callback ? 'application/javascript' : 'application/json') .
// There’s no reason not to allow CORS for public APIs.
// See for details.
header('Access-Control-Allow-Origin: *');
// Your data goes here. It’s recommended to always use an associative array
// here, so that the resulting JSON represents a non-array object, as this
// prevents JSON hijacking attacks. See for details.
$data = array('some-key' => 'some-value');
// Output the end result.
echo ($callback ? $callback . '(' : '') .
json_encode($data, JSON_UNESCAPED_SLASHES) . // ≥ PHP 5.4.0
($callback ? ')' : '');

This comment has been minimized.

Copy link
Owner Author

@mathiasbynens mathiasbynens commented May 9, 2013

This used to be a comment over at, but I’ve made it a proper gist for future reference.

I’ve added the JSON_UNESCAPED_SLASHES bit, too. There’s no need to escape / unless the JSON-formatted data is inserted as part of an HTML <script> element, and the / in question is part of the sequence </script. Since this is code for a stand-alone JSON/JSON-P service, this context doesn’t apply here.

Attack vectors such as or (see Abuse of JSONP). An XSS vulnerability in a JSON-P service can be used to bypass CSP on the same origin, as part of a bigger attack .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment