Restrict python exec acess to one directory - python

I have a python script which executes a string of code with the exec function. I need a way to restrict the read/write access of the script to the current directory. How can I achieve this?
Or, is there a way to restrict the python script's environment directly through the command line so that when I run the interpreter, it does not allow writes out of the directory? Can I do that using a virtualenv? How?
So basically, my app is a web portal where people can write and execute python apps and get a response - and I've hosted this on heroku. Now there might be multiple users with multiple folders and no user should have access to other's folders or even system files and folders. The permissions should be determined by the user on the nodejs app (a web app) and not a local user. How do I achieve that?

Execute the code as a user that only owns that specific directory and has no permissions anywhere else?
However- if you do not completely trust the source of code, you should simply not be using exec under any circumstances. Remember, say you came up with a python solution... the exec code could literally undo whatever restrictions you put on it before doing its nefarious deeds. If you tell us the problem you're trying to solve, we can probably come up with a better idea.

The question boils down to: How can I safely execute the code I don't trust.
You can't.
Either you know what the code does or you don't execute it.
You can have an isolated environment for your process, for example with docker. But the use cases are far away from executing unsafe code.

Related

Restrict execution of Python scripts (to certain folder)

Im working in an architecture firm where we are trying to use the Python API for ArchiCAD.
It allows us some much needed automation for certain workflows, but we still haven't used it, because we don't know how to limit the users right to execute Pyhton.
We are planning to put some Python Scripts on an internal server and our co-workers would be able to use the "ArchiCAD Palette" to execute the scripts from the Server.
But we are currently worried that a person could write tehir own script and harm our projects etc, or delete data w/e.
So we were thinking about only allowing the Execution of Python scripts from a certain folder.
->The Folder would be read-only for users so they cant throw in their own scripts
Is it possible to do that?
If not, can anyone recommend a way were we can limit our co-workers to use only our self-written scripts but prevent them from running anything harmful?
Thanks for any Help
Kind Regards
Dayiz

Making sure that a script does not modify files in specific folder

I'm writing a python script which copies files from a server, performs a few operations on them, and delete the files locally after processing.
The script is not supposed to modify the files on the server in any way.
However, since bugs may occur, I would like to make sure that I'm not modifying\deleting the original server files.
Is there a way to prevent a python script from having writing permissions to a specific folder? I work on Windows OS.
That is unrelated to Python, but to the filesystem security provided by the OS. The key is that permissions are not given to programs but to the user under which they run.
Windows provides the command runas that allows to run a command (whatever the language is uses) under a different user. There is even a /savecred option that allows not to provide the password on each activation but instead save in in the current user's profile.
So if you setup a dedicated user to run the scrip, give it only read permissions on the server folder and run the scrip under that user, then even a bug in the script could not tamper that folder.
BTW, if the script is runned as a scheduled task, you can directly say what user should be used and give its password at config time.

Using the GAE remote_api to Create Local Scripts

I'm trying to do some local processing of data entries from the GAE datastore and I am trying to do this by using the remote_api. I just want to write some quick processing scripts that pull some data, but I am getting import errors saying that Python cannot import from google.
Am I supposed to run the script from within the development environment somehow. Or perhaps I need to include all of the google stuff in my Python path? That seems excessive though.
Why is including the paths that onerous ?
Normally the remote_api shell is used interactively but it is a good tool that you can use as the basis of acheiving what your want.
The simplest way will be to copy and modify the remote_api shell so that rather than presenting an interactive shell you get it to run a named script.
That way it will deal with all the path setup.
In the past I have integrated the remote_api inside a zope server, so that plone could publish stuff to appengine. All sort of things are possible with remote_api, however you need to deal with imports like anything else in python, except that appengine libraries are not installed in site-packages.

Local development (invoking python <script>, port 8888) serves stale files

I had a similar issue when running fast-cgi and I was told there is no way to fix it: Files being served are stale / cached ; Python as fcgi + web.py + nginx without doing custom work. I was told to use the python method, which invokes a local "web server" to host the python page.
Even doing that, the files served are stale / cached. If I make edits to the files, save and refresh, the python web server is still serving the stale / cached file.
The only way to get it to serve the modified file is to kill (ctrl+c) the script, and then restart...this takes about 5 seconds every-time and seriously impedes my development workflow.
Ideally any change to the script would be reflected next time the page is requested from the web server.
EDIT
#Jordan: Thanks for the suggestions. I've tried #2, which yields the following error:
app = web.application(urls, globals(), web.reloader)
AttributeError: 'module' object has no attribute 'reloader'
Per the documentation here: http://webpy.org/tutorial2.en
I then tried suggestion #4,
web.config.debug = True
Both still cause 'stale' files to get served.
Understandably you want a simple, set it up once and never worry about it again, solution. But you might be making this problem more difficult than it needs to be.
I generally write applications for an apache/modwsgi/nginx stack. If I have a caching problem, I just restart apache and voila, my python files are re-interpreted. I don't remember the commands to restart apache on all of my different boxes (mac's, ubuntu, centos, etc), and I shouldn't need to.
That is what command line aliases are for...
A python application is interpreted before it is run, and when run on a webserver, it is run once and should be considered stateless. This is unlike javascript running in a browser, which can be considered to have state since it is a continually running VM. You can edit javascript while it is running and that is probably fine for most applications of the language.
In python you generally write the code, run it, and if that doesn't work you start over. You don't edit the code in real time. That means you are knowingly saving the source and changing contexts to run it.
I am betting that you are editing your source from a Graphical IDE instead of a command-line editor like vi or emacs (I might be wrong, and I'm not saying there is anything 'wrong' with that). I only write iOS applications using an IDE, everything else I stick to ViM. Why? Because then I am always on the command line, and I am not distracted by anything (animations, mouse pointers, notifications). I finish writing my code, i quickly type ':wq' (write and quit), and then quickly type 'restartweb' (actually i usually type 're' then <\tab> to auto-complete) which is my alias to whatever the command to restart apache is. Voila my python is reinterpreted.
My point is that you should probably keep it simple and use something like an alias to solve your problem. It might not be the coolest thing you could do. But it is what Ninja coders have been doing for the last 20 years to get work done fast and simple.
Now obviously I only suggested a solution for apache, and I have never used web.py before. But the same possible solution still applies. Make a bash script that goes in your project directory, call it something like restart.bash. In it put something like:
rm -r *.pyc
Which will recursively remove all compiled pyc files, forcing your app to reload. Then make an alias in your ~/.bashrc that runs that file
Something like:
alias restartproject="bash /full/path/to/restart.bash"
Magical, now you have a solution that works everywhere, regardless of which type of web server you choose to run your application from.
Edit:
Now you have a solution that works everywhere but on a Windows IIS server. And if you are trying to run python from Windows, you should probably Stahp! hugz
We are using virtualenv right? :) We want to keep our python nice and system-agnostic so we can sell it to anyone right? :) And you should really check out ViM and emacs if you don't use them... you will bang your head against the wall for a week getting used to it, then never want to touch a mouse again after that.
Right, so Python is a compiled language when run on a web server. It's outputting a .pyc file that's the compiled version. Your goal is to tell the web server that the .pyc file is out of date and is no longer valid.
You have a few options:
Delete the relevant .pyc file
For web.py, use the reloader middleware
Send it a HUP signal (I'm lazy and usually do killall -SIGHUP python). You can do this automatically with a file watching tool like watchdog (thanks barracel).
web.config.debug = True should be the default in your application
None of those options are working for you?

Executing Python program on web

Can I use os.system() or subprocess.call() to execute a Python program on a webserver?
I mean can I write these functions in a .py script and run it from a web browser and expect the program to be executed?
Thanks a lot.
EDIT:
Sorry for all the confusion, I am giving you more background to my problem.
The reason I am trying to do is this.
I have a Python program that accepts an XML file and returns me TTF file.
I run that program in terminal like this:
ttx somefile.xml
After which it does all the work and generates a ttf file.
Now when I deploy this script as a module on web server. I use a to allow user to browse and select the XML file.
Then I read the file data to temporary file and then pass the file to the module script to be executed like this:
ttx.main([temp_filename])
Is this right way to do it? Because at this point, I don't get any error in the log or in browser. I get blank screen.
When this didn't work, I was going to try os.system or subprocess.call
You do not use os.system or subprocess.call to execute something as a cgi process.
Maybe you should read the Python cgi tutorial here:
http://www.cs.virginia.edu/~lab2q/
If you want your cgi process to communicate with another process on your local machine, you might want to look at "REST frameworks" for Python.
So long as your server is configured to run CGI scripts (Apache's documentation for that is here, for example), yes, you can execute a python script from a webserver. Simply make sure the script is in the appropriate cgi-bin/ directory and that the file has executable permission on the server.
With regards to your comments:
You can, if you really want, explicitly allow other folders on the server to run executable code. I don't know what server you're using, but on Apache this is done by setting Option +ExecCGI for the folder you want. Again, see the docs I linked to.
You need to give an absolute path with respect to the server. As an example, a site I develop has the layout: /public_html/cgi-bin/ When I want to access .cgi or .py files, the url for the site is something like http://chess.narnia.homeunix.com/cgi-bin/index.cgi. You can also set up re-directs to certain files if you want.
One way to pass parameters through your browser is to append them to the URL like an HTTP POST method. Here's a good example of doing that.
Is that what you were looking for with your question, or did you want to actually invoke the python script with os.system()?
Yes, I do it all the time. Import as you would do normally, stick your .py in your cgi-bin folder and make sure the server is capable of handling python.
Another option would be to simply create an application on Google's App Engine. That gives you oodles of resources and APIs for Python execution.
http://code.google.com/appengine
I've done it quite a bit in classic ASP on IIS 5 and above. I would have the ASP engine execute python code (instead of, e.g., vbscript (hearkening back to the old days, here)). Behind those asp pages would be python modules written in straight python that could be imported and could execute pretty much arbitrary code. As others have mentioned, the effective user needs to have execute permission on the thing you're trying to execute.

Categories