simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

security.md (4208B)


      1 # Security
      2 
      3 Executing arbitrary expressions like enabled by the expression parser of
      4 mathjs involves a risk in general. When you're using mathjs to let users
      5 execute arbitrary expressions, it's good to take a moment to think about
      6 possible security and stability implications, especially when running
      7 the code server side.
      8 
      9 ## Security risks
     10 
     11 A user could try to inject malicious JavaScript code via the expression
     12 parser. The expression parser of mathjs offers a sandboxed environment
     13 to execute expressions which should make this impossible. It's possible
     14 though that there are unknown security vulnerabilities, so it's important
     15 to be careful, especially when allowing server side execution of
     16 arbitrary expressions.
     17 
     18 The expression parser of mathjs parses the input in a controlled
     19 way into an expression tree or abstract syntax tree (AST).
     20 In a "compile" step, it does as much as possible preprocessing on the
     21 static parts of the expression, and creates a fast performing function
     22 which can be used to evaluate the expression repeatedly using a
     23 dynamically passed scope.
     24 
     25 The parser actively prevents access to JavaScripts internal `eval` and
     26 `new Function` which are the main cause of security attacks. Mathjs
     27 versions 4 and newer does not use JavaScript's `eval` under the hood.
     28 Version 3 and older did use `eval` for the compile step. This is not
     29 directly a security issue but results in a larger possible attack surface.
     30 
     31 When running a node.js server, it's good to be aware of the different
     32 types of security risks. The risk whe running inside a browser may be
     33 limited though it's good to be aware of [Cross side scripting (XSS)](https://www.wikiwand.com/en/Cross-site_scripting) vulnerabilities. A nice overview of
     34 security risks of a node.js servers is listed in an article [Node.js security checklist](https://blog.risingstack.com/node-js-security-checklist/) by Gergely Nemeth.
     35 
     36 ### Less vulnerable expression parser
     37 
     38 There is a small number of functions which yield the biggest security
     39 risk in the expression parser:
     40 
     41 - `import` and `createUnit` which alter the built-in functionality and
     42   allow overriding existing functions and units.
     43 - `evaluate`, `parse`, `simplify`, and `derivative` which parse arbitrary
     44   input into a manipulable expression tree.
     45 
     46 To make the expression parser less vulnerable whilst still supporting
     47 most functionality, these functions can be disabled:
     48 
     49 ```js
     50 import { create, all } from 'mathjs'
     51 
     52 const math = create(all)
     53 const limitedEvaluate = math.evaluate
     54 
     55 math.import({
     56   'import':     function () { throw new Error('Function import is disabled') },
     57   'createUnit': function () { throw new Error('Function createUnit is disabled') },
     58   'evaluate':   function () { throw new Error('Function evaluate is disabled') },
     59   'parse':      function () { throw new Error('Function parse is disabled') },
     60   'simplify':   function () { throw new Error('Function simplify is disabled') },
     61   'derivative': function () { throw new Error('Function derivative is disabled') }
     62 }, { override: true })
     63 
     64 console.log(limitedEvaluate('sqrt(16)'))     // Ok, 4
     65 console.log(limitedEvaluate('parse("2+3")')) // Error: Function parse is disabled
     66 ```
     67 
     68 
     69 ### Found a security vulnerability? Please report in private!
     70 
     71 You found a security vulnerability? Awesome! We hope you don't have bad
     72 intentions and want to help fix the issue. Please report the
     73 vulnerability in a private way by contacting one of the maintainers
     74 via mail or an other private channel. That way we can work together
     75 on a fix before sharing the issue with everybody including the bad guys.
     76 
     77 ## Stability risks
     78 
     79 A user could accidentally or on purpose execute a
     80 heavy expression like creating a huge matrix. That can let the
     81 JavaScript engine run out of memory or freeze it when the CPU goes
     82 to 100% for a long time.
     83 
     84 To protect against this sort of issue, one can run the expression parser
     85 in a separate Web Worker or child_process, so it can't affect the
     86 main process. The workers can be killed when it runs for too
     87 long or consumes too much memory. A useful library in this regard
     88 is [workerpool](https://github.com/josdejong/workerpool), which makes
     89 it easy to manage a pool of workers in both browser and node.js.