Skip to content

security risk -- restrict the input of eval in CC constructor #2877

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

Closed
robertwb opened this issue Apr 11, 2008 · 46 comments
Closed

security risk -- restrict the input of eval in CC constructor #2877

robertwb opened this issue Apr 11, 2008 · 46 comments

Comments

@robertwb
Copy link
Contributor

There are valid uses for eval() and sage_eval(), it makes it much easier to parse output from interfaces for example.

It is difficult (if not impossible) to completely sanitize arbitrary input, but one should be able to (say) write a backend that takes specific data, calls on Sage to process it, and then returns the result. For example, I might want a webpage that uses Sage to compute Julia sets, and takes as input a complex number. That the following work is scary

sage: CC("os.getpid()")
10324.0000000000
sage: CC("os.mkdir('a')")
NaN - NaN*I
sage: CC("os.rmdir('a')")
NaN - NaN*I
sage: CC("os.exec(...)")

In this ticket, one introduces restrictions on the text input to CC that prevent most of these terrible examples.

CC: @tscrim @slel @kliem @kwankyu

Component: misc

Author: Frédéric Chapoton

Branch/Commit: 57e8e9b

Reviewer: Travis Scrimshaw, Kwankyu Lee

Issue created by migration from https://trac.sagemath.org/ticket/2877

@robertwb
Copy link
Contributor Author

comment:1

See #2347 which is related.

@sagetrac-mabshoff sagetrac-mabshoff mannequin added this to the sage-3.0 milestone Apr 11, 2008
@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@jdemeyer
Copy link
Contributor

jdemeyer commented Sep 2, 2014

Reviewer: Jeroen Demeyer

@jdemeyer
Copy link
Contributor

jdemeyer commented Sep 2, 2014

comment:8

Sage is not a secure program and nobody ever claimed it was. Sanitise your input before sending it to Sage!

@embray
Copy link
Contributor

embray commented Jul 5, 2019

comment:11

A strange response coming from Jeroen. The use of sage_eval to convert arbitrary string inputs to elements of different fields is, I think, obviously bad on so many levels, and badly mishandled in several cases (e.g. some of them will catch NameErrors, but not SyntaxErrors; some will just work, but in weird ways, if you pass some arbitrary string; some are just broken as in https://ask.sagemath.org/question/47068/possible-bug-in-cc-needs-confirmation )

If you want to convert string representations of some elements of a field to actual elements of that field there should be proper parsing, not just arbitrary evals.

@embray embray reopened this Jul 5, 2019
@embray embray added this to the sage-8.9 milestone Jul 5, 2019
@vbraun
Copy link
Member

vbraun commented Jul 6, 2019

comment:12

A simpler fix would be to use a limited eval, e.g. https://newville.github.io/asteval/

The reason for the eval in CC is of course that you want to allow expressions like 2+3*I that exceed python's literal_eval capabilities.

@videlec
Copy link
Contributor

videlec commented Jul 11, 2019

comment:13

I fully agree with Erik.

The following does not work (as expected)

sage: ZZ('2**3 + 3*g - 2')
Traceback (most recent call last):
...
TypeError: unable to convert '2**3 + 3*g - 2' to an integer
sage: RR('2**2 + 3*5 - 2')
Traceback (most recent call last):
...
TypeError: unable to convert '2**3+5*I-2' to a real number

Supporting the following with CC is a nonsense

sage: CC('2**2 + 3*5 - 2')
17.0000000000000
sage: CC('erf(2)')
0.995322265018953

We don't want the element constructor to evaluate a string in hope that it gives a complex number. There should be a clear definition of what is the input format. And the constructor should just stick to specifications. The element constructor of CC is trying to do much more than what it is supposed to.

@videlec
Copy link
Contributor

videlec commented Jul 11, 2019

comment:14

And to my mind the main problem is not the security risk (I agree with Jeroen on that point). I would advice to open another ticket "fix element constructor of CC".

@embray
Copy link
Contributor

embray commented Jul 12, 2019

comment:15

It's not just CC. It's all of them. It's really flaky to allow a general eval to construct instances of some particular type. Instead, it should really just parse constant-valued expressions for whatever that type is, at the most. That can either involve custom parsing code, or as Volker suggested a custom AST parser.

@fchapoton
Copy link
Contributor

comment:26

bot is morally green, so please review

@tscrim
Copy link
Collaborator

tscrim commented Oct 20, 2021

comment:27

Do we also want to allow j to match Python's convention for complex numbers:

sage: complex('1+2j')
(1+2j)
sage: complex('1+2i')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-a2113f9c148b> in <module>
----> 1 complex('1+2i')

ValueError: complex() arg is a malformed string

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 21, 2021

Changed commit from 53f6c2a to 77031e8

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 21, 2021

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

77031e8simple-minded check for string input of CC

@fchapoton
Copy link
Contributor

comment:29

ok, done (and squashed the commits)

@fchapoton
Copy link
Contributor

comment:30

but this will break the doctest in singular.pyx... (sigh)

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 21, 2021

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

feab03fsimple-minded check for string input of CC

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 21, 2021

Changed commit from 77031e8 to feab03f

@fchapoton
Copy link
Contributor

comment:32

bot is morally green now

@kwankyu
Copy link
Collaborator

kwankyu commented Oct 22, 2021

comment:33

Sorry for late comment, but how about this?

--- a/src/sage/rings/complex_mpfr.pyx
+++ b/src/sage/rings/complex_mpfr.pyx
@@ -504,7 +504,7 @@ class ComplexField_class(sage.rings.abc.ComplexField):
             sage: CC('hello')
             Traceback (most recent call last):
             ...
-            ValueError: given string (hello) is not a complex number
+            ValueError: given string 'hello' is not a complex number
         """
         if not isinstance(x, (RealNumber, tuple)):
             if isinstance(x, ComplexDoubleElement):
@@ -516,7 +516,7 @@ class ComplexField_class(sage.rings.abc.ComplexField):
                 x = x.replace('E', 'e')
                 allowed = '+-.*0123456789Ie'
                 if not all(letter in allowed for letter in x):
-                    raise ValueError(f'given string ({x}) is not a complex number')
+                    raise ValueError(f'given string {x!r} is not a complex number')
                 # This should rather use a proper parser to validate input.
                 # TODO: this is probably not the best and most
                 # efficient way to do this.  -- Martin Albrecht

and does not express a complex number.

@tscrim
Copy link
Collaborator

tscrim commented Oct 22, 2021

comment:34

Thank you. I am also wondering a bit if we want to document that CC also supports j as a valid string input. Although I don't hold a strong opinion on this.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 22, 2021

Changed commit from feab03f to 45039da

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 22, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

45039dasome details

@fchapoton
Copy link
Contributor

comment:36

ok, done.

WARNING: note that CC('1.0+2.0*j') works, but not CC('1.0+2.0j').

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 24, 2021

Changed commit from 45039da to 57e8e9b

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 24, 2021

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

57e8e9bsimple-minded check for string input of CC

@fchapoton
Copy link
Contributor

comment:38

I fixed the failing doctest

@tscrim
Copy link
Collaborator

tscrim commented Oct 24, 2021

Reviewer: Travis Scrimshaw, Kwankyu Lee

@tscrim
Copy link
Collaborator

tscrim commented Oct 24, 2021

comment:39

Great, thank you. LGTM. Kwankyu, if you do not agree, feel free to revert the positive review.

@kwankyu
Copy link
Collaborator

kwankyu commented Oct 25, 2021

comment:40

Replying to @tscrim:

Great, thank you. LGTM. Kwankyu, if you do not agree, feel free to revert the positive review.

I fully agree. Thanks.

@slel
Copy link
Member

slel commented Oct 25, 2021

comment:41

Update ticket summary and description
to better describe the changes made here?

(Or just contract "should be able to be able to"
if the rest is still fine?)

@fchapoton
Copy link
Contributor

comment:42

voilà, voilà.

@fchapoton

This comment has been minimized.

@fchapoton fchapoton changed the title security risk -- several constructors use eval to parse input security risk -- restrict the input of eval in CC constructor Oct 25, 2021
@slel
Copy link
Member

slel commented Oct 25, 2021

comment:43

Merci.

@vbraun
Copy link
Member

vbraun commented Oct 28, 2021

Changed branch from u/chapoton/2877 to 57e8e9b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests