helmet-crossdomain
Advanced tools
Comparing version 0.1.0 to 0.2.0
46
index.js
@@ -1,36 +0,24 @@ | ||
var parse = require('url').parse; | ||
var url = require('url') | ||
var data = '<?xml version="1.0"?>' + | ||
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">' + | ||
'<cross-domain-policy>' + | ||
'<site-control permitted-cross-domain-policies="none"/>' + | ||
'</cross-domain-policy>'; | ||
var POLICY = [ | ||
'<?xml version="1.0"?>', | ||
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">', | ||
'<cross-domain-policy>', | ||
'<site-control permitted-cross-domain-policies="none"/>', | ||
'</cross-domain-policy>' | ||
].join('') | ||
module.exports = function crossdomain(options) { | ||
module.exports = function crossdomain () { | ||
return function crossdomain (req, res, next) { | ||
var pathname = url.parse(req.url).pathname | ||
options = options || {}; | ||
var caseSensitive = options.caseSensitive; | ||
return function crossdomain(req, res, next) { | ||
var pathname = parse(req.url).pathname; | ||
var uri; | ||
if (caseSensitive) { | ||
uri = pathname; | ||
} else { | ||
uri = pathname.toLowerCase(); | ||
} | ||
if ('/crossdomain.xml' === uri) { | ||
if (pathname === '/crossdomain.xml') { | ||
res.writeHead(200, { | ||
'Content-Type': 'text/x-cross-domain-policy' | ||
}); | ||
res.end(data); | ||
}) | ||
res.end(POLICY) | ||
} else { | ||
next(); | ||
next() | ||
} | ||
}; | ||
}; | ||
} | ||
} |
{ | ||
"name": "helmet-crossdomain", | ||
"author": "Evan Hahn <me@evanhahn.com> (http://evanhahn.com)", | ||
"author": "Evan Hahn <me@evanhahn.com> (https://evanhahn.com)", | ||
"description": "Serve a restrictive crossdomain.xml at your site's root.", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"license": "MIT", | ||
"keywords": [ | ||
"helmet", | ||
"security", | ||
@@ -18,10 +18,21 @@ "express", | ||
"bugs": "https://github.com/helmetjs/crossdomain/issues", | ||
"engines": { | ||
"node": ">= 4" | ||
}, | ||
"scripts": { | ||
"pretest": "standard --fix", | ||
"test": "mocha" | ||
}, | ||
"devDependencies": { | ||
"connect": "^2.25.7", | ||
"mocha": "^1.21.4", | ||
"supertest": "^0.13.0" | ||
"connect": "^3.6.6", | ||
"mocha": "^5.0.1", | ||
"standard": "^10.0.3", | ||
"supertest": "^3.0.0" | ||
}, | ||
"standard": { | ||
"globals": [ | ||
"describe", | ||
"it" | ||
] | ||
} | ||
} |
Helmet's crossdomain.xml middleware | ||
=================================== | ||
Adobe defines [the spec for crossdomain.xml](http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html), a policy file that grants some Adobe products (like Flash) read access to resources on your domain. An unrestrictive policy could let others load things off your domain that you don't want. | ||
[![Build Status](https://travis-ci.org/helmetjs/crossdomain.svg?branch=master)](https://travis-ci.org/helmetjs/crossdomain) | ||
Adobe defines [the spec for crossdomain.xml](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html), a policy file that grants some Adobe products (like Flash) read access to resources on your domain. An unrestrictive policy could let others load things off your domain that you don't want. | ||
To serve up a restrictive policy: | ||
```javascript | ||
var crossdomain = require('helmet-crossdomain'); | ||
app.use(crossdomain()); | ||
var crossdomain = require('helmet-crossdomain') | ||
app.use(crossdomain()) | ||
``` | ||
This serves the policy at `/crossdomain.xml`. By default, this is case-insensitive. To make it case-sensitive: | ||
This serves the policy at `/crossdomain.xml`. | ||
```javascript | ||
app.use(crossdomain({ caseSensitive: true })); | ||
// This will now ONLY match all-lowercase /crossdomain.xml. | ||
``` | ||
This doesn't make you wildly more secure, but it does help to keep Flash from loading things that you don't want it to. You might also *want* some of this behavior, in which case you should make your own less-restrictive policy and serve it. |
@@ -1,88 +0,51 @@ | ||
var crossdomain = require('..'); | ||
var crossdomain = require('..') | ||
var assert = require('assert'); | ||
var connect = require('connect'); | ||
var request = require('supertest'); | ||
var assert = require('assert') | ||
var connect = require('connect') | ||
var request = require('supertest') | ||
var POLICY = '<?xml version="1.0"?>' + | ||
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">' + | ||
'<cross-domain-policy>' + | ||
'<site-control permitted-cross-domain-policies="none"/>' + | ||
'</cross-domain-policy>'; | ||
var EXPECTED_POLICY = [ | ||
'<?xml version="1.0"?>', | ||
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">', | ||
'<cross-domain-policy>', | ||
'<site-control permitted-cross-domain-policies="none"/>', | ||
'</cross-domain-policy>' | ||
].join('') | ||
describe('crossdomain', function () { | ||
function helloWorld(req, res) { | ||
res.end('Hello world!'); | ||
function app () { | ||
var result = connect() | ||
result.use(crossdomain()) | ||
result.use(function (req, res) { res.end('Hello world') }) | ||
return result | ||
} | ||
var app; | ||
beforeEach(function () { | ||
app = connect(); | ||
app.use(crossdomain()); | ||
app.use(helloWorld); | ||
}); | ||
it("doesn't respond to requests to /", function () { | ||
return request(app()).get('/').expect('Hello world') | ||
}) | ||
function expectPolicy(uri, done) { | ||
request(app).get(uri) | ||
.expect(POLICY) | ||
.expect(200, done); | ||
} | ||
it("doesn't respond to requests to different casing", function () { | ||
return Promise.all([ | ||
request(app()).get('/CROSSDOMAIN.XML').expect('Hello world'), | ||
request(app()).get('/crossdomain.XML').expect('Hello world'), | ||
request(app()).get('/CROSSDOMAIN.xml').expect('Hello world') | ||
]) | ||
}) | ||
function expectHello(uri, done) { | ||
request(app).get('/') | ||
.expect('Hello world!', done); | ||
} | ||
it('responds with proper XML when visiting /crossdomain.xml', function () { | ||
return request(app()).get('/crossdomain.xml') | ||
.expect('Content-Type', 'text/x-cross-domain-policy') | ||
.expect(EXPECTED_POLICY) | ||
}) | ||
function test(uri) { | ||
it('responds with proper XML visiting ' + uri, function (done) { | ||
expectPolicy(uri, done); | ||
}); | ||
} | ||
it('responds with proper XML when visiting /crossdomain.xml with query string', function () { | ||
return request(app()).get('/crossdomain.xml?hi=5') | ||
.expect('Content-Type', 'text/x-cross-domain-policy') | ||
.expect(EXPECTED_POLICY) | ||
}) | ||
it('preserves normal responses', function (done) { | ||
expectHello('/', done); | ||
}); | ||
test('/crossdomain.xml'); | ||
test('/crossdomain.XML'); | ||
test('/CrossDomain.xml'); | ||
test('/CROSSDOMAIN.xml'); | ||
test('/CROSSDOMAIN.XML'); | ||
test('/crossdomain.xml?'); | ||
test('/crossdomain.xml?foo=123&bar=456'); | ||
it('can be forced to be case-sensitive in the middleware', function (done) { | ||
var testsRemaining = 7; | ||
function finished(err) { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
testsRemaining -= 1; | ||
if (testsRemaining === 0) { | ||
done(); | ||
} | ||
} | ||
app = connect(); | ||
app.use(crossdomain({ caseSensitive: true })); | ||
app.use(helloWorld); | ||
expectPolicy('/crossdomain.xml', finished); | ||
expectPolicy('/crossdomain.xml?CAPITALIZED=ARGUMENTS', finished); | ||
expectHello('/crossdomain.XML', finished); | ||
expectHello('/CrossDomain.xml', finished); | ||
expectHello('/CROSSDOMAIN.xml', finished); | ||
expectHello('/CROSSDOMAIN.XML', finished); | ||
expectHello('/CROSSDOMAIN.XML?foo=bar', finished); | ||
}); | ||
it('names its function and middleware', function () { | ||
assert.equal(crossdomain.name, 'crossdomain'); | ||
assert.equal(crossdomain().name, 'crossdomain'); | ||
}); | ||
}); | ||
assert.equal(crossdomain.name, 'crossdomain') | ||
assert.equal(crossdomain().name, 'crossdomain') | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
5180
4
64
18