@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.
@@ -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
- basepath = (basepath) ? path.normalize(basepath) : null;
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
- return path.resolve(from, to);
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinostone/swig-core",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "Shared IR, backend, and runtime for the @rhinostone/swig family of template engines.",
5
5
  "keywords": [
6
6
  "template",