mathjs 13.1.0 → 13.1.1

Sign up to get free protection for your applications and to get access to all the features.
package/HISTORY.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # History
2
2
 
3
+ # 2024-08-27, 13.1.1
4
+
5
+ - Fix security vulnerability in the CLI and web API allowing to call functions
6
+ `import`, `createUnit` and `reviver`, allowing to get access to the internal
7
+ math namespace and allowing arbitrary code execution. Thanks @StarlightPWN.
8
+ - Fix security vulnerability: when overwriting a `rawArgs` function with a
9
+ non-`rawArgs` function, it was still called with raw arguments. This was both
10
+ a functional issue and a security issue. Thanks @StarlightPWN.
11
+ - Fix security vulnerability: ensure that `ObjectWrappingMap` cannot delete
12
+ unsafe properties. Thanks @StarlightPWN.
13
+ - Fix: not being able to use methods and properties on arrays inside the
14
+ expression parser.
15
+
3
16
  # 2024-08-26, 13.1.0
4
17
 
5
18
  - Feat: support multiple inputs in function `map` (#3228, #3196).
package/bin/cli.js CHANGED
@@ -56,10 +56,23 @@ const PRECISION = 14 // decimals
56
56
  * "Lazy" load math.js: only require when we actually start using it.
57
57
  * This ensures the cli application looks like it loads instantly.
58
58
  * When requesting help or version number, math.js isn't even loaded.
59
- * @return {*}
59
+ * @return {{ evalute: function, parse: function, math: Object }}
60
60
  */
61
61
  function getMath () {
62
- return require('../lib/browser/math.js')
62
+ const { create, all } = require('../lib/browser/math.js')
63
+
64
+ const math = create(all)
65
+ const parse = math.parse
66
+ const evaluate = math.evaluate
67
+
68
+ // See https://mathjs.org/docs/expressions/security.html#less-vulnerable-expression-parser
69
+ math.import({
70
+ 'import': function () { throw new Error('Function import is disabled') },
71
+ 'createUnit': function () { throw new Error('Function createUnit is disabled') },
72
+ 'reviver': function () { throw new Error('Function reviver is disabled') }
73
+ }, { override: true })
74
+
75
+ return { math, parse, evaluate }
63
76
  }
64
77
 
65
78
  /**
@@ -68,7 +81,7 @@ function getMath () {
68
81
  * @param {*} value
69
82
  */
70
83
  function format (value) {
71
- const math = getMath()
84
+ const { math } = getMath()
72
85
 
73
86
  return math.format(value, {
74
87
  fn: function (value) {
@@ -88,7 +101,7 @@ function format (value) {
88
101
  * @return {[Array, String]} completions
89
102
  */
90
103
  function completer (text) {
91
- const math = getMath()
104
+ const { math } = getMath()
92
105
  let matches = []
93
106
  let keyword
94
107
  const m = /[a-zA-Z_0-9]+$/.exec(text)
@@ -183,7 +196,7 @@ function runStream (input, output, mode, parenthesis) {
183
196
  }
184
197
 
185
198
  // load math.js now, right *after* loading the prompt.
186
- const math = getMath()
199
+ const { math, parse } = getMath()
187
200
 
188
201
  // TODO: automatic insertion of 'ans' before operators like +, -, *, /
189
202
 
@@ -214,7 +227,7 @@ function runStream (input, output, mode, parenthesis) {
214
227
  case 'evaluate':
215
228
  // evaluate expression
216
229
  try {
217
- let node = math.parse(expr)
230
+ let node = parse(expr)
218
231
  let res = node.evaluate(scope)
219
232
 
220
233
  if (math.isResultSet(res)) {
@@ -288,7 +301,7 @@ function runStream (input, output, mode, parenthesis) {
288
301
  * @return {string | null} Returns the name when found, else returns null.
289
302
  */
290
303
  function findSymbolName (node) {
291
- const math = getMath()
304
+ const { math } = getMath()
292
305
  let n = node
293
306
 
294
307
  while (n) {
@@ -412,9 +425,10 @@ if (version) {
412
425
  // run a stream, can be user input or pipe input
413
426
  runStream(process.stdin, process.stdout, mode, parenthesis)
414
427
  } else {
415
- fs.stat(scripts[0], function (e, f) {
416
- if (e) {
417
- console.log(getMath().evaluate(scripts.join(' ')).toString())
428
+ fs.stat(scripts[0], function (err) {
429
+ if (err) {
430
+ const { evaluate } = getMath()
431
+ console.log(evaluate(scripts.join(' ')).toString())
418
432
  } else {
419
433
  // work through the queue of scripts
420
434
  scripts.forEach(function (arg) {