@forge/api 2.18.6-next.2 → 2.19.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/out/safeUrl.d.ts +1 -1
- package/out/safeUrl.d.ts.map +1 -1
- package/out/safeUrl.js +32 -13
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @forge/api
|
|
2
2
|
|
|
3
|
+
## 2.19.0-next.4
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 347359b: Better protection against path traversal attacks in product requests
|
|
8
|
+
|
|
9
|
+
## 2.18.6-next.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- ccc113ec: Bumping dependencies via Renovate:
|
|
14
|
+
|
|
15
|
+
- @types/node
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [ccc113ec]
|
|
18
|
+
- @forge/egress@1.2.4-next.2
|
|
19
|
+
- @forge/storage@1.5.8-next.2
|
|
20
|
+
|
|
3
21
|
## 2.18.6-next.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/out/safeUrl.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type Route = {
|
|
|
3
3
|
};
|
|
4
4
|
export declare function isRoute(x: unknown): x is Route;
|
|
5
5
|
export declare function routeFromAbsolute(absolutePath: string): Route;
|
|
6
|
-
export declare function route(
|
|
6
|
+
export declare function route(template: TemplateStringsArray, ...parameters: (string | number | URLSearchParams | Route)[]): Route;
|
|
7
7
|
export declare function requireSafeUrl(url: unknown): Route;
|
|
8
8
|
export declare function assumeTrustedRoute(route: string): Route;
|
|
9
9
|
//# sourceMappingURL=safeUrl.d.ts.map
|
package/out/safeUrl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safeUrl.d.ts","sourceRoot":"","sources":["../src/safeUrl.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAcF,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,CAE9C;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAG7D;
|
|
1
|
+
{"version":3,"file":"safeUrl.d.ts","sourceRoot":"","sources":["../src/safeUrl.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAcF,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,CAE9C;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAG7D;AAkCD,wBAAgB,KAAK,CACnB,QAAQ,EAAE,oBAAoB,EAC9B,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,eAAe,GAAG,KAAK,CAAC,EAAE,GAC3D,KAAK,CAoBP;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CASlD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEvD"}
|
package/out/safeUrl.js
CHANGED
|
@@ -21,27 +21,46 @@ function routeFromAbsolute(absolutePath) {
|
|
|
21
21
|
return assumeTrustedRoute(`${absoluteURL.pathname}${absoluteURL.search}`);
|
|
22
22
|
}
|
|
23
23
|
exports.routeFromAbsolute = routeFromAbsolute;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
const DOUBLE_DOT = ['..', '.%2e', '%2e.', '%2e%2e', '.%2E', '%2E.', '%2E%2e'];
|
|
25
|
+
const ENDS_PATH = ['?', '#'];
|
|
26
|
+
function containsOneOf(needles, haystack) {
|
|
27
|
+
return needles.some((needle) => haystack.includes(needle));
|
|
28
|
+
}
|
|
29
|
+
function escapeParameter(parameter, mode) {
|
|
30
|
+
switch (mode) {
|
|
31
|
+
case 'path':
|
|
32
|
+
const parameterString = isRoute(parameter) ? parameter.value : String(parameter);
|
|
33
|
+
if (containsOneOf(DOUBLE_DOT, parameterString) || containsOneOf(ENDS_PATH, parameterString)) {
|
|
34
|
+
throw new Error('Disallowing path manipulation attempt');
|
|
32
35
|
}
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
return parameterString;
|
|
37
|
+
case 'query':
|
|
38
|
+
if (isRoute(parameter)) {
|
|
39
|
+
return encodeURIComponent(parameter.value);
|
|
35
40
|
}
|
|
36
41
|
else if (parameter instanceof URLSearchParams) {
|
|
37
|
-
|
|
42
|
+
return parameter.toString();
|
|
38
43
|
}
|
|
39
44
|
else {
|
|
40
|
-
|
|
45
|
+
return encodeURIComponent(parameter);
|
|
41
46
|
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function route(template, ...parameters) {
|
|
50
|
+
let mode = 'path';
|
|
51
|
+
let result = '';
|
|
52
|
+
for (let i = 0; i < template.length; i++) {
|
|
53
|
+
const templateFragment = template[i];
|
|
54
|
+
if (containsOneOf(ENDS_PATH, templateFragment)) {
|
|
55
|
+
mode = 'query';
|
|
56
|
+
}
|
|
57
|
+
result += templateFragment;
|
|
58
|
+
if (i >= parameters.length) {
|
|
59
|
+
break;
|
|
42
60
|
}
|
|
61
|
+
result += escapeParameter(parameters[i], mode);
|
|
43
62
|
}
|
|
44
|
-
return new ReadonlyRoute(
|
|
63
|
+
return new ReadonlyRoute(result);
|
|
45
64
|
}
|
|
46
65
|
exports.route = route;
|
|
47
66
|
function requireSafeUrl(url) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/api",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0-next.4",
|
|
4
4
|
"description": "Forge API methods",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
"compile": "tsc -b -v"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@forge/runtime": "5.0.1-next.
|
|
16
|
-
"@types/node": "14.18.
|
|
15
|
+
"@forge/runtime": "5.0.1-next.5",
|
|
16
|
+
"@types/node": "14.18.57",
|
|
17
17
|
"jest-matcher-specific-error": "^1.0.0",
|
|
18
18
|
"nock": "^10.0.6"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@forge/auth": "0.0.5",
|
|
22
|
-
"@forge/egress": "1.2.4-next.
|
|
23
|
-
"@forge/storage": "1.5.8-next.
|
|
22
|
+
"@forge/egress": "1.2.4-next.2",
|
|
23
|
+
"@forge/storage": "1.5.8-next.2",
|
|
24
24
|
"@forge/util": "1.3.1",
|
|
25
25
|
"@types/node-fetch": "^2.6.4",
|
|
26
26
|
"node-fetch": "2.7.0"
|