Questions about this topic? Sign up to ask in the talk tab.
Difference between revisions of "Anonymous function calls"
From NetSec
(Created page with " Unsafe programmatic construct referencing Dynamic referencing of functions and classes through user input is dangerous and should never be done, some examples are listed ...") |
(→Mitigation) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | Unsafe programmatic construct referencing | |
− | + | Dynamic referencing of functions and classes through user input is dangerous and should never be done, some examples are listed below. | |
− | + | ||
− | + | === Unsafe [[PHP]] examples === | |
− | + | * Anonymous function implementation example: | |
− | + | {{code|text=<source lang="php"><?php | |
− | + | $func = $_GET['func']; | |
− | + | $func($args); | |
− | + | ?></source>}} | |
− | + | * Anonymous object implementation example: | |
− | + | {{code|text=<source lang="php"><?php | |
− | + | $class = $_GET['object_type']; | |
− | + | $object = new $class(); | |
− | + | ?></source>}} | |
− | + | * Anonymous object method implementation example: | |
− | + | {{code|text=<source lang="php"><?php | |
− | + | $class = $_GET['object_type']; | |
− | + | $method = $_GET['method']; | |
− | + | $object = new $class(); | |
− | + | $object->$method(); | |
− | + | ?></source>}} | |
− | + | ||
− | + | === Unsafe [[Perl]] examples === | |
− | + | * Anonymous function implementation example: | |
− | + | {{code|text=<source lang="perl">#!/usr/bin/perl | |
− | + | $func = <>; | |
− | + | $func->();</source>}} | |
− | + | * Anonymous object implementation example: | |
− | + | {{code|text=<source lang="perl">#!/usr/bin/perl | |
− | + | $class = <>; | |
− | + | $object = $class->new();</source>}} | |
− | + | * Anonymous object method implementation example: | |
− | + | {{code|text=<source lang="perl">#!/usr/bin/perl | |
− | + | $class = <>; | |
− | + | $method = <>; | |
+ | $object = $class->new()->method();</source>}} | ||
− | + | === Unsafe [[Python]] examples === | |
− | + | * Anonymous function implementation example: | |
− | + | {{code|text=<source lang="python">var = "function_name" | |
− | + | locals()[var]() # or globals()</source>}} | |
− | + | * Anonymous object implementation example: | |
− | + | {{code|text=<source lang="python">class_name = input() | |
− | + | instance = globals()[class_name]() | |
− | + | # OR | |
− | + | instance = locals()[class_name]() | |
− | + | # OR | |
− | + | any_scoped_class = lambda x: dict(target for classlist in [inspect.getmembers(sys.modules[module],inspect.isclass) for module in sys.modules] for target in classlist)[x]() | |
− | + | instance = any_scoped_class(class_name) | |
− | + | </source>}} | |
− | + | * Anonymous object method implementation example: | |
− | + | {{code|text=<source lang="python">ClassName = "ObjectName" | |
− | + | func_name = "object_method" | |
− | + | instance = globals()[ClassName]() | |
− | + | func = getattr(instance, func_name) | |
− | + | instance.func();</source>}} | |
− | + | ||
− | + | === Unsafe [[Ruby]] examples === | |
− | + | * Anonymous function implementation example: | |
− | + | {{code|text=<source lang="ruby">send("function_name")</source>}} | |
− | + | * Anonymous object implementation example: | |
− | + | {{code|text=<source lang="ruby">Object.const_get('ClassName').new()</source>}} | |
− | + | * Anonymous object method implementation example: | |
− | + | {{code|text=<source lang="ruby">Object.const_get("ClassName").new().send("function_name")</source>}} | |
− | + | === Mitigation === | |
− | + | These functions are best left unused unless the data is whitelisted and not directly based on user input. There is no safe way to allow users to call arbitrary (non-whitelisted) classes and functions. Do not do this! Whitelists should always be in place when referencing objects from user input. | |
− | + | ||
− | + | ||
− | + | '''Whitelisting examples:''' | |
− | + | * [[PHP]] | |
− | + | ||
− | + | {{code|text=<source lang="php"> | |
+ | <?php | ||
+ | $class_whitelist['class_name'] = 'real_class_name'; | ||
− | + | if (isset($_GET['module']) && # Check that input is defined | |
− | + | isset($class_whitelist[$_GET['module']] && # Be sure the class is in the whitelist | |
− | + | class_exists($class_whitelist[$_GET['module']])) { # even if its whitelisted, lets make sure its a class... typos exist. | |
− | + | $class = new $class_whitelist[$_GET['module']](); # new real_class_name() - this way user input isn't trusted directly for instantiation. | |
− | + | } else { | |
− | + | # Handle Error... | |
− | + | } | |
− | + | ?> | |
− | + | </source>}} | |
− | + | ||
− | + | === Auditing === | |
− | -o -name \*.rb -exec grep -EHnC2 "const_get\(\|send\(\|eval\(" '{}' \; | + | To audit: |
+ | {{code|text=<source lang="bash">find -name \*.py -exec grep -EHnC2 "[a-zA-Z0-9\)]\[[^\'\"\]]\\+\]\(" '{}' \; \ | ||
+ | -o -name \*.rb -exec grep -EHnC2 "const_get\(\|send\(\|eval\(" '{}' \; </source>}} | ||
+ | |||
+ | [[Category:Secure programming]] |
Latest revision as of 01:42, 12 May 2013
Unsafe programmatic construct referencing Dynamic referencing of functions and classes through user input is dangerous and should never be done, some examples are listed below.
Contents
Unsafe PHP examples
- Anonymous function implementation example:
<?php $func = $_GET['func']; $func($args); ?> |
- Anonymous object implementation example:
<?php $class = $_GET['object_type']; $object = new $class(); ?> |
- Anonymous object method implementation example:
<?php $class = $_GET['object_type']; $method = $_GET['method']; $object = new $class(); $object->$method(); ?> |
Unsafe Perl examples
- Anonymous function implementation example:
#!/usr/bin/perl $func = <>; $func->(); |
- Anonymous object implementation example:
#!/usr/bin/perl $class = <>; $object = $class->new(); |
- Anonymous object method implementation example:
#!/usr/bin/perl $class = <>; $method = <>; $object = $class->new()->method(); |
Unsafe Python examples
- Anonymous function implementation example:
var = "function_name" locals()[var]() # or globals() |
- Anonymous object implementation example:
class_name = input() instance = globals()[class_name]() # OR instance = locals()[class_name]() # OR any_scoped_class = lambda x: dict(target for classlist in [inspect.getmembers(sys.modules[module],inspect.isclass) for module in sys.modules] for target in classlist)[x]() instance = any_scoped_class(class_name) |
- Anonymous object method implementation example:
ClassName = "ObjectName" func_name = "object_method" instance = globals()[ClassName]() func = getattr(instance, func_name) instance.func(); |
Unsafe Ruby examples
- Anonymous function implementation example:
send("function_name") |
- Anonymous object implementation example:
Object.const_get('ClassName').new() |
- Anonymous object method implementation example:
Object.const_get("ClassName").new().send("function_name") |
Mitigation
These functions are best left unused unless the data is whitelisted and not directly based on user input. There is no safe way to allow users to call arbitrary (non-whitelisted) classes and functions. Do not do this! Whitelists should always be in place when referencing objects from user input.
Whitelisting examples:
<?php $class_whitelist['class_name'] = 'real_class_name'; if (isset($_GET['module']) && # Check that input is defined isset($class_whitelist[$_GET['module']] && # Be sure the class is in the whitelist class_exists($class_whitelist[$_GET['module']])) { # even if its whitelisted, lets make sure its a class... typos exist. $class = new $class_whitelist[$_GET['module']](); # new real_class_name() - this way user input isn't trusted directly for instantiation. } else { # Handle Error... } ?> |
Auditing
To audit:
find -name \*.py -exec grep -EHnC2 "[a-zA-Z0-9\)]\[[^\'\"\]]\\+\]\(" '{}' \; \ -o -name \*.rb -exec grep -EHnC2 "const_get\(\|send\(\|eval\(" '{}' \; |