Skip to content

ZackeryRSmith/cval

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Cval logo

Cval

A layer of protection for eval
View Examples · Report Bug

Installation

I know many people don't care about the motives behind a program, so I have put the installation at the top.

Unix and Mac

python3 -m pip install cval

Windows

py -m pip install cval

About

A decently simple script that uses regular expression to add a layer of protection to eval. Why? Well I keep seeing "eval really is dangerous" and "eval is a bad practice". All these statements have some validity to them, and there is almost always a better way to do what you want to acomplish. Cval tackles the "eval really is dangerous" mindset, if you must use eval for a public project use cval.

Exploiting

I encourage you to break my script, report any bugs or vulnerabilities here, thanks!

Examples

These examples are focused purely on security rather then real world practical examples.

Disable module importing
# :NOTE: modules is False by default, and the reason we allow function calls
#        is to see the error given when trying to import a module.
cval('__import__("os")', calls=True, modules=False)
Output:
cval.IllegalSource: Cval panicked due to an attempted illegal import of the module "os"
Allow certain modules
cval('__import__("os")', allowed_modules=["os"], allowed_calls=["import"])
Disable function calls
cval('print("Hello, World!")', calls=False)
Output:
cval.IllegalSource: Cval panicked due to an illegal function call in source! Attemped call to "print"
Allow certain function calls
cval('print("Hello, World!")', allowed_calls=["print"])
Block access to global variables
foo = "bar"

def foobar():
    # :NOTE: `globals` doesn't need to be passed in this case
    #        this is only done here for clarity 
    cval('print(foo)', globals=globals(), allowed_calls=["print"])  # Will not be able to access "foo"
foobar()
Output:
cval.SuspiciousSource: Cval found global variable "foo" in the source, killing for safety.
Allow some access to global variables
foo = "bar"

def foobar():
    cval('print(foo)', globals=globals(), allowed_global_vars=["foo"], allowed_calls=["print"])
foobar()
Output:
bar
Allow access to all global variables
foo = "bar"
bar = "foo"

def foobar():
    cval('print(bar+foo")', globals=globals(), allowed_global_vars=["*"], allowed_calls=["print"])
foobar()
Output:
foobar
Block access local variables
def fizzbuzz():
    fizz = "buzz"
    cval('print(fizz)', locals=locals())  # Will not be able to access "fizz"
fizzbuzz()
Output:
cval.SuspiciousSource: Cval found local variable "fizz" in the source, killing for safety.
Allow some access to local variables
def fizzbuzz():
    fizz = "buzz"
    cval('print(fizz)', locals=locals(), allowed_local_vars=["fizz"], allowed_calls=["print"])
fizzbuzz()
Output:
buzz
Allow access to all local variables
def fizzbuzz():
    fizz = "buzz"
    buzz = "fizz"
    cval('print(buzz+fizz)', locals=locals(), allowed_local_vars=["*"], allowed_calls=["print"])
fizzbuzz()
Output:
fizzbuzz