Skip to content

Commit

Permalink
Merge pull request #17 from vivaxy/security-issue
Browse files Browse the repository at this point in the history
fix: 🔒Fix an issue that users can browse outside the wd
  • Loading branch information
vivaxy authored Dec 28, 2017
2 parents 4f27246 + 68f0c70 commit 298dbab
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 217 deletions.
21 changes: 2 additions & 19 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
language: node_js
node_js:
- "8"
- "7"
- "6"
- "6.1"
- "6.0"
- "5.11"
- "5.10"
- "5.9"
- "5.8"
- "5.7"
- "5.6"
- "5.5"
- "5.4"
- "5.3"
- "5.2"
- "5.1"
- "5.0"
- "4.4"
- "4.3"
- "4.2"
- "4.1"
- "4.0"
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@
[![NPM Downloads][npm-downloads-image]][npm-url]
[![MIT License][license-image]][license-url]

local static server
Local static server

everything start from `here`
Everything start from `here`.

## FEATURE

- look up available port automatically, which means multiple instances without specifying port
- Look up available port automatically, which means multiple instances without specifying port.

- custom routes by scripting `here.js`
- Custom routes by scripting `here.js`.

- live reload
- Live reload.

- support https
- Support https.

- add ip address to your server, which makes your server available to other devices
- Add ip address to your server, which makes your server available to other devices.

- resolve get, post... every method into local files, for ajax
- Resolve get, post... every method into local files, for ajax.

- respond files without extension as `application/json` for ajax
- Respond files without extension as `application/json` for ajax.

- open default browser after server launched
- Open default browser after server launched.

- when the server is on, press `enter` will open the browser
- When the server is on, press `enter` will open the browser.

## INSTALLATION

Expand All @@ -49,7 +49,7 @@ or

`here --port 8888`

default port is 3000
Default port is 3000.

#### switch protocol to https

Expand All @@ -67,7 +67,7 @@ or

`here --directory test`

default directory is `./`
Default directory is `./`.

#### watch file changes, once files changed, reload pages

Expand All @@ -77,9 +77,9 @@ or

`here --watch`

default interval is 0 second
Default interval is 0 second.

recommend to set reload interval to page reload time
Recommend to set reload interval to page reload time.

#### do not open the browser

Expand All @@ -99,7 +99,7 @@ or

#### middleware support

write `here.js` in server base directory
Write `here.js` in server base directory.

```
let db = {
Expand Down Expand Up @@ -146,7 +146,7 @@ module.exports = [
];
```

see [koa-router document](https://github.com/alexmingoia/koa-router#module_koa-router--Router+get%7Cput%7Cpost%7Cpatch%7Cdelete) for more detail
See [koa-router document](https://github.com/alexmingoia/koa-router#module_koa-router--Router+get%7Cput%7Cpost%7Cpatch%7Cdelete) for more detail.

## Prior Art

Expand Down
21 changes: 6 additions & 15 deletions lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,23 @@ const EMPTY_STRING = '';
const USAGE_TRACKER_ID_KEY = 'usage-tracker-id';

const formatWatch = (value) => {
let result = value;
if (isNaN(Number(value))) {
result = 0;
return 0;
} else if (value < 0) {
result = 0;
return 0;
}
return result;
return value;
};

const formatDirectory = (value) => {
let absoluteWorkingDirectory = process.cwd();
const absoluteWorkingDirectory = process.cwd();
if (path.isAbsolute(value)) {
absoluteWorkingDirectory = value;
} else {
absoluteWorkingDirectory = path.join(absoluteWorkingDirectory, value);
return value;
}
return absoluteWorkingDirectory;
return path.join(absoluteWorkingDirectory, value);
};

const prepare = () => {

if (config.get(configKey.IS_DEBUG)) {
config.set(configKey.LOG_LEVEL, 0);
}
Expand Down Expand Up @@ -115,13 +111,10 @@ const prepare = () => {
};

module.exports = () => {

prepare();

if (!config.get(configKey.IS_DEBUG)) {

process.on('uncaughtException', (e) => {

new usageTracker.UsageTracker({
owner: config.get(configKey.USAGE_TRACKER_OWNER),
repo: config.get(configKey.USAGE_TRACKER_REPO),
Expand All @@ -140,13 +133,11 @@ module.exports = () => {
log.error(e.stack);
// still exit as uncaught exception
});

}

startServer((nativeServer) => {
if (config.get(configKey.WATCH) !== false) {
startWatcher(nativeServer);
}
});

};
78 changes: 12 additions & 66 deletions lib/build-file-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,12 @@ const HTML_EXTENSION = '.html';
* @returns {number} sort value
*/
const compare = (_a, _b) => {

let result = STILL;

if (_a < _b) {

result = AHEAD;

return AHEAD;
} else if (_a > _b) {

result = ABACK;

return ABACK;
}

return result;

return STILL;
};

/**
Expand All @@ -50,125 +41,80 @@ const compare = (_a, _b) => {
* @returns {String} html content
*/
module.exports = (files, pathname, absoluteWorkingDirectory) => {

const baseDir = join(absoluteWorkingDirectory, pathname);

let filesFiltered = files.filter((file) => {

const filesFiltered = files.filter((file) => {
if (file.indexOf('.') === 0) {

return false;

}
// #3 remove inaccessible files from file list
// win下access任何文件都会返回可访问
try {

if (isWindows) {

fs.statSync(join(baseDir, file));

} else {

fs.accessSync(join(baseDir, file), fs.R_OK);

}

} catch (e) {

return false;

}
return true;

});

filesFiltered.sort((a, b) => {

let _isDirectoryA = fs.lstatSync(join(baseDir, a)).isDirectory();
let _isDirectoryB = fs.lstatSync(join(baseDir, b)).isDirectory();

const _isDirectoryA = fs.lstatSync(join(baseDir, a)).isDirectory();
const _isDirectoryB = fs.lstatSync(join(baseDir, b)).isDirectory();
// order by priority
if (_isDirectoryA && _isDirectoryB) {

return compare(a, b);

}
if (_isDirectoryA && !_isDirectoryB) {

return AHEAD;

}
if (_isDirectoryB && !_isDirectoryA) {

return ABACK;

}

let _extensionA = extname(a);
let _extensionB = extname(b);
let _isHtmlA = _extensionA === HTML_EXTENSION;
let _isHtmlB = _extensionB === HTML_EXTENSION;

const _extensionA = extname(a);
const _extensionB = extname(b);
const _isHtmlA = _extensionA === HTML_EXTENSION;
const _isHtmlB = _extensionB === HTML_EXTENSION;
if (_isHtmlA && _isHtmlB) {

return compare(a, b);

}
if (_isHtmlA && !_isHtmlB) {

return AHEAD;

}
if (_isHtmlB && !_isHtmlA) {

return ABACK;

}

if (_extensionA === _extensionB) {

return compare(a, b);

}

return compare(a, b);

});

if (pathname !== '/') {

filesFiltered.unshift('..');

}

let list = filesFiltered.map((file) => {

let ext = extname(file);
const list = filesFiltered.map((file) => {
const ext = extname(file);
let _ext = 'other';

if (ext === HTML_EXTENSION) {

_ext = 'html';

}
if (fs.lstatSync(join(baseDir, file)).isDirectory()) {

_ext = 'dir';

}
if (file === '..') {

_ext = 'null';

}
return {
// remove http://ip:port to redirect to correct ip:port
href: join(pathname, file),
className: _ext,
fileName: file
};

});

return pug.compileFile(join(__dirname, '../res/list.pug'), {
Expand Down
2 changes: 1 addition & 1 deletion lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
'use strict';

let config = {
const config = {
isDebug: false,

port: 3000,
Expand Down
2 changes: 0 additions & 2 deletions lib/open-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const logPrefix = require('../constant/log-prefix');
const configKey = require('../constant/config');

module.exports = () => {

// always use current ip address

const protocol = config.get(configKey.SSL) ? 'https:' : 'http:';
Expand All @@ -28,5 +27,4 @@ module.exports = () => {
// open browser succeeded
log.debug(logPrefix.BROWSER, execCommand, openUrl);
});

};
Loading

0 comments on commit 298dbab

Please sign in to comment.