A few questions using SSL in controllers

11 views
Skip to first unread message

voltron

unread,
Mar 18, 2008, 4:10:43 AM3/18/08
to web2py Web Framework
Hi!

Apart form preparing the server to accept requests over port 443 and
creating the certificates, I understand that I would have to do the
following in Web2py.

1. For the exposed function that is supposed to use SSL, check to see
if the request really used the right protocol as in "HTTPS" instead of
"HTTP"

2. If the protocol was wrong, redirect to the same URL, but using
HTTPS

Is that all there is to it?

How do I redirect to a URL with the HTTPS protocol ?

redirect(URL(a="init", c="accounts", f="private_link"))


Thanks!

Michael Wills

unread,
Mar 18, 2008, 5:55:07 AM3/18/08
to web...@googlegroups.com
Short answer: not that I can see. You have to build it. Python gurus will have a better answer I am sure.

The long answer and some thoughts about web2py and absolute paths:

Since URL only builds relative paths, it won't build the complete path, especially the https bit. I am sure the gurus have a better answer but depending on your setup, you can build it. It's just not so fun. If you run the status app you can check a few variables. If you are not running behind a host you can use something like:

path='https://%s/%s' % (request.env.host,URL(a="init", c="accounts", f="private_link"))
redirect(path)

Perhaps if URL had a 'absolute' option, and/or a 'secure' option. Or even a 'protocol'.

redirect(URL(a="init", c="accounts", f="private_link", secure=True))

I'm not sure but this would return have to return an absolute URL out of necessity since it needs to build it from the 'https'.

If it were wrapped in the URL function, it would be nice but it might require something like a SITE variable.

redirect(URL(a="init", c="accounts", f="private_link", secure=True, url_base=SITE))

In my case I am on a proxy I actually don't use request.env.host. I could use request.env.http_x_forwarded_host. You can see Massimo's status app as an example of that.

Is there any other way to get the actual site? I may actually need this so In my case I would probably end up putting something in my applications.init.models so that it checks:

SITE=http_host if not http_x_forwarded_host else http_x_forwarded_host

But there are a lot of ways web2py can be deployed so I wouldn't know how to figure that for all cases. :-P

voltron

unread,
Mar 18, 2008, 6:04:10 AM3/18/08
to web2py Web Framework
Thanks Michael for the detailed answer, I sort of guessed there would
not be any Web2Py "magic" that would ease the "pain" :-)) oh well. I
am using mod_proxy as well. I read back some time ago that someone
wrote up some Django code to forward the actual site name of a proxied
site, Ill try to dig it up

On Mar 18, 10:55 am, "Michael Wills" <mcwi...@gmail.com> wrote:
> Short answer: not that I can see. You have to build it. Python gurus will
> have a better answer I am sure.
>
> The long answer and some thoughts about web2py and absolute paths:
>
> Since URL only builds relative paths, it won't build the complete path,
> especially the https bit. I am sure the gurus have a better answer but
> depending on your setup, you can build it. It's just not so fun. If you run
> the status app <http://mdp.cti.depaul.edu/examples/simple_examples/status>you
> can check a few variables. If you are not running behind a host you
> can
> use something like:
>
> path='https://%s/%s' % (request.env.host,URL(a="init", c="accounts",
> f="private_link"))
> redirect(path)
>
> Perhaps if URL had a 'absolute' option, and/or a 'secure' option. Or even a
> 'protocol'.
>
> redirect(URL(a="init", c="accounts", f="private_link", secure=True))
>
> I'm not sure but this would return have to return an absolute URL out of
> necessity since it needs to build it from the 'https'.
>
> If it were wrapped in the URL function, it would be nice but it might
> require something like a SITE variable.
>
> redirect(URL(a="init", c="accounts", f="private_link", secure=True,
> url_base=SITE))
>
> In my case I am on a proxy I actually don't use request.env.host. I could
> use request.env.http_x_forwarded_host. You can see Massimo's status
> app<http://mdp.cti.depaul.edu/examples/simple_examples/status>as an

Michael Wills

unread,
Mar 18, 2008, 6:24:15 AM3/18/08
to web...@googlegroups.com
If you're using mod_proxy then

SITE=request.env.http_host if request.env.not http_x_forwarded_host else request.env.http_x_forwarded_host

might do the trick for you. That seems to work in my minimal tests but hopefully it does. I'll need it later, too! :-P

Michael Wills

unread,
Mar 18, 2008, 6:25:33 AM3/18/08
to web...@googlegroups.com
But if there is some good Django code though that'd be really cool! :-P

On Tue, Mar 18, 2008 at 3:04 AM, voltron <nhy...@googlemail.com> wrote:

voltron

unread,
Mar 18, 2008, 7:04:55 AM3/18/08
to web2py Web Framework
I could´nt find the code anymore, Ill have to search further. The
Django site cites that using a new algo to get the correct host
though, this is the code:

def get_host(self):
48 "Returns the HTTP host using the environment or request
headers."
49 # We try three options, in order of decreasing preference.
50 if 'HTTP_X_FORWARDED_HOST' in self.META:
51 host = self.META['HTTP_X_FORWARDED_HOST']
52 elif 'HTTP_HOST' in self.META:
53 host = self.META['HTTP_HOST']
54 else:
55 # Reconstruct the host using the algorithm from PEP
333.
56 host = self.META['SERVER_NAME']
57 server_port = self.META['SERVER_PORT']
58 if server_port != (self.is_secure() and 443 or 80):
59 host = '%s:%s' % (host, server_port)
60 return host

Michael Wills

unread,
Mar 18, 2008, 7:20:37 AM3/18/08
to web...@googlegroups.com
It makes sense and not too much crazier than what I wrote... hmm... well I may try to make a patch... never done that before. :-) It'd be fun to try. Just have to dig in a bit to see how they test for is_secure. Thanks for the info!

Massimo Di Pierro

unread,
Mar 18, 2008, 3:11:31 PM3/18/08
to web...@googlegroups.com
cool. Who writes the HTTP_X_FORWARDED_HOST variable? apache? does it
work with lightpd?

Massimo

Michael Wills

unread,
Mar 19, 2008, 12:57:53 AM3/19/08
to web...@googlegroups.com
good question to look into. i was wondering about all those possible setups. :-p

Massimo Di Pierro

unread,
Mar 19, 2008, 5:39:49 PM3/19/08
to web...@googlegroups.com
It seems that mod_proxy writes it. The problem is that the client can forge this http header and make web2py (or any other server that uses it) believe that the request is going over https.  This can trusted only if the proxy is running on localhost. 
The Django way of doing it is insecure if it used to determine an https connection. There need to be an additional if statement.

Anyway. we need to take advantage of these somehow:

Massimo

voltron

unread,
Mar 23, 2008, 4:40:24 AM3/23/08
to web2py Web Framework
What do you suggest that one should use in the meantime Massimo? Hard
coding the path by building it manually with "HTTPS" as Michael
suggested? You use SSL on some parts of your site, how is that taken
care of?

Thanks and happy Easter!

On Mar 19, 10:39 pm, Massimo Di Pierro <mdipie...@cs.depaul.edu>
wrote:

Massimo Di Pierro

unread,
Mar 23, 2008, 9:46:07 AM3/23/08
to web...@googlegroups.com
If you use apache use mod_rewrite to force over https all apps that
that require authentication, including admin.
If admin is the only app that requires authentication, you may want
to edit the apache config to block admin and */appadmin and use an
ssh tunnel.
I wrote a short post about this on alterego.

Massimo

Reply all
Reply to author
Forward
0 new messages