Using webapp2's DomainRoute on google app engine - python

I'm trying to use webapp2's DomainRoute to route requess to specific users. The definition of the routes looks like this:
app = webapp2.WSGIApplication([
DomainRoute("<subdomain>." + os.environ["HTTP_HOST"], [
webapp2.Route('/',ClientHandler)]),
('/', MainHandler)],
debug=True)
the handlers all exist, and currently, my ClientHandler should just spit out the current subdomain but when I currently go to nosub.localhost:8090 it doesn't even reach the server. Do I need to edit my hosts file? And if so, is it valid to add a wildcart like *.localhost so any subdomain will work?

Yes, you need to edit your hosts file - whatever.localhost does not automatically resolve to 127.0.0.1. Alternately, save yourself some time and use xip.io.
Your code has a significant problem, though: you're using os.environ["HTTP_HOST"] in a context that only gets run on the first request. This means that you extract the hostname from the first request to your app and use that as a base name for it and all subsequent requests - which is pretty definitely not what you want. For instance, if the first user to your app instance comes from subdomain.myapp.com, you'll set up a route for subdomain.subdomain.myapp.com.

Related

Is it possible to get flask app url without request context?

It's a URL shortener app. The app structure is like following:
App structure
In forms.py, I have custom validators: validate_url() and validate_short_url()
that use APP_URL; APP_URL = "localhost:5000/"
I'm fine with that running locally, but there is a lot of cases app domain can change:
Running through docker image;
Hosting (e.g. on Heroku);
Changing the port value;
So every time I run this flask app differently I have to change the value of APP_URL, which isn't the best practice
All in all, I want to use something like flask.Request.url_root to avoid manual writing again and again
When I just try to use flask.request I get the following traceback:
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
forms.py is posted here
The app is already hosted on Heroku, here is the link: https://qysqa.herokuapp.com/
The solution was to use flask.request inside custom validators (validate_url() and validate_short_url()) where app context gets passed

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.

How to detect which of the two virtual hosts is being used in python and flask

I have a website developed in flask running on an apache2 server that responds on port 80 to two URLs
Url-1 http://www.example.com
Url-2 http://oer.example.com
I want to detect which of the two urls the user is coming in from and adjust what the server does and store the variable in a config variable
app.config['SITE'] = 'OER'
or
app.config['SITE'] = 'WWW'
Looking around on the internet I can find lots of examples using urllib2 the issue is that you need to pass it the url you want to slice and I cant find a way to pull that out as it may change between the two with each request.
I could fork the code and put up two different versions but that's as ugly as a box of frogs.
Thoughts welcome.
Use the Flask request object (from flask import request) and one of the following in your request handler:
hostname = request.environ.get('HTTP_HOST', '')
url = urlparse(request.url)
hostname = url.netloc
This will get e.g. oer.example.com or www.example.com. If there is a port number that will be included too. Keep in mind that this ultimately comes from the client request so "bad" requests might have it set wrong, although hopefully apache wouldn't route those to your app.

Can't reach Eve REST API

I'm using Eve to create a REST API for MongoDB.
It's all working fine, except for the fact that I can't reach the API from any other computer (in the same network), or even a different URL (e.g.: if I set SERVER_NAME = 'localhost:29000', I will not be able to reach the API with 127.0.0.1 and vice versa).
I've been looking around for hours, and I can't seem to find an answer. I also tried other REST API's for MongoDB like Kule, and they seem to work just fine, but they don't have as many options as Eve has.
Eve's SERVER_NAME seems to be based on the configuration variable by the same name from Flask: See "More on server name" below the table in the Flask Configuration docs. So it's really just for the name (hostname / subdomain handling) - the actual network interfaces it binds to therfore are probably determined by the server that runs the WSGI application.
If you're just doing the
app = Eve()
app.run()
from the quickstart example, try
app.run(host='0.0.0.0')
instead and leave the server name empty (SERVER_NAME = '').
I've never used Eve, but from what I understand about how it's built that should work

Django Admin Page broken links

I am deploying a Django app using uwsgi.
The app is deployed under SERVER_URL:PORT.
Using a proxy server, the app can be accessed also via EXTERNAL_WEB_SITE/MY_APP_NAME.
When using the admin page, under: EXTERNAL_WEB_SITE/MY_APP_NAME/ADMIN/, I can see the correct models. But, the links in the admin page that direct to the models themselves direct to: EXTERNAL_WEB_SITE/ADMIN/MAIN_PACKAGE/SELECTED_MODEL/. That is - the MY_APP_NAME won't pass in the link provided.
I suppose this is because in the server itself the app is deployed with no app name, just under a specific port.
In order to solve it, I tried defining FORCE_SCRIPT_NAME=MY_APP_NAME in settings.py. This gives me good links. BUT - when trying to modify an object and save it - under EXTERNAL_WEB_SITE/MY_APP_NAME/ADMIN/MAIN_PACKAGE/SELECTED_MODEL/ITEM/ - after hitting Save I am linked to EXTERNAL_WEB_SITE/MY_APP_NAME/MY_APP_NAME/ADMIN/MAIN_PACKAGE/SELECTED_MODEL/ITEM/ - that is - I get MY_APP_NAME twice.
Does anyone know how to solve this issue?
you need to pass SCRIPT_NAME env variable with your request from proxy server
alternatively you could have two instances running one with FORCE_SCRIPT_NAME set and second without
uwsgi have a nice option, that you can deploy your app on two ports or (even better) set env variable depending on headers or paths
[uwsgi]
route = ^(/MY_APP_NAME)/ addvar:SCRIPT_NAME=$1

Categories