Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"gulp-mocha": "2.2.0",
"gulp-multi-process": "^1.3.1",
"hapi": "^17.5.3",
"is-path-inside": "^2.0.0",
"jest": "^23.6.0",
"jest-cli": "^23.6.0",
"jest-styled-components": "^6.2.2",
Expand Down
49 changes: 49 additions & 0 deletions x-pack/plugins/canvas/tasks/helpers/import_whitelist_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { relative, resolve } from 'path';

import isPathInside from 'is-path-inside';
import chalk from 'chalk';

const KIBANA_ROOT = resolve(__dirname, '../../../../..');

function match(path, pathsOrRegexps) {
return [].concat(pathsOrRegexps).some(pathOrRegexp => {
if (pathOrRegexp instanceof RegExp) return pathOrRegexp.test(path);
return path === pathOrRegexp || isPathInside(path, pathOrRegexp);
});
}

export class ImportWhitelistPlugin {
constructor({ from, whitelist }) {
this.from = from;
this.whitelist = whitelist;
}

apply(resolver) {
resolver.hooks.file.tap('ImportWhitelistPlugin', request => {
if (!request.context || !request.context.issuer) {
// ignore internal requests that don't have an issuer
return;
}

if (!match(request.context.issuer, this.from)) {
// request is not filtered by this whitelist unless it comes
// from a module matching the from directory/regex
return;
}

if (!match(request.path, this.whitelist)) {
throw new Error(
`Attempted to import "${chalk.yellow(relative(KIBANA_ROOT, request.path))}" which ` +
`is not in the whitelist for the ${chalk.cyan(relative(KIBANA_ROOT, this.from))} ` +
`directory.`
);
}
});
}
}
24 changes: 22 additions & 2 deletions x-pack/plugins/canvas/tasks/helpers/webpack.plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
import path from 'path';
import CopyWebpackPlugin from 'copy-webpack-plugin';

import { ImportWhitelistPlugin } from './import_whitelist_plugin';

const sourceDir = path.resolve(__dirname, '../../canvas_plugin_src');
const buildDir = path.resolve(__dirname, '../../canvas_plugin');
const sharedDir = path.resolve(__dirname, '../../shared');

export function getWebpackConfig({ devtool, watch } = {}) {
return {
Expand Down Expand Up @@ -54,6 +57,23 @@ export function getWebpackConfig({ devtool, watch } = {}) {
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
mainFields: ['browser', 'main'],
plugins: [
// whitelist imports from the canvas_plugin_src directory
// to ensure that only modules in its own directory and node_modules
// are included in the canvas_plugin bundle. An additional /shared/
// directory at the root of canvas is included so that code can be shared
// with the rest of the canvas app
new ImportWhitelistPlugin({
from: sourceDir,
whitelist: [/[\/\\]node_modules[\/\\]/, sourceDir, sharedDir],
}),
// only whitelist node_modules and code within the shared directory so that
// they can safely be imported by the canvas_plugin_src or the canvas app
new ImportWhitelistPlugin({
from: sharedDir,
whitelist: [/[\/\\]node_modules[\/\\]/, sharedDir],
}),
],
},

plugins: [
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11511,6 +11511,13 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"

is-path-inside@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.0.0.tgz#28f249020fe6906671fe31a76118f2cd490441fd"
integrity sha512-OmUXvSq+P7aI/aRbl1dzwdlyLn8vW7Nr2/11S7y/dcLLgnQ89hgYJp7tfc+A5SRid3rNCLpruOp2CAV68/iOcA==
dependencies:
path-is-inside "^1.0.2"

is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
Expand Down