Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Apr 30th, 2006, 1:31 PM   #1
Dietrich
Professional Programmer
 
Dietrich's Avatar
 
Join Date: Feb 2005
Posts: 434
Rep Power: 4 Dietrich is on a distinguished road
Smile Remote Python

One of the problems with Python is the following. You have a Python idea (can happen!), but the computer you have access to does not have Python installed (shame on them!).

I would love to see a website that you can run your Python codes on in a pinch, remote so to speak. Is there something like that out there? I know there is a Ruby site that can do this.
__________________
I looked it up on the Intergnats!
Dietrich is offline   Reply With Quote
Old Apr 30th, 2006, 2:03 PM   #2
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,835
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
There used to be one advertised on IRC. But I don't believe it's up anymore.

If anyone could show me how to parse lines that import modules, out of any code, I'd put this up on my site. The only reason I haven't made this yet, is I'm afraid someone will call the os module and delete my computer, or something else.

And no, it can't be as simple as
if 'import' in code:
    return False
... sort of thing. Since they could do something like this:
exec "impor"+"t os"
... and my little if statement wouldn't catch it. And they'd have the os module imported. So if you can figure someway to prevent this, I might add this to my site.
Sane is offline   Reply With Quote
Old Apr 30th, 2006, 4:47 PM   #3
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Python doesn't have sandboxing (the technique of running code with limited priviledges), but you could see about using chroot, restricted user priviledges, and CPU and RAM limits to achieve the same result.
Arevos is offline   Reply With Quote
Old Apr 30th, 2006, 7:59 PM   #4
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,835
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
All right, I decided to try tackling it.

I couldn't figure out the chroot(). I found some posts talking about os.chroot(2), but that function doesn't exist. I also found the rexec module and some other, but those don't really seem to work properly.

I had to figure out how to make my own restrict function. I hope I did that properly. It was mostly a guess on my part for how to restrict the usage of functions like raw_input, input and open.

Well here's what I got so far.

# does not support multiline prints
# does not support ',' as part of print statement


import random


def get_between(t, s, e):
    return t.split(s)[-1].split(e)[0]


"""replace a function with your own
based on a filter's result to the paramters"""
def restrict(func, filt):
        def new_func(*args, **kwargs):
                if filt(*args, **kwargs):
                        return func(*args, **kwargs)
                else:
                        raise Exception, 'Permission Denied in "' + func.__name__ + '"'
                    
        return new_func    


"""this filter will always block the use
of the function, hence the name, 'lock'""" 
def filter_lock(*args, **kwargs):
        return False


open      = restrict(open, filter_lock)
raw_input = restrict(raw_input, filter_lock)
input     = restrict(input, filter_lock)





class run:

        def run_code(self, code):
                exec code
        

        def pad_code(self, code):
                # "security key" to prevent tampering with the result variable
                self.rand_key = ''.join( str(random.randrange(10)) for c in range(5) )

                # form code to replace print with string concatenation
                new_code = 'self.__res' + self.rand_key + '__ = ""\n'

                find = ''
                code = '\n'+code+'\n'
                while find != code:
                    if find:
                        code = code.replace('print%s\n'%find,
                                            'self.__res%s__ += str(%s)+"\\n"\n'%(self.rand_key, find))
                    find = get_between(code, 'print', '\n')

                    if not find:
                        break
                
                new_code += code

                return new_code


        def exc_code(self, code):
                new_code = self.pad_code(code)
                try:
                        self.run_code(new_code)
                except Exception, e:
                        return e, new_code

                return getattr(self, '__res%s__'%self.rand_key), new_code



if __name__ == '__main__':

        # an example of the code a user could give
        code = """
def prime(n):
    for i in range(2, n):
        if not n%i:
            return False
    return True

for i in range(2, 100):
    print "%s: %s"%(i, prime(i))
"""

        session = run()
        result, code = session.exc_code(code)

        # the result of the output to return to the user
        print result

        # print code # (debug purposes)

        # an example of some code restrictions
        result, code = session.exc_code("raw_input('test')")
        print result
        print code

I think it works fairly nicely.

One thing that I just realised is that they could tamper with the "self" variables...

To solve this I could change run_code to an independent function, which then returns the __res%s__ var.
Sane is offline   Reply With Quote
Old Apr 30th, 2006, 8:25 PM   #5
Yarvin
Programmer
 
Join Date: Sep 2005
Location: Anchorage, Alaska
Posts: 37
Rep Power: 0 Yarvin is on a distinguished road
I've heard of sites that have the python interpreter on them... and I used one once.. a very long time ago when I first started python. but I haven't been able to find them lately....

another idea would be to install python onto a thumb drive ^_^
Yarvin is offline   Reply With Quote
Old May 1st, 2006, 9:42 AM   #6
Dietrich
Professional Programmer
 
Dietrich's Avatar
 
Join Date: Feb 2005
Posts: 434
Rep Power: 4 Dietrich is on a distinguished road
Smile

A version of Python that installs onto a thumb drive is available for a price (used to be free!). It's called "movable Python". Now you have to remember (can be done!) to take that thumb drive with you and hope the other machine has a matching OS.
__________________
I looked it up on the Intergnats!
Dietrich is offline   Reply With Quote
Old May 1st, 2006, 11:39 AM   #7
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by Sane
All right, I decided to try tackling it.

I couldn't figure out the chroot(). I found some posts talking about os.chroot(2), but that function doesn't exist. I also found the rexec module and some other, but those don't really seem to work properly.
chroot is a Linux command. It changes the root directory for the program being executed so that it runs in a "chroot jail". Even if the user were to get access to the filesystem, he cannot ascend any higher than the directory you chrooted him to. He's trapped in a subdirectory, without any access to anything outside it.

os.chroot exists in Linux, but not in Windows. Still, you might as well use the system chroot rather than the Linux one. chrooting programs correctly takes some knowledge, but there are plenty of tutorials out there dealing with chroots. It's a common security measue when you need touch security.

If you want to give remote users access to Python, a chroot jail is the very least you should do. There's no other way to guarentee that the user can't access the rest of your filesystem without using a dedicated system. No amount of code checking can feasibly prevent all attacks.

You should also run the Python interpretor with limited user priviledges (create a user called something like "pythonuser" that belongs to no extra groups), and then limit that user via /etc/security/limits.conf to a fixed quota of RAM and CPU. That way, you can ensure that any attacker doesn't flood your system with a DOS attack.

You could also limit your system to accept connections from only trusted users.
Arevos is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:55 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC