-
Notifications
You must be signed in to change notification settings - Fork 934
Expand file tree
/
Copy pathopenURLMiddleware.ts
More file actions
73 lines (61 loc) · 1.88 KB
/
openURLMiddleware.ts
File metadata and controls
73 lines (61 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type {IncomingMessage, ServerResponse} from 'http';
import {json} from 'body-parser';
import connect from 'connect';
import open from 'open';
/**
* Open a URL in the system browser.
*/
export async function openURLMiddleware(
req: IncomingMessage & {
// Populated by body-parser
body?: Object;
},
res: ServerResponse,
next: (err?: Error) => void,
) {
if (req.method === 'POST') {
if (req.body == null) {
res.writeHead(400);
res.end('Missing request body');
return;
}
const {url} = req.body as {url: string};
if (typeof url !== 'string') {
res.writeHead(400);
res.end('URL must be a string');
return;
}
let parsedUrl: URL;
try {
parsedUrl = new URL(url);
} catch (error) {
res.writeHead(400);
res.end('Invalid URL format');
return;
}
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
res.writeHead(400);
res.end('Invalid URL protocol');
return;
}
// Reconstruct URL with proper encoding to prevent command injection
// The URL constructor doesn't automatically encode special characters like | in query strings,
// which can be interpreted as shell commands.
// So we create a new URL object with sanitized components to prevent command injection.
const sanitizedUrl = new URL(parsedUrl.origin);
sanitizedUrl.pathname = encodeURI(parsedUrl.pathname);
sanitizedUrl.search = new URLSearchParams(parsedUrl.search).toString();
sanitizedUrl.hash = encodeURI(parsedUrl.hash);
await open(sanitizedUrl.href);
res.writeHead(200);
res.end();
}
next();
}
export default connect().use(json()).use(openURLMiddleware);