Skip to content

Commit

Permalink
Merge 0ad4919 into e86357b
Browse files Browse the repository at this point in the history
  • Loading branch information
dzcpy committed Feb 3, 2015
2 parents e86357b + 0ad4919 commit 3c9580c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
14 changes: 9 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ function send(ctx, path, opts) {
if (!root && !isAbsolute(path)) return ctx.throw('relative paths require the .root option', 500);
if (!root && ~path.indexOf('..')) return ctx.throw('malicious path', 400);

// hidden file support, ignore
if (!hidden && isHidden(path)) return;

// relative to root
path = normalize(join(root, path));

// out of bounds
if (root && 0 !== path.indexOf(root)) return ctx.throw('malicious path', 400);

// hidden file support, ignore
if (!hidden && leadingDot(path)) return;

// serve gzipped file when possible
if (encoding === 'gzip' && (yield fs.exists(path + '.gz'))) {
path = path + '.gz';
Expand Down Expand Up @@ -102,8 +102,12 @@ function send(ctx, path, opts) {
* Check if it's hidden.
*/

function leadingDot(path) {
return '.' == basename(path)[0];
function isHidden(path) {
// unescaped version: /[/\].(?!.[/\])/
// [\/] matches a path separator, . matches leading dot
// while (?!.[/\]) makes sure that something like /../ should not be matched
// and is passed to resove-path to get the correct error response
return /[\\\/]\.(?!\.[\\\/])/.test(path);
}

/**
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/.hidden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You should never get here
1 change: 1 addition & 0 deletions test/fixtures/.private/id_rsa.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You should never get here
43 changes: 43 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,49 @@ describe('send(ctx, file)', function(){
})
})
})
describe('.hidden option', function() {
describe('when trying to get a hidden file', function(){
it('should 404', function(done){
var app = koa();

app.use(function *(){
yield send(this, __dirname + '/fixtures/.hidden');
});

request(app.listen())
.get('/')
.expect(404, done);
})
})

describe('when trying to get a file from a hidden directory', function(){
it('should 404', function(done){
var app = koa();

app.use(function *(){
yield send(this, __dirname + '/fixtures/.private/id_rsa.txt');
});

request(app.listen())
.get('/')
.expect(404, done);
})
})

describe('when trying to get a hidden file and .hidden check is turned off', function(){
it('should 404', function(done){
var app = koa();

app.use(function *(){
yield send(this, __dirname + '/fixtures/.hidden', {hidden: true});
});

request(app.listen())
.get('/')
.expect(200, done);
})
})
});

it('should set the Content-Type', function(done){
var app = koa();
Expand Down

0 comments on commit 3c9580c

Please sign in to comment.