Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$http's JSONP should require trusted resource URLs #11352

Closed
chirayuk opened this issue Mar 17, 2015 · 4 comments
Closed

$http's JSONP should require trusted resource URLs #11352

chirayuk opened this issue Mar 17, 2015 · 4 comments

Comments

@chirayuk
Copy link
Contributor

$http does not perform any security checks on the URLs that it receives. It should require URLs that pass checks for $sce.RESOURCE_URL.

This should generally not have a huge impact in terms of breaking backwards compatibility. The cases that break, are where folks are performing JSONP requests to 3rd party servers. In such cases, it would be a good idea for the apps that do break to configure the $sce whitelist to include that specific trusted 3rd party server to unbreak themselves.

It might be a good idea to backport this to earlier versions if we can feel confident that we won't actually be breaking most applications.

@chirayuk chirayuk self-assigned this Mar 17, 2015
@chirayuk chirayuk added this to the 1.4.0-beta.7 / 1.3.16 milestone Mar 17, 2015
@chirayuk
Copy link
Contributor Author

@petebacondarwin for triage review (milestone ok?)

@petebacondarwin
Copy link
Contributor

@chirayuk - This sounds like a good security measure and if the mitigation is simply adding to a whitelist then it seems a reasonable breaking change. Do you think you could knock up a PR? If not, then if anyone else in the community wants to have a go at a PR that would be great too!

@chirayuk
Copy link
Contributor Author

@petebacondarwin I'm working on this today.

chirayuk added a commit to chirayuk/angular.js that referenced this issue Apr 16, 2015
WORK-IN-PROGRESS.  Do **NOT** merge.  More work needs to be done and the tests are currently broken.

- JSONP should require trusted resource URLs.  This would be a breaking
  change but maybe not too onerous since same origin URLs are trusted in
  the default config and you can easily whitelist any 3rd party URLs you
  trust in one single place (your app/module config.)
- fix a bug where $http can't handle $sce wrapper URLs.

Closes angular#11352
Closes angular#11328
@chirayuk
Copy link
Contributor Author

I started on it yesterday but didn't have time to finish it. I won't get to it anytime today or tomorrow. However, I created a work-in-progress PR #11623 of my progress so far.

@chirayuk chirayuk modified the milestones: 1.4.0-rc.1, 1.4.0-rc.2 Apr 24, 2015
@petebacondarwin petebacondarwin modified the milestones: 1.5.x - migration-facilitation, 1.4.0-rc.2 May 5, 2015
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 15, 2016
- JSONP should require trusted resource URLs.  This would be a breaking
  change but maybe not too onerous since same origin URLs are trusted in
  the default config and you can easily whitelist any 3rd party URLs you
  trust in one single place (your app/module config.)
- fix a bug where $http can't handle $sce wrapper URLs.

Closes angular#11352
Closes angular#11328
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 16, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be whitelisted with the
`$sceDelegateProvider.resourceUrlWhitelist()` method.

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 16, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be whitelisted with the
`$sceDelegateProvider.resourceUrlWhitelist()` method.

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 16, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be whitelisted with the
`$sceDelegateProvider.resourceUrlWhitelist()` method.

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 16, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be whitelisted with the
`$sceDelegateProvider.resourceUrlWhitelist()` method.

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```
petebacondarwin pushed a commit to petebacondarwin/angular.js that referenced this issue Sep 16, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be whitelisted with the
`$sceDelegateProvider.resourceUrlWhitelist()` method.

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Sep 20, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".
This change makes is easier for developers to see clearly where in their
code they are making JSONP calls that may be to untrusted endpoings and
forces them to think about how these URLs are generated.

Be aware that this commit does not put any constraint on the parameters
that will be appended to the URL. Developers should be mindful of what
parameters can be attached and how they are generated.

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be trusted as resource URLs.
There are two approaches to trust a URL:

**Whitelisting with the `$sceDelegateProvider.resourceUrlWhitelist()`
method.**

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```

**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
method**

You can pass a trusted object instead of a string as a URL to the `$http`
service:

```
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
```
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Oct 3, 2016
Reject JSONP requests that are not trusted by `$sce` as "ResourceUrl".
This change makes is easier for developers to see clearly where in their
code they are making JSONP calls that may be to untrusted endpoings and
forces them to think about how these URLs are generated.

Be aware that this commit does not put any constraint on the parameters
that will be appended to the URL. Developers should be mindful of what
parameters can be attached and how they are generated.

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be trusted as resource URLs.
There are two approaches to trust a URL:

**Whitelisting with the `$sceDelegateProvider.resourceUrlWhitelist()`
method.**

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```

**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
method**

You can pass a trusted object instead of a string as a URL to the `$http`
service:

```
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
```
petebacondarwin added a commit that referenced this issue Oct 5, 2016
… config

The query parameter that will be used to transmit the JSONP callback to the
server is now specified via the `jsonpCallbackParam` config value, instead of
using the `JSON_CALLBACK` placeholder.

* Any use of `JSON_CALLBACK` in a JSONP request URL will cause an error.
* Any request that provides a parameter with the same name as that given
by the `jsonpCallbackParam` config property will cause an error.

This is to prevent malicious attack via the response from an app inadvertently
allowing untrusted data to be used to generate the callback parameter.

Closes #15161
Closes #15143
Closes #11352
Closes #11328

BREAKING CHANGE

You can no longer use the `JSON_CALLBACK` placeholder in your JSONP requests.
Instead you must provide the name of the query parameter that will pass the
callback via the `jsonpCallbackParam` property of the config object, or app-wide via
the `$http.defaults.jsonpCallbackParam` property, which is `"callback"` by default.

Before this change:

```
$http.json('trusted/url?callback=JSON_CALLBACK');
$http.json('other/trusted/url', {params:cb:'JSON_CALLBACK'});
```

After this change:

```
$http.json('trusted/url');
$http.json('other/trusted/url', {callbackParam:'cb'});
```
ellimist pushed a commit to ellimist/angular.js that referenced this issue Mar 15, 2017
The $http service will reject JSONP requests that are not trusted by
`$sce` as "ResourceUrl".
This change makes is easier for developers to see clearly where in their
code they are making JSONP calls that may be to untrusted endpoings and
forces them to think about how these URLs are generated.

Be aware that this commit does not put any constraint on the parameters
that will be appended to the URL. Developers should be mindful of what
parameters can be attached and how they are generated.

Closes angular#11352

BREAKING CHANGE

All JSONP requests now require the URL to be trusted as resource URLs.
There are two approaches to trust a URL:

**Whitelisting with the `$sceDelegateProvider.resourceUrlWhitelist()`
method.**

You configure this list in a module configuration block:

```
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhiteList([
    // Allow same origin resource loads.
    'self',
    // Allow JSONP calls that match this pattern
    'https://some.dataserver.com/**.jsonp?**`
  ]);
}]);
```

**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
method**

You can pass a trusted object instead of a string as a URL to the `$http`
service:

```
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
```
ellimist pushed a commit to ellimist/angular.js that referenced this issue Mar 15, 2017
… config

The query parameter that will be used to transmit the JSONP callback to the
server is now specified via the `jsonpCallbackParam` config value, instead of
using the `JSON_CALLBACK` placeholder.

* Any use of `JSON_CALLBACK` in a JSONP request URL will cause an error.
* Any request that provides a parameter with the same name as that given
by the `jsonpCallbackParam` config property will cause an error.

This is to prevent malicious attack via the response from an app inadvertently
allowing untrusted data to be used to generate the callback parameter.

Closes angular#15161
Closes angular#15143
Closes angular#11352
Closes angular#11328

BREAKING CHANGE

You can no longer use the `JSON_CALLBACK` placeholder in your JSONP requests.
Instead you must provide the name of the query parameter that will pass the
callback via the `jsonpCallbackParam` property of the config object, or app-wide via
the `$http.defaults.jsonpCallbackParam` property, which is `"callback"` by default.

Before this change:

```
$http.json('trusted/url?callback=JSON_CALLBACK');
$http.json('other/trusted/url', {params:cb:'JSON_CALLBACK'});
```

After this change:

```
$http.json('trusted/url');
$http.json('other/trusted/url', {callbackParam:'cb'});
```
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.