Hiding modules

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tommy Trojan

    Hiding modules

    Hi,

    I have a custom application in which I have a Python interpreter embedded.
    Everything works really well and Python is taking over bigger and bigger
    chunks of the hosting application (it's spreading like a cancer :-). My
    users have direct access to the interpreter through a console window. So
    they can run pretty much any code they like. Now I have some modules that I
    use in my code and that I don't want my users to access. Is there anything
    that can be done to import modules conditionally?
    I guess I could just check for import statements or write an __import__
    hook, however, I want my code still to be able to access the modules in
    question.
    Any ideas?

    Thanks,
    T


  • Miki Tebeka

    #2
    Re: Hiding modules

    Hello Tommy,

    [color=blue]
    > Is there anything that can be done to import modules conditionally?
    > Any ideas?[/color]
    Writing a custom REPL (read-eval-print-loop) should be easy enough:
    import re
    split = re.compile("\s+ ").split

    forbidden = ("os", "sys")

    def repl():
    while 1:
    s = raw_input(">>> ").strip()
    ok = 1
    if s.startswith("i mport"):
    for module in split(s.strip() )[1:]:
    if module in forbidden:
    print "can't use %s module" % module
    ok = 0
    break
    if ok:
    exec(s)

    while 1:
    repl()

    HTH.
    Miki

    Comment

    • Tommy Trojan

      #3
      Re: Hiding modules

      Mike,

      thanks for the tip. I thought along the same lines, but that doesn't get
      around the problem that the user could just embed an import in a script, or
      import a script that I provide and that internally uses the module that
      should not be exposed, i.e.:
      [color=blue][color=green][color=darkred]
      >>> import UserModule[/color][/color][/color]

      in UserModule:

      import RestrictedModul e


      This would get around the simple loop in checking the input arguments of the
      interactive prompt. It needs to be a hook that is further down in the
      system. The problem with an import hook is that it would need to distinguish
      when it is okay to import the module (when I call it) and when it is not
      okay (when my user calls it).

      Thanks,
      Thomas


      "Miki Tebeka" <miki.tebeka@zo ran.com> wrote in message
      news:4f0a9fdb.0 402160359.33f90 363@posting.goo gle.com...[color=blue]
      > Hello Tommy,
      >
      >[color=green]
      > > Is there anything that can be done to import modules conditionally?
      > > Any ideas?[/color]
      > Writing a custom REPL (read-eval-print-loop) should be easy enough:
      > import re
      > split = re.compile("\s+ ").split
      >
      > forbidden = ("os", "sys")
      >
      > def repl():
      > while 1:
      > s = raw_input(">>> ").strip()
      > ok = 1
      > if s.startswith("i mport"):
      > for module in split(s.strip() )[1:]:
      > if module in forbidden:
      > print "can't use %s module" % module
      > ok = 0
      > break
      > if ok:
      > exec(s)
      >
      > while 1:
      > repl()
      >
      > HTH.
      > Miki[/color]


      Comment

      • Josiah Carlson

        #4
        Re: Hiding modules


        import sys
        import traceback


        class MyDict(UserDict ):
        def __getitem__(sel f, key):
        try:
        raise ""
        except:
        a = traceback.extra ct_stack()
        #do all your call checking on a
        #similar checks for __setitem__

        sys.modules = MyDict(sys.modu les)

        Do as many checks on the caller that tries to access a module via
        sys.modules as you want.

        You could also replace new.module with similar attribute get and set
        permission checking, though my testing suggests that this may not be
        enough (perhaps import keeps a reference to the original version of
        new.module, or something).

        - Josiah

        Comment

        • Tommy Trojan

          #5
          Re: Hiding modules

          Josiah,

          thanks, I will check out your solution. It looks similar to an import hook
          to me. There is still a problem that the user could just reset sys.modules
          to his own dict.

          Thanks,
          Thomas


          "Josiah Carlson" <jcarlson@nospa m.uci.edu> wrote in message
          news:c0r3j8$268 $1@news.service .uci.edu...[color=blue]
          >
          > import sys
          > import traceback
          >
          >
          > class MyDict(UserDict ):
          > def __getitem__(sel f, key):
          > try:
          > raise ""
          > except:
          > a = traceback.extra ct_stack()
          > #do all your call checking on a
          > #similar checks for __setitem__
          >
          > sys.modules = MyDict(sys.modu les)
          >
          > Do as many checks on the caller that tries to access a module via
          > sys.modules as you want.
          >
          > You could also replace new.module with similar attribute get and set
          > permission checking, though my testing suggests that this may not be
          > enough (perhaps import keeps a reference to the original version of
          > new.module, or something).
          >
          > - Josiah[/color]


          Comment

          • Josiah Carlson

            #6
            Re: Hiding modules

            Tommy,

            Heh, derive all of your classes from a single base class. Call this
            base class "Restrictor " or something similarly funny. Give it the
            equivalent __getattr__ and __setattr__ controls as the MyDict example's
            __getitem__ and __setitem__.

            Now all attribute accesses (including function calls) need to be
            validated. It would slow things down considerably
            (traceback.extr act_stack() is slow), but you could restrict as much as
            you want.

            - Josiah
            [color=blue]
            > thanks, I will check out your solution. It looks similar to an import hook
            > to me. There is still a problem that the user could just reset sys.modules
            > to his own dict.
            >[color=green]
            >>import sys
            >>import traceback
            >>
            >>
            >>class MyDict(UserDict ):
            >> def __getitem__(sel f, key):
            >> try:
            >> raise ""
            >> except:
            >> a = traceback.extra ct_stack()
            >> #do all your call checking on a
            >> #similar checks for __setitem__
            >>
            >>sys.modules = MyDict(sys.modu les)[/color][/color]

            Comment

            Working...