diff --git a/packages/plugins/audit/.babelrc b/packages/plugins/audit/.babelrc new file mode 100644 index 000000000..851856e59 --- /dev/null +++ b/packages/plugins/audit/.babelrc @@ -0,0 +1,3 @@ +{ + "extends": "../../../.babelrc" +} diff --git a/packages/plugins/audit/CHANGELOG.md b/packages/plugins/audit/CHANGELOG.md new file mode 100644 index 000000000..f84baacb7 --- /dev/null +++ b/packages/plugins/audit/CHANGELOG.md @@ -0,0 +1,348 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [9.7.3](https://github.com/verdaccio/monorepo/compare/v9.7.2...v9.7.3) (2020-07-30) + + +### Bug Fixes + +* update marked / request security vulnerability ([#378](https://github.com/verdaccio/monorepo/issues/378)) ([4188e08](https://github.com/verdaccio/monorepo/commit/4188e088f42d0f6e090c948b869312ba1f30cd79)) + + + + + +## [9.7.2](https://github.com/verdaccio/monorepo/compare/v9.7.1...v9.7.2) (2020-07-20) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [9.7.1](https://github.com/verdaccio/monorepo/compare/v9.7.0...v9.7.1) (2020-07-10) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [9.7.0](https://github.com/verdaccio/monorepo/compare/v9.6.1...v9.7.0) (2020-06-24) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [9.6.1](https://github.com/verdaccio/monorepo/compare/v9.6.0...v9.6.1) (2020-06-07) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [9.5.0](https://github.com/verdaccio/monorepo/compare/v9.4.1...v9.5.0) (2020-05-02) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [9.4.0](https://github.com/verdaccio/monorepo/compare/v9.3.4...v9.4.0) (2020-03-21) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [9.3.2](https://github.com/verdaccio/monorepo/compare/v9.3.1...v9.3.2) (2020-03-08) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [9.3.1](https://github.com/verdaccio/monorepo/compare/v9.3.0...v9.3.1) (2020-02-23) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [9.3.0](https://github.com/verdaccio/monorepo/compare/v9.2.0...v9.3.0) (2020-01-29) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [9.0.0](https://github.com/verdaccio/monorepo/compare/v8.5.3...v9.0.0) (2020-01-07) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.5.2](https://github.com/verdaccio/monorepo/compare/v8.5.1...v8.5.2) (2019-12-25) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.5.1](https://github.com/verdaccio/monorepo/compare/v8.5.0...v8.5.1) (2019-12-24) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.5.0](https://github.com/verdaccio/monorepo/compare/v8.4.2...v8.5.0) (2019-12-22) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.4.2](https://github.com/verdaccio/monorepo/compare/v8.4.1...v8.4.2) (2019-11-23) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.4.1](https://github.com/verdaccio/monorepo/compare/v8.4.0...v8.4.1) (2019-11-22) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.4.0](https://github.com/verdaccio/monorepo/compare/v8.3.0...v8.4.0) (2019-11-22) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.3.0](https://github.com/verdaccio/monorepo/compare/v8.2.0...v8.3.0) (2019-10-27) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.2.0](https://github.com/verdaccio/monorepo/compare/v8.2.0-next.0...v8.2.0) (2019-10-23) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.2.0-next.0](https://github.com/verdaccio/monorepo/compare/v8.1.4...v8.2.0-next.0) (2019-10-08) + + +### Bug Fixes + +* fixed lint errors ([c80e915](https://github.com/verdaccio/monorepo/commit/c80e915)) + + + + + +## [8.1.4](https://github.com/verdaccio/monorepo/compare/v8.1.3...v8.1.4) (2019-09-30) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.1.3](https://github.com/verdaccio/monorepo/compare/v8.1.2...v8.1.3) (2019-09-30) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.1.2](https://github.com/verdaccio/monorepo/compare/v8.1.1...v8.1.2) (2019-09-29) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.1.1](https://github.com/verdaccio/monorepo/compare/v8.1.0...v8.1.1) (2019-09-26) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.1.0](https://github.com/verdaccio/monorepo/compare/v8.0.1-next.1...v8.1.0) (2019-09-07) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.0.1-next.1](https://github.com/verdaccio/monorepo/compare/v8.0.1-next.0...v8.0.1-next.1) (2019-08-29) + +**Note:** Version bump only for package verdaccio-audit + + + + + +## [8.0.1-next.0](https://github.com/verdaccio/monorepo/compare/v8.0.0...v8.0.1-next.0) (2019-08-29) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.0.0](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.4...v8.0.0) (2019-08-22) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.0.0-next.4](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.3...v8.0.0-next.4) (2019-08-18) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.0.0-next.2](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.1...v8.0.0-next.2) (2019-08-03) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.0.0-next.1](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.0...v8.0.0-next.1) (2019-08-01) + +**Note:** Version bump only for package verdaccio-audit + + + + + +# [8.0.0-next.0](https://github.com/verdaccio/monorepo/compare/v2.0.0...v8.0.0-next.0) (2019-08-01) + + +### Bug Fixes + +* on error returns 500 by default ([86bf628](https://github.com/verdaccio/monorepo/commit/86bf628)) +* package.json to reduce vulnerabilities ([457a791](https://github.com/verdaccio/monorepo/commit/457a791)) + + +### Features + +* add audit quick endpoint ([5ab2ece](https://github.com/verdaccio/monorepo/commit/5ab2ece)) +* migrate to typescript ([caffcd5](https://github.com/verdaccio/monorepo/commit/caffcd5)) +* proxy npm audit endpoint ([b11151d](https://github.com/verdaccio/monorepo/commit/b11151d)) + + + + + +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +### [1.2.1](https://github.com/verdaccio/verdaccio-audit/compare/v1.2.0...v1.2.1) (2019-07-29) + + +### Bug Fixes + +* audit module doesn't support strict_ssl flag ([f7d3f86](https://github.com/verdaccio/verdaccio-audit/commit/f7d3f86)) + + +### Build System + +* update dependencies ([ddaa990](https://github.com/verdaccio/verdaccio-audit/commit/ddaa990)) + + + +# [1.2.0](https://github.com/verdaccio/verdaccio-audit/compare/v1.1.0...v1.2.0) (2019-04-06) + + +### Bug Fixes + +* bad network causes the server down ([2c838b4](https://github.com/verdaccio/verdaccio-audit/commit/2c838b4)) +* types error ([16d623e](https://github.com/verdaccio/verdaccio-audit/commit/16d623e)) + + +### Features + +* migrate to typescript ([bec6824](https://github.com/verdaccio/verdaccio-audit/commit/bec6824)) + + + + +# [1.1.0](https://github.com/verdaccio/verdaccio-audit/compare/v1.0.1...v1.1.0) (2019-01-09) + + +### Features + +* pipe request and response bodies to save memory ([#8](https://github.com/verdaccio/verdaccio-audit/issues/8)) ([0af7363](https://github.com/verdaccio/verdaccio-audit/commit/0af7363)) + + + + +## [1.0.1](https://github.com/verdaccio/verdaccio-audit/compare/v1.0.0...v1.0.1) (2019-01-09) + + +### Bug Fixes + +* package.json to reduce vulnerabilities ([bdf35df](https://github.com/verdaccio/verdaccio-audit/commit/bdf35df)) + + + + +# [1.0.0](https://github.com/verdaccio/verdaccio-audit/compare/v0.2.0...v1.0.0) (2018-10-18) + + +### Features + +* handle 'application/json, application/octet-stream' content types ([cf38a38](https://github.com/verdaccio/verdaccio-audit/commit/cf38a38)) + + + + +# [0.2.0](https://github.com/verdaccio/verdaccio-audit/compare/v0.1.0...v0.2.0) (2018-06-15) + + +### Features + +* support audit via HTTPS proxy ([5328bc3](https://github.com/verdaccio/verdaccio-audit/commit/5328bc3)) diff --git a/packages/plugins/audit/LICENSE b/packages/plugins/audit/LICENSE new file mode 100644 index 000000000..65fb12e2a --- /dev/null +++ b/packages/plugins/audit/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Verdaccio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/plugins/audit/README.md b/packages/plugins/audit/README.md new file mode 100644 index 000000000..79cc78277 --- /dev/null +++ b/packages/plugins/audit/README.md @@ -0,0 +1,41 @@ +# verdaccio-audit + +🛡🔬 npmjs audit support for verdaccio + +[![verdaccio (latest)](https://img.shields.io/npm/v/verdaccio-audit/latest.svg)](https://www.npmjs.com/package/verdaccio-audit) +[![Known Vulnerabilities](https://snyk.io/test/github/verdaccio/verdaccio-audit/badge.svg?targetFile=package.json)](https://snyk.io/test/github/verdaccio/verdaccio-audit?targetFile=package.json) +[![backers](https://opencollective.com/verdaccio/tiers/backer/badge.svg?label=Backer&color=brightgreen)](https://opencollective.com/verdaccio) +[![discord](https://img.shields.io/discord/388674437219745793.svg)](http://chat.verdaccio.org/) +![MIT](https://img.shields.io/github/license/mashape/apistatus.svg) +[![node](https://img.shields.io/node/v/verdaccio-audit/latest.svg)](https://www.npmjs.com/package/verdaccio-audit) + +## Requirements + +- verdaccio@3.x or higher + +``` + npm install --global verdaccio-audit +``` + +## Usage + +To enable it you need to add this to your configuration file. + +```yaml +middlewares: + audit: + enabled: true + strict_ssl: true # optional, defaults to true +``` + +### Strict SSL + +In some scenarios it may be necessary to disable SSL certificate validation. Setting _strict_ssl_ to false will disable these checks, but will make all connections passing through this plugin inherently insecure. + +## Disclaimer + +This plugin is experimental and unstable. Please report any issue you found. + +## License + +MIT (http://www.opensource.org/licenses/mit-license.php) diff --git a/packages/plugins/audit/jest.config.js b/packages/plugins/audit/jest.config.js new file mode 100644 index 000000000..a162244c9 --- /dev/null +++ b/packages/plugins/audit/jest.config.js @@ -0,0 +1,5 @@ +const config = require('../../../jest/config'); + +module.exports = Object.assign({}, config, { + collectCoverage: true, +}); diff --git a/packages/plugins/audit/package.json b/packages/plugins/audit/package.json new file mode 100644 index 000000000..09442e04f --- /dev/null +++ b/packages/plugins/audit/package.json @@ -0,0 +1,47 @@ +{ + "name": "verdaccio-audit", + "version": "10.0.0-beta", + "description": "Verdaccio Middleware plugin to bypass npmjs audit", + "keywords": [ + "verdaccio", + "plugin", + "middleware", + "audit" + ], + "author": "Juan Picado ", + "license": "MIT", + "homepage": "https://verdaccio.org", + "repository": { + "type": "git", + "url": "https://github.com/verdaccio/verdaccio", + "directory": "packages/plugins/audit" + }, + "bugs": { + "url": "https://github.com/verdaccio/verdaccio/issues" + }, + "main": "build/index.js", + "types": "build/index.d.ts", + "dependencies": { + "express": "^4.17.1", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.0" + }, + "devDependencies": { + "@verdaccio/types": "workspace:*", + "nock": "^12.0.3", + "body-parser": "^1.19.0", + "supertest": "^4.0.2" + }, + "scripts": { + "clean": "rimraf ./build", + "type-check": "tsc --noEmit -p tsconfig.build.json", + "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json", + "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps", + "build": "pnpm run build:js && pnpm run build:types", + "test": "cross-env NODE_ENV=test BABEL_ENV=test jest" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } +} diff --git a/packages/plugins/audit/src/audit.ts b/packages/plugins/audit/src/audit.ts new file mode 100644 index 000000000..427d290d2 --- /dev/null +++ b/packages/plugins/audit/src/audit.ts @@ -0,0 +1,88 @@ +import util from 'util'; +import https from 'https'; + +import fetch from 'node-fetch'; +import createHttpsProxyAgent from 'https-proxy-agent'; +import express, { Request, Response } from 'express'; +import { Logger, IPluginMiddleware, IBasicAuth, PluginOptions } from '@verdaccio/types'; + +import { ConfigAudit } from './types'; + +const streamPipeline = util.promisify(require('stream').pipeline); + +// FUTURE: we should be able to overwrite this +export const REGISTRY_DOMAIN = 'https://registry.npmjs.org'; +export const AUDIT_ENDPOINT = `/-/npm/v1/security/audits`; + +function getSSLAgent(rejectUnauthorized) { + return new https.Agent({ rejectUnauthorized }); +} + +export default class ProxyAudit implements IPluginMiddleware { + public enabled: boolean; + public logger: Logger; + public strict_ssl: boolean; + + public constructor(config: ConfigAudit, options: PluginOptions) { + this.enabled = config.enabled || false; + this.strict_ssl = config.strict_ssl !== undefined ? config.strict_ssl : true; + this.logger = options.logger; + } + + public register_middlewares(app: any, auth: IBasicAuth): void { + const fetchAudit = (req: Request, res: Response & { report_error?: Function }): void => { + const headers = req.headers; + headers.host = 'https://registry.npmjs.org/'; + + let requestOptions: any = { + method: req.method, + headers, + }; + + if (this.strict_ssl) { + requestOptions = Object.assign({}, requestOptions, { + agent: getSSLAgent(this.strict_ssl), + }); + } + + if (auth?.config?.https_proxy) { + // we should check whether this works fine after this migration + // please notify if anyone is having issues + const agent = createHttpsProxyAgent(auth?.config?.https_proxy); + requestOptions = Object.assign({}, requestOptions, { + agent, + }); + } + + (async () => { + try { + const response = await fetch(`${REGISTRY_DOMAIN}${AUDIT_ENDPOINT}`, requestOptions); + if (response.ok) { + return streamPipeline(response.body, res); + } + + res.status(response.status).end(); + } catch { + res.status(500).end(); + } + })(); + }; + + const handleAudit = (req: Request, res: Response): void => { + if (this.enabled) { + fetchAudit(req, res); + } else { + res.status(500).end(); + } + }; + + /* eslint new-cap:off */ + const router = express.Router(); + /* eslint new-cap:off */ + router.post('/audits', handleAudit); + + router.post('/audits/quick', handleAudit); + + app.use('/-/npm/v1/security', router); + } +} diff --git a/packages/plugins/audit/src/index.ts b/packages/plugins/audit/src/index.ts new file mode 100644 index 000000000..1b7165efe --- /dev/null +++ b/packages/plugins/audit/src/index.ts @@ -0,0 +1,6 @@ +import AuditPlugin from './audit'; +import { ConfigAudit } from './types'; + +export { ConfigAudit }; + +export default AuditPlugin; diff --git a/packages/plugins/audit/src/types.ts b/packages/plugins/audit/src/types.ts new file mode 100644 index 000000000..75dc0ea07 --- /dev/null +++ b/packages/plugins/audit/src/types.ts @@ -0,0 +1,7 @@ +// Temporary solution for requiring types will not cause the error. +import { Config } from '@verdaccio/types'; + +export interface ConfigAudit extends Config { + enabled: boolean; + strict_ssl?: boolean | void; +} diff --git a/packages/plugins/audit/tests/audit.spec.ts b/packages/plugins/audit/tests/audit.spec.ts new file mode 100644 index 000000000..6980a22b8 --- /dev/null +++ b/packages/plugins/audit/tests/audit.spec.ts @@ -0,0 +1,31 @@ +import { Logger } from '@verdaccio/types'; + +import ProxyAudit, { ConfigAudit } from '../src/index'; + +const config: ConfigAudit = { + enabled: true, +} as ConfigAudit; + +const logger: Logger = { + error: (e) => console.warn(e), + info: (e) => console.warn(e), + debug: (e) => console.warn(e), + child: (e) => console.warn(e), + warn: () => {}, + http: (e) => console.warn(e), + trace: (e) => console.warn(e), +}; + +describe('Audit plugin', () => { + test('should test audit', () => { + const audit = new ProxyAudit(config, { logger, config: undefined }); + expect(audit).toBeDefined(); + }); + + test('should test audit with configuration', () => { + const config = { strict_ssl: false } as ConfigAudit; + const audit = new ProxyAudit(config, { logger, config: config }); + expect(audit).toBeDefined(); + expect(audit.strict_ssl).toBeFalsy(); + }); +}); diff --git a/packages/plugins/audit/tsconfig.build.json b/packages/plugins/audit/tsconfig.build.json new file mode 100644 index 000000000..6d445a271 --- /dev/null +++ b/packages/plugins/audit/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./build" + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"] +} diff --git a/packages/plugins/audit/tsconfig.json b/packages/plugins/audit/tsconfig.json new file mode 100644 index 000000000..2430f9bba --- /dev/null +++ b/packages/plugins/audit/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../../tsconfig.reference.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./build" + }, + "include": ["src/**/*", "types/*.d.ts"], + "exclude": ["src/**/*.test.ts"], + "references": [ + { + "path": "../../core/commons-api" + }, + { + "path": "../../core/streams" + }, + { + "path": "../../core/types" + } + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3bfb638af..fff049ff4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -519,6 +519,24 @@ importers: core-js: ^3.6.5 lodash: ^4.17.20 selfsigned: 1.10.7 + packages/plugins/audit: + dependencies: + express: 4.17.1 + https-proxy-agent: 5.0.0 + node-fetch: 2.6.1 + devDependencies: + '@verdaccio/types': 'link:../../core/types' + body-parser: 1.19.0 + nock: 12.0.3 + supertest: 4.0.2 + specifiers: + '@verdaccio/types': 'workspace:*' + body-parser: ^1.19.0 + express: ^4.17.1 + https-proxy-agent: ^5.0.0 + nock: ^12.0.3 + node-fetch: ^2.6.0 + supertest: ^4.0.2 packages/plugins/auth-memory: dependencies: '@verdaccio/commons-api': 'link:../../core/commons-api' @@ -6569,6 +6587,14 @@ packages: node: '>= 4.0.0' resolution: integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + /agent-base/6.0.2: + dependencies: + debug: 4.2.0 + dev: false + engines: + node: '>= 6.0.0' + resolution: + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== /aggregate-error/3.1.0: dependencies: clean-stack: 2.2.0 @@ -13622,6 +13648,15 @@ packages: node: '>= 4.5.0' resolution: integrity: sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== + /https-proxy-agent/5.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.2.0 + dev: false + engines: + node: '>= 6' + resolution: + integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== /human-id/1.0.2: dev: true resolution: