'Setup Python App' feature on cPanel shared hosting - python

I have just found out this "feature" under my web hosting cPanel called "Setup Python App" and very much would like to play around with a nice flask app if I could however it does not seem to work so I come here looking for some help. Here is a brief description of the setup and it's symptoms:
Clicking on this takes me to a very simple page asking for a directory and URI however when "setting it up" not much information is reported back but a directory is generated with a passenger_wsgi.py file with what looks like a basic server setup however trying to land on it simply downloads the file.
passenger_wsgi.py
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
message = 'It works!\n'
version = 'Python %s\n' % sys.version.split()[0]
response = '\n'.join([message, version])
return [response.encode()]
To solve this I figured I would setup an Apache Handler to include .py under the cgi-script handlers which then makes landing on this page a simple 500 Server Error.
I am running out of ideas on how to get this working and can't find any documentation about this "Setup Python App" feature. If anyone has had experience with it I would very much appreciate some assistance. I have already reached out to web hosting support and they also do not know what is going on. I do suspect that there is a phusion passenger server that gets setup in the process but not correctly maybe? Also there doesn't seem to be a way for me to know which port it is running under and no redirect is automatically generated (I say this because when generating a Rails app an internal redirect is automatically created pointing to the correct internal port, which I would expect to happen here too).

I've had the Python file set at 644 and added the following to the top of my .htaccess file to allow both root URL and non-root URL to work:
RewriteEngine on
RewriteRule ^http://%{HTTP_HOST}%{REQUEST_URI} [END,NE]
Got this info from: https://stackoverflow.com/a/63971427/10122266
Apologies that I couldn't add this as a comment as I do not have sufficient rights yet. But this solution worked for me and it would be a pitty if this little gem is hidden from those who may arrive here.
So would appreciate if this post is not deleted.

Related

Very Lost: Flack and NYU Osiris Challenges

I am going through some CTF challenges at https://recruit.osiris.cyber.nyu.edu/challenges.
I got to one for Template Programming where the task is to "Read /flag.txt from the server. http://recruit.osiris.cyber.nyu.edu:2000"
I am not asking for a solution, but I would like some better understanding of what is going on below:
What is this code doing?
Should I be worried about running out of Debugging mode and/or using host="0.0.0.0"?
What are some resources that could help me understand this? I tried reading through the Flask documentation and the tutorialspoint page, but I am unclear as to how this doesn't just set up a local server for testing as opposed to accessing a remote server...
If I ctrl+C do I need to worry about leaving a server still running on an open port when I am not in Debugging mode?
#!/usr/bin/env python3
from flask import Flask, request, abort, render_template_string
import os.path
app = Flask(__name__)
#app.route('/', methods=['GET'])
def index():
name = request.args.get('name')
if name is not None:
return render_template_string(open('templates/hello.html').read().format(name=name))
return render_template_string(open('templates/index.html').read())
if __name__ == "__main__":
app.run(host="0.0.0.0")
I think I can answer most of these.
As you probably already figured out, Flask is a fairly basic web framework. By the look of things, what you have there is a copy of the code running at the CTF site. It displays just two pages; one that contains the initial web form (templates/index.html) and another that uses a query string variable to greet the user (templates/hello.html) when a name has been provided.
You don't really have to run this code yourself. The 0.0.0.0 host address is catch-all that matches all IPv4 addresses on the local machine, which would include local addresses like 192.168.0.1 and 127.0.0.1 as well as the IP address used for incoming connections to the server.
Like I said, this is the code running on the remote server.
I think what you need to do is find some way of crafting a request to this web service in such a way that it reveals the contents of /flag.txt instead of (or perhaps in addition to) just saying hello. A quick search for something like "flask include file vulnerability" should give you some idea of how to attack this problem.

Twisted redirect subdirectory to another domain

I'm hosting a couple domains static files with Twisted. However, for a subdirectory of the domain, I want to redirect to another domain.
For example: Serve foo.com static files, but foo.com/bar goes to foobar.com/bar
I can't seem to find anything in the Twisted docs for this scenario.
Update
I replied to Glyph that it wasn't working, but I had placed it in the wrong spot. His suggestion was, of course, absolutely correct. I should have provided more initial info. Here it is implemented:
from twisted.application import internet, service
from twisted.web import static, server, vhost, script
from twisted.web.util import Redirect
root = vhost.NameVirtualHost()
# Add a default -- htdocs
root.default=static.File("/home/foo")
root.putChild("myredirect", Redirect("http://othersite.com/myredirect"))
# Add a simple virtual host -- bar.com
root.addHost("bar", static.File("bar"))
# Add a simple virtual host -- foo.com
root.addHost("foo", static.File("/home/foo"))
application = service.Application('web')
sc = service.IServiceCollection(application)
site = server.Site(root)
i = internet.TCPServer(80, site)
i.setServiceParent(sc)
This is pretty straightforward, although it depends on how your site is set up.
Basically though,
from twisted.web.util import Redirect
fooDotComResource.putChild("bar", Redirect("http://foobar.com/bar"))

Flask 404 on Dreamhost

I am using Flask on Dreamhost. I (mostly) followed the instruction posted here https://mattcarrier.com/flask-dreamhost-setup/. I was able to successfully set up pages and direct urls to those pages, etc.
Now I want to be able to set a 404 page. I set the error handler using #app.errorhandler. The only problem is that it just returns a standard Apache 500 error page if I go to any page that doesn't have a URL set. Is this because of how Dreamhost has Apache setup? The public (static) folder is at the top level. How can I fix this?
You may want to try creating the file "missing.html" at the top level.
source: http://wiki.dreamhost.com/Creating_custom_error_pages
Edit:
To setup an error handling page from Flask itself, you do this:
from flask import render_template
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
See: http://flask.pocoo.org/docs/patterns/errorpages/
My thought is that you are getting the 500 error because Flask/Python is crashing. Do you have debugging turned on? How is your routing setup?
I found the answer here - http://blog.tuxcoder.com/2011/9/8/dreamhost_python_wsgi/
If you plan to do any active development on the Dreamhost side, this step will simplify your efforts. Werkzeug comes with a really nice debugging engine, but it does not work with the Dreamhost configuration by default.
or example, if you have a simple Python coding error in your app, it will result in the following:
In this mode, you're out of luck. The only option is to startup a local server where you can go back and test the app. In some cases it might be a big effort just to replicate the bug.
With the Werkzeug Debugger enabled and patched, you'll get a much nicer output:
Here is what it says on the Dreamhost Wiki http://wiki.dreamhost.com/Flask (in passenger_wsgi.py:
# Uncomment next two lines to enable debugging
# from werkzeug.debug import DebuggedApplication
# application = DebuggedApplication(application, evalex=True)

using wsgi script to call exe

I'm running apache, Django and wsgi. I also use this other software called SAS to do statistical analysis. Just to give you some context. My end goal is when a client hits submit on a form written in the django, the appropriate sas script is called (via a python wsgi script) which performs calculations on the server, and then redirects the client to the output page.
I have a basic script called test5.py. It looks like this:
import os
import subprocess
def application(environ, start_response):
status = '200 OK'
output = 'Running External Program!'
f = open("C:\Documents and Settings\eric\Desktop\out.txt", 'a')
f.write('hi')
f.close()
#os.system(r'start "C:\Program Files\SAS92\SASFoundation\9.2\sas.exe"')
#subprocess.call([r'C:\Program Files\SAS92\SASFoundation\9.2\sas.exe'])
#os.startfile(r'C:\Program Files\SAS92\SASFoundation\9.2\sas.exe')
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
#start_response('301 Redirect', [('Location', 'http://myserver/reports'),])
start_response(status, response_headers)
return [output]
So what happens is that the out.txt file does get created and have hi written in the file. That's quite cool. The first 3 commented lines were 3 attempts to have this same script also call sas.exe which lives on the server. I'm just trying to get any .exe to work right now, so calling paint or wordpad would be fine. Those lines however do not seems to execute in the wsgi context. If I just load the Python command line, I can get the .exes to execute just fine. Also the last comment seems to be working properly in the redirecting. I'm not sure if I need to configure apache to add executables. Please forgive me if I'm using terms incorrectly. I am still quite new to all of this.
Thanks
Hi Paulo,
I was trying to look into your last comment. I am a bit confused as to exactly what i am looking for or how to look for it. Here is some information that I have gathered. By the way i am running on windows XP and using Apache 2.2.
My apache is installed for all users as in regedit the variable ServerRoot is under HKEY_LOCAL_MACHINE (http://httpd.apache.org/docs/2.2/platform/windows.html). Also I believe SAS is installed under all users. I tested this by having my coworker sign in using her login and I still had access. I’m not sure if that is a sufficient test though.
The log I get when I run the wsgi is the following. I’m not sure if it matters that the process is empty.
[Mon Aug 20 10:33:17 2012] [info] [client 10.60.8.71] mod_wsgi (pid=5980, process='', application='..com|/test5'): Reloading WSGI script 'C:/Sites/cprm/pyscripts/test5.wsgi'.
Also I tried the .bat trick from the link I posted in the comment i posted earlier to no avail. I made a simple batch file that just echoes 'hi' and placed it in the same directory where my wsgi scripts live. I feel like there should be no access problems there, but I may be mistaken. I also just tried calling a simple python script using subprocess just to test. Also nothing happened.
Also just to show you, my httpd.conf file looks like such:
AllowOverride None
Options None
Order allow,deny
Allow from all
WSGIScriptAlias /test1 "C:/sites/cprm/pyscripts/test1.wsgi"
WSGIScriptAlias /test2 "C:/sites/cprm/pyscripts/test2.py"
WSGIScriptAlias /test3 C:/sites/cprm/pyscripts/test3.py
WSGIScriptAlias /test4 "C:/sites/cprm/pyscripts/test4.py"
WSGIScriptAlias /test5 "C:/sites/cprm/pyscripts/test5.wsgi"
WSGIScriptAlias / "C:/sites/cprm/wsgi.py"
Is this information helpful or not really? Also, am i looking for a specific environ variable or something?
Thanks again
For web applications that perform background calculations or other tasks, IMHO it is best to queue the tasks for processing instead of calling an external process from a Django view and hang everything until the task completes. This leads to better:
user experience (request returns instantly - use ajax to signal task status and present the download link once task completes)
security (background process can run under safer credentials)
scalability (tasks can be distributed among servers)
resilience (by default many webservers will send an 'error 500' if your application fails to answer under 30 seconds or so)
For a background daemon processing all entries in the queue, there are several approaches depending on how big you want to scale:
a cron job
a daemon using supervisor (or your watchdog of choice)
an AMQP module like django-celery
[edit]
The process you start from a WSGI script will run under the same user that is running the webserver. In linux it is generally 'www-data' or 'nobody', in Windows/IIS it is 'IUSR_MachineName' (or authenticated user if using IIS authentication). Check if you can start the program using the same credentials your WSGI is running under.

Output from a Python page call by a JQuery getJSON function

I'm working on a website that uses Python web.py. There is a form where the user enters input and when the submit button is hit, a python page is called (matches) using the .getJSON JQuery function show below.
function buildMatches(input){
$.getJSON("/matches", {e:input}, function(json){
//Returned JSON object is worked on
}
}
The "matches" python page grabs a value from a DB, runs some string reg ex and returns a JSON object. Everything works fine, my question is how would I be able to output something from the python page "matches" to see what is exactly happening during the reg ex operations? I've tried print "" (python 2.5), but I understand that would print to the console. I've done some research but couldn't find anything for my situation. I don't necessarily need to print it out to the HTML page, just any where where I can see what's going on. Thanks in advance for any help.
I have access to the webserver (SSH, SFTP, etc.), I tried to log by importing the logging module, below is the code I used. I could get it to log if I ran the page from the command line, but not when it is called by the JS page.
import logging
logging.basicConfig(filename='./SomeClass.log', filemode='w', level=logging.DEBUG)
class SomeClass:
logging.info('Started')
logging.info('Another log')
def __init__(self, obj):
logging.info('In the init')
def another_functio(self):
logging.info('Logging inside the function')
I've tried setting the full path of the log and I still have the same problem where the log file will only be written or updated when I run this class from the console. This doesn't work when the class is called by the webserver.
logging.basicConfig(filename='/home/.../.../.../example.log', filemode='w', level=logging.DEBUG)
Depending on how much access you have to the web server you can run your code manually so web.py uses its built-in web server. Then print statements will end up on the console.
Otherwise, have you thought about simply writing to your own log file somewhere accessible with a browser?
Thanks again for all the help. After digging more into the setup of the Apache server and Python implementation I was able to find a solution to help me see what's going and debug my web app. I saw that Apache config is setup to log errors and WSGI also blocks (pukes on) std.out. What I was able to do is redirect the print command to the Apache error log files.
print >> sys.stderr, "Debugging print with variable" + variable
Then I check the Apache error log to start debugging the web app. I thought I would share this in case anyone else ran into this problem as it was a pain for me.
Thanks again.

Categories