Questions about this topic? Sign up to ask in the talk tab.

Anonymous function calls

From NetSec
Revision as of 11:02, 2 December 2012 by JtRIPper (Talk | contribs) (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 ...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
   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:
          <?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:
         <?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\(" '{}' \; &>  string_comparison.txt