Skip to content

Commit 4690305

Browse files
mw-dingzfy0701
authored andcommitted
[Code] Add git clone url host and protocol whitelist (#33371)
1 parent 5774b55 commit 4690305

File tree

7 files changed

+66
-6
lines changed

7 files changed

+66
-6
lines changed

x-pack/plugins/code/common/git_url_utils.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,15 @@ test('Git url validation', () => {
3131
// An url without protocol
3232
expect(isValidGitUrl('/Users/elastic/elasticsearch')).toBeFalsy();
3333
expect(isValidGitUrl('github.com/elastic/elasticsearch')).toBeFalsy();
34+
35+
// An valid git url but without whitelisted host
36+
expect(isValidGitUrl('https://github.com/elastic/elasticsearch.git', ['gitlab.com'])).toBeFalsy();
37+
38+
// An valid git url but without whitelisted protocol
39+
expect(isValidGitUrl('https://github.com/elastic/elasticsearch.git', [], ['ssh'])).toBeFalsy();
40+
41+
// An valid git url with both whitelisted host and protocol
42+
expect(
43+
isValidGitUrl('https://github.com/elastic/elasticsearch.git', ['github.com'], ['https'])
44+
).toBeTruthy();
3445
});

x-pack/plugins/code/common/git_url_utils.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,33 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
export function isValidGitUrl(url: string): boolean {
7+
import GitUrlParse from 'git-url-parse';
8+
9+
export function isValidGitUrl(
10+
url: string,
11+
hostWhitelist?: string[],
12+
protocolWhitelist?: string[]
13+
): boolean {
814
const regex = /(?:git|ssh|https?|git@[-\w.]+):(\/\/)?(.*?)(\.git)?(\/?|\#[-\d\w._]+?)$/;
9-
return regex.test(url);
15+
const isPatternValid = regex.test(url);
16+
17+
if (!isPatternValid) {
18+
return false;
19+
}
20+
21+
const repo = GitUrlParse(url);
22+
23+
let isHostValid = true;
24+
if (hostWhitelist && hostWhitelist.length > 0) {
25+
const hostSet = new Set(hostWhitelist);
26+
isHostValid = hostSet.has(repo.source);
27+
}
28+
29+
let isProtocolValid = true;
30+
if (protocolWhitelist && protocolWhitelist.length > 0) {
31+
const protocolSet = new Set(protocolWhitelist);
32+
isProtocolValid = protocolSet.has(repo.protocol);
33+
}
34+
35+
return isHostValid && isProtocolValid;
1036
}

x-pack/plugins/code/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ export const code = (kibana: any) =>
5555
enableMavenImport: Joi.boolean().default(true),
5656
enableGradleImport: Joi.boolean().default(true),
5757
installNodeDependency: Joi.boolean().default(true),
58+
gitHostWhitelist: Joi.array()
59+
.items(Joi.string())
60+
.default([]),
61+
gitProtocolWhitelist: Joi.array()
62+
.items(Joi.string())
63+
.default([]),
5864
}).default(),
5965
maxWorkspace: Joi.number().default(5), // max workspace folder for each language server
6066
disableScheduler: Joi.boolean().default(true), // Temp option to disable all schedulers.

x-pack/plugins/code/server/init.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ async function initCodeNode(server: Server, serverOptions: ServerOptions, log: L
221221
deleteWorker,
222222
indexWorker,
223223
repoIndexInitializerFactory,
224-
repoConfigController
224+
repoConfigController,
225+
serverOptions
225226
);
226227
repositorySearchRoute(server, log);
227228
documentSearchRoute(server, log);

x-pack/plugins/code/server/queue/clone_worker.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ export class CloneWorker extends AbstractGitWorker {
3838

3939
public async executeJob(job: Job) {
4040
const { url } = job.payload;
41-
if (!isValidGitUrl(url)) {
41+
if (
42+
!isValidGitUrl(
43+
url,
44+
this.serverOptions.security.gitHostWhitelist,
45+
this.serverOptions.security.gitProtocolWhitelist
46+
)
47+
) {
4248
this.log.error(`Invalid git url ${url}`);
4349
return {
4450
uri: url,

x-pack/plugins/code/server/routes/repository.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Logger } from '../log';
1515
import { CloneWorker, DeleteWorker, IndexWorker } from '../queue';
1616
import { RepositoryConfigController } from '../repository_config_controller';
1717
import { RepositoryObjectClient } from '../search';
18+
import { ServerOptions } from '../server_options';
1819
import { EsClientWithRequest } from '../utils/esclient_with_request';
1920

2021
export function repositoryRoute(
@@ -23,7 +24,8 @@ export function repositoryRoute(
2324
deleteWorker: DeleteWorker,
2425
indexWorker: IndexWorker,
2526
repoIndexInitializerFactory: RepositoryIndexInitializerFactory,
26-
repoConfigController: RepositoryConfigController
27+
repoConfigController: RepositoryConfigController,
28+
options: ServerOptions
2729
) {
2830
// Clone a git repository
2931
server.securedRoute({
@@ -35,7 +37,13 @@ export function repositoryRoute(
3537
const log = new Logger(req.server);
3638

3739
// Reject the request if the url is an invalid git url.
38-
if (!isValidGitUrl(repoUrl)) {
40+
if (
41+
!isValidGitUrl(
42+
repoUrl,
43+
options.security.gitHostWhitelist,
44+
options.security.gitProtocolWhitelist
45+
)
46+
) {
3947
return Boom.badRequest('Invalid git url.');
4048
}
4149

x-pack/plugins/code/server/server_options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export interface SecurityOptions {
1717
enableMavenImport: boolean;
1818
enableGradleImport: boolean;
1919
installNodeDependency: boolean;
20+
gitHostWhitelist: string[];
21+
gitProtocolWhitelist: string[];
2022
}
2123

2224
export class ServerOptions {

0 commit comments

Comments
 (0)