Skip to content

Commit e368cf1

Browse files
authored
Merge pull request #174 from MarcinHoppe/strict-string-whitelisting
Add strict string domain whitelisting
2 parents 239e229 + 67e09f9 commit e368cf1

File tree

6 files changed

+38
-10
lines changed

6 files changed

+38
-10
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,13 @@ angular
167167
168168
...
169169
170-
whiteListedDomains: [/api-version-\d+.myapp.com$/i, 'localhost']
170+
whiteListedDomains: [/^api-version-\d+\.myapp\.com$/i, 'localhost']
171171
});
172172
});
173173
```
174174

175+
Regular expressions should be as strict as possible to prevent attackers from registering their own malicious domains to bypass the whitelist.
176+
175177
### Not Sending the JWT for Template Requests
176178

177179
The `tokenGetter` method can have a parameter `options` injected by angular-jwt. This parameter is the options object of the current request.

dist/angular-jwt.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,14 @@ angular.module('angular-jwt.interceptor', [])
148148
var hostname = urlUtils.urlResolve(url).hostname.toLowerCase();
149149
for (var i = 0; i < options.whiteListedDomains.length; i++) {
150150
var domain = options.whiteListedDomains[i];
151-
var regexp = domain instanceof RegExp ? domain : new RegExp(domain, 'i');
152-
if (hostname.match(regexp)) {
153-
return true;
151+
if (domain instanceof RegExp) {
152+
if (hostname.match(domain)) {
153+
return true;
154+
}
155+
} else {
156+
if (hostname === domain.toLowerCase()) {
157+
return true;
158+
}
154159
}
155160
}
156161

dist/angular-jwt.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-jwt",
3-
"version": "0.1.9",
3+
"version": "0.1.10",
44
"description": "Library to help you work with JWTs on AngularJS",
55
"main": "index.js",
66
"license": "MIT",

src/angularJwt/services/interceptor.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@ angular.module('angular-jwt.interceptor', [])
2020
var hostname = urlUtils.urlResolve(url).hostname.toLowerCase();
2121
for (var i = 0; i < options.whiteListedDomains.length; i++) {
2222
var domain = options.whiteListedDomains[i];
23-
var regexp = domain instanceof RegExp ? domain : new RegExp(domain, 'i');
24-
if (hostname.match(regexp)) {
25-
return true;
23+
if (domain instanceof RegExp) {
24+
if (hostname.match(domain)) {
25+
return true;
26+
}
27+
} else {
28+
if (hostname === domain.toLowerCase()) {
29+
return true;
30+
}
2631
}
2732
}
2833

test/unit/angularJwt/services/interceptorSpec.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ describe('interceptor', function() {
4848
$q.all([
4949
$http({url: 'http://Example.com/hello' }),
5050
$http({url: 'http://www.example.com/hello' }),
51+
$http({url: 'http://wwwXexample.com/hello' }),
52+
$http({url: 'http://whitelisted.example.com.evil.com/hello' }),
5153
$http({url: 'http://whitelisted.example.com/hello' })
5254
]).then(function () {
5355
done();
@@ -59,6 +61,12 @@ describe('interceptor', function() {
5961
$httpBackend.expectGET('http://www.example.com/hello', function (headers) {
6062
return headers.Authorization === undefined;
6163
}).respond(200);
64+
$httpBackend.expectGET('http://wwwXexample.com/hello', function (headers) {
65+
return headers.Authorization === undefined;
66+
}).respond(200);
67+
$httpBackend.expectGET('http://whitelisted.example.com.evil.com/hello', function (headers) {
68+
return headers.Authorization === undefined;
69+
}).respond(200);
6270
$httpBackend.expectGET('http://whitelisted.example.com/hello', function (headers) {
6371
return headers.Authorization === 'Bearer 123';
6472
}).respond(200);
@@ -69,7 +77,7 @@ describe('interceptor', function() {
6977

7078
it('should not add Authr headers to Cross Origin requests unless whitelisted with regexp', function (done) {
7179
module( function ($httpProvider, jwtOptionsProvider, jwtInterceptorProvider) {
72-
jwtInterceptorProvider.whiteListedDomains = [/whitelisted(-pr-\d+)?\.Example\.com$/i]
80+
jwtInterceptorProvider.whiteListedDomains = [/^whitelisted(-pr-\d+)?\.Example\.com$/i]
7381
jwtInterceptorProvider.tokenGetter = function() {
7482
return 123;
7583
}
@@ -80,6 +88,8 @@ describe('interceptor', function() {
8088
$q.all([
8189
$http({url: 'http://Example.com/hello' }),
8290
$http({url: 'http://www.example.com/hello' }),
91+
$http({url: 'http://whitelisted-pr-123.example.com.evil.com/hello' }),
92+
$http({url: 'http://extrawhitelisted-pr-123.example.com.evil.com/hello' }),
8393
$http({url: 'http://whitelisted-pr-123.example.com/hello' })
8494
]).then(function () {
8595
done();
@@ -91,6 +101,12 @@ describe('interceptor', function() {
91101
$httpBackend.expectGET('http://www.example.com/hello', function (headers) {
92102
return headers.Authorization === undefined;
93103
}).respond(200);
104+
$httpBackend.expectGET('http://whitelisted-pr-123.example.com.evil.com/hello', function (headers) {
105+
return headers.Authorization === undefined;
106+
}).respond(200);
107+
$httpBackend.expectGET('http://extrawhitelisted-pr-123.example.com.evil.com/hello', function (headers) {
108+
return headers.Authorization === undefined;
109+
}).respond(200);
94110
$httpBackend.expectGET('http://whitelisted-pr-123.example.com/hello', function (headers) {
95111
return headers.Authorization === 'Bearer 123';
96112
}).respond(200);

0 commit comments

Comments
 (0)