Closed jledfordtbc closed 4 years ago
We just released Element API 2.6.0 with JSONP support via a new callback endpoint setting.
If you want that to be configurable with a callback
query string param, do this:
use yii\web\BadRequestHttpException;
return [
'test.json' => function() {
$callback = Craft::$app->request->getQueryParam('callback');
// Only alphanumeric and underscore characters allowed
if ($callback && !preg_match('/^\w+$/', $callback)) {
throw new BadRequestHttpException('Invalid callback');
}
return [
'callback' => $callback ? "/**/ $callback" : null,
// ...
];
},
];
@brandonkelly Can you confirm that the callback is appropriately filtered and truncated to prevent attacks? For example you don’t want people doing this...
http://server/my-api-endpoint/?callback=<malicious script goes here>
Be aware that even pure alphanumeric strings can be abused via the Rosetta Flash technique, so you often need to add a /**/
comment prefix and truncate the length to help prevent this. Haven’t reviewed your code to see if it’s doing this.
Some of the security issues are explained on the JSONP Wikipedia page at https://en.m.wikipedia.org/wiki/JSONP#Security_concerns
@SimonEast It’s a config setting so as far as Element API is concerned the value is trusted. If you want to set the value from user input it’s on you to ensure the value isn’t malicious. I’ve updated the example above to verify that the callback only contains alphanumeric characters and underscores, and append /**/
to the value.
I haven't seen anyone asking or answering this, but can you pass a callback with element api and wrap it in jsonp? Dynamic callbacks would be even better so I can hit the endpoint myserver.com/test.json?mycallback=whatever and what is returned is wrapped in a whatever callback. Is that possible?