0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00

feat: add some security headers for web UI (#1295) @juanpicado

* feat: add some security headers for web UI

The idea behind this is have more control over the content is rendered mostly via README.

* chore: rename header for frame options

* chore: rename method better name
This commit is contained in:
Juan Picado @jotadeveloper 2019-04-30 23:46:36 +02:00 committed by GitHub
parent 5ee485e984
commit 615db0affb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 6 deletions

View file

@ -22,9 +22,15 @@ export function match(regexp: RegExp) {
}; };
} }
export function securityIframe(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function setSecurityWebHeaders(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
// disable loading in frames (clickjacking, etc.) // disable loading in frames (clickjacking, etc.)
res.header('X-Frame-Options', 'deny'); res.header(HEADERS.FRAMES_OPTIONS, 'deny');
// avoid stablish connections outside of domain
res.header(HEADERS.CSP, "connect-src 'self'");
// https://stackoverflow.com/questions/18337630/what-is-x-content-type-options-nosniff
res.header(HEADERS.CTO, 'nosniff');
// https://stackoverflow.com/questions/9090577/what-is-the-http-header-x-xss-protection
res.header(HEADERS.XSS, '1; mode=block');
next(); next();
} }

View file

@ -10,7 +10,7 @@ import addPackageWebApi from './endpoint/package';
import addSearchWebApi from './endpoint/search'; import addSearchWebApi from './endpoint/search';
import Search from '../../lib/search'; import Search from '../../lib/search';
import { match, validateName, validatePackage, securityIframe } from '../middleware'; import { match, validateName, validatePackage, setSecurityWebHeaders } from '../middleware';
import type { Config } from '@verdaccio/types'; import type { Config } from '@verdaccio/types';
import type { IAuth, IStorageHandler } from '../../../types'; import type { IAuth, IStorageHandler } from '../../../types';
@ -33,7 +33,7 @@ export default function(config: Config, auth: IAuth, storage: IStorageHandler) {
route.use(bodyParser.urlencoded({ extended: false })); route.use(bodyParser.urlencoded({ extended: false }));
route.use(auth.webUIJWTmiddleware()); route.use(auth.webUIJWTmiddleware());
route.use(securityIframe); route.use(setSecurityWebHeaders);
addPackageWebApi(route, storage, auth, config); addPackageWebApi(route, storage, auth, config);
addSearchWebApi(route, storage, auth); addSearchWebApi(route, storage, auth);

View file

@ -13,7 +13,7 @@ import Search from '../../lib/search';
import { HEADERS, HTTP_STATUS, WEB_TITLE } from '../../lib/constants'; import { HEADERS, HTTP_STATUS, WEB_TITLE } from '../../lib/constants';
import loadPlugin from '../../lib/plugin-loader'; import loadPlugin from '../../lib/plugin-loader';
const { securityIframe } = require('../middleware'); const { setSecurityWebHeaders } = require('../middleware');
const pkgJSON = require('../../../package.json'); const pkgJSON = require('../../../package.json');
export function loadTheme(config) { export function loadTheme(config) {
@ -49,7 +49,7 @@ module.exports = function(config, auth, storage) {
const router = express.Router(); const router = express.Router();
router.use(auth.webUIJWTmiddleware()); router.use(auth.webUIJWTmiddleware());
router.use(securityIframe); router.use(setSecurityWebHeaders);
const themePath = loadTheme(config) || require('@verdaccio/ui-theme')(); const themePath = loadTheme(config) || require('@verdaccio/ui-theme')();
const indexTemplate = path.join(themePath, 'index.html'); const indexTemplate = path.join(themePath, 'index.html');
const template = fs.readFileSync(indexTemplate).toString(); const template = fs.readFileSync(indexTemplate).toString();

View file

@ -24,6 +24,10 @@ export const HEADERS = {
TEXT_PLAIN: 'text/plain', TEXT_PLAIN: 'text/plain',
TEXT_HTML: 'text/html', TEXT_HTML: 'text/html',
FORWARDED_PROTO: 'X-Forwarded-Proto', FORWARDED_PROTO: 'X-Forwarded-Proto',
FRAMES_OPTIONS: 'X-Frame-Options',
CSP: 'Content-Security-Policy',
CTO: 'X-Content-Type-Options',
XSS: 'X-XSS-Protection',
ETAG: 'ETag', ETAG: 'ETag',
JSON_CHARSET: 'application/json; charset=utf-8', JSON_CHARSET: 'application/json; charset=utf-8',
OCTET_STREAM: 'application/octet-stream; charset=utf-8', OCTET_STREAM: 'application/octet-stream; charset=utf-8',