@rhinostone/swig-core 2.7.0 → 2.7.2
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/lib/loaders/filesystem.js +24 -3
- package/package.json +1 -1
|
@@ -11,12 +11,18 @@ var fs = require('fs'),
|
|
|
11
11
|
* swig.setDefaults({ loader: swig.loaders.fs(__dirname + '/templates' )});
|
|
12
12
|
* @param {string} [basepath=''] Path to the templates as string. Assigning this value allows you to use semi-absolute paths to templates instead of relative paths.
|
|
13
13
|
* @param {string} [encoding='utf8'] Template encoding
|
|
14
|
+
* @param {boolean} [allowOutsideRoot=false] When false (default) and a <var>basepath</var> is set, template paths that resolve outside the basepath root are rejected (CVE-2023-25345 path-traversal hardening). Set true to permit includes / extends that intentionally read files from outside the template root.
|
|
14
15
|
*/
|
|
15
|
-
module.exports = function (basepath, encoding) {
|
|
16
|
+
module.exports = function (basepath, encoding, allowOutsideRoot) {
|
|
16
17
|
var ret = {};
|
|
17
18
|
|
|
18
19
|
encoding = encoding || 'utf8';
|
|
19
|
-
|
|
20
|
+
// Resolve (not merely normalize) basepath to an absolute path. The root
|
|
21
|
+
// check in resolve() compares it against path.resolve()'d template paths,
|
|
22
|
+
// which are always absolute, so a relative basepath must be made absolute
|
|
23
|
+
// too -- otherwise every in-root path is wrongly rejected (CVE-2023-25345
|
|
24
|
+
// confinement must not break the legitimate relative-basepath mode).
|
|
25
|
+
basepath = (basepath) ? path.resolve(basepath) : null;
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
28
|
* Resolves <var>to</var> to an absolute path or unique identifier. This is used for building correct, normalized, and absolute paths to a given template.
|
|
@@ -26,12 +32,27 @@ module.exports = function (basepath, encoding) {
|
|
|
26
32
|
* @return {string}
|
|
27
33
|
*/
|
|
28
34
|
ret.resolve = function (to, from) {
|
|
35
|
+
var resolved, rootWithSep;
|
|
29
36
|
if (basepath) {
|
|
30
37
|
from = basepath;
|
|
31
38
|
} else {
|
|
32
39
|
from = (from) ? path.dirname(from) : process.cwd();
|
|
33
40
|
}
|
|
34
|
-
|
|
41
|
+
resolved = path.resolve(from, to);
|
|
42
|
+
|
|
43
|
+
// CVE-2023-25345: reject include / extends / import paths that resolve
|
|
44
|
+
// outside the configured loader root (e.g. "../../../etc/passwd"),
|
|
45
|
+
// including when the path is supplied by an untrusted runtime variable
|
|
46
|
+
// ({% include userVar %}). Enforced only when a basepath defines the
|
|
47
|
+
// root; pass allowOutsideRoot === true to opt out for the rare case of
|
|
48
|
+
// legitimately including files from outside the template root.
|
|
49
|
+
if (basepath && !allowOutsideRoot) {
|
|
50
|
+
rootWithSep = path.normalize(basepath + path.sep);
|
|
51
|
+
if (resolved !== basepath && resolved.indexOf(rootWithSep) !== 0) {
|
|
52
|
+
throw new Error('Template "' + to + '" resolves outside the loader root "' + basepath + '" (CVE-2023-25345).');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return resolved;
|
|
35
56
|
};
|
|
36
57
|
|
|
37
58
|
/**
|