-
Notifications
You must be signed in to change notification settings - Fork 885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Tinymath with math.js #4492
Conversation
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
…t still supporting most functionality Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Codecov Report
@@ Coverage Diff @@
## main #4492 +/- ##
=======================================
Coverage 66.49% 66.50%
=======================================
Files 3402 3403 +1
Lines 65011 65021 +10
Branches 10401 10401
=======================================
+ Hits 43230 43242 +12
+ Misses 19212 19211 -1
+ Partials 2569 2568 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
153c7ac
to
46f3313
Compare
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
Signed-off-by: Danila Gulderov <gulderov@ya.ru>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we disable the following math.js functions due to security issues? How do you know these are the only functions that we need to disable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions are marked as unsafe by the mathjs documentation https://mathjs.org/docs/expressions/security.html
A user could try to inject malicious JavaScript code via the expression parser. The expression parser of mathjs offers a sandboxed environment to execute expressions which should make this impossible. It’s possible though that there are unknown security vulnerabilities, so it’s important to be careful, especially when allowing server side execution of arbitrary expressions.
The expression parser of mathjs parses the input in a controlled way into an expression tree or abstract syntax tree (AST). In a “compile” step, it does as much as possible preprocessing on the static parts of the expression, and creates a fast performing function which can be used to evaluate the expression repeatedly using a dynamically passed scope.
The parser actively prevents access to JavaScripts internal eval and new Function which are the main cause of security attacks. Mathjs versions 4 and newer does not use JavaScript’s eval under the hood.
createUnit() { | ||
throw new Error(MATH_THROW_MSG); | ||
}, | ||
evaluate() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this evaluate() function different than math.evaluate()
from line 9?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the same evaluate
function. The idea is to disable risky functions on the user side. We can find a list of all risky functions in the mathjs
documentation: https://mathjs.org/docs/expressions/security.html.
So it is possible to do: mathjs.evaluate('add(2, 2)')
.
At the same time, it is impossible to evaluate inside the evaluate function itself: mathjs.evaluate('evaluate("add(2,2)")')
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @gulderov, no issues functionality-wise, but some questions regarding the disabled functions.
Thanks for this PR.
I labelled this as |
@abbyhu2000 Thank you so much! |
@AMoo-Miki, library change could be marked as breaking for sure It is not a drop in replacement for users. But in most cases it would work as is or with minimal changes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanations!
Signed-off-by: Anan Zhuang <ananzh@amazon.com>
cypress fail but not caused by this PR. |
Description
Migrate from tinymath to math.js
Tinymath has been deprecated for several years, and as part of the modernization plan (#4306), we need to replace it.
Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants. It is maintained project with good docs.
The evaluate method can replace tinymath.evaluate with security in mind
Examples :
2 + 3
add(params.count, 3)
[a = params.count * 100, f(x) = sqrt(x), f(a)]
Examples that would NOT work:
parse
,derivative
andevaluate
are disabled as risky:[ h = parse('x^2 + x'), dh = derivative(h, 'x'), dh.evaluate({ x: params.count }) ]
Issues Resolved
closes #3655
closes #3656
closes #3657
Testing the changes
Open [eCommerce] Revenue Dashboard with sample data => Edit => Create new => New Visualization TSVB => Press +
Add Series
=> Press +Add Metric
=> Last AggregationMath
=> Variable name:count
, Expression:params.count + 10
=> Check graphCheck List
yarn test:jest