OK. check trunk. Auth(db,secure=True). 

On Thursday, 4 October 2012 13:01:51 UTC-5, Yarin wrote:
>
> Yes exactly
>
> On Thursday, October 4, 2012 12:38:34 PM UTC-4, Massimo Di Pierro wrote:
>>
>> So... would replaing this in gluon.main.py 
>>
>> is_https = env.wsgi_url_scheme in ['https', 'HTTPS'] or env.https=='on')
>>
>> with 
>>
>> is_https = env.wsgi_url_scheme in ['https', 'HTTPS'] or env.https=='on' 
>> or request.env.http_x_forwarded_proto in ['https', 'HTTPS']
>>
>> address the first issue?
>>
>> Massimo
>>
>> On Thursday, 4 October 2012 07:05:17 UTC-5, Yarin wrote:
>>>
>>> I'm revising my stance on this. After further digging around, I'm gonna 
>>> go with Niphlod's position that securing only the login traffic without 
>>> securing the entire session is for the most part pretty worthless. While 
>>> this might have value to some sites that have to deal with mixed content, 
>>> the complexity it introduces isn't worth it.
>>>
>>> I'm also taking back my recommendation that we need to have a setting to 
>>> explicitly allow SSL traffic. I think it's fine to just check the headers 
>>> for forwarded SSL traffic and trust that it is. Yes, headers can be 
>>> spoofed, but I can't think of how this could be exploited on the user end- 
>>>
>>> So that leaves only *two recommended changes:*
>>>
>>>    - When checking whether HTTPS, check for forwarded SSL headers with 
>>>    if request.env.http_x_forwarded_proto in ['https', 'HTTPS']:
>>>    - Add a auth.secure = True convenience setting, which would call 
>>>    requires_https() while the user is logged in, and on all 
>>> login/registration 
>>>    methods.
>>>    
>>> I'll update the ticket
>>>
>>>
>>>
>>> On Friday, September 21, 2012 2:26:36 PM UTC-4, Yarin wrote:
>>>>
>>>> Done http://code.google.com/p/web2py/issues/detail?id=1023
>>>>
>>>> On Friday, September 21, 2012 2:05:41 PM UTC-4, Massimo Di Pierro wrote:
>>>>>
>>>>> Yarin, please open an issue on google code as suggested enhancement so 
>>>>> ti does not get lost. Also feel free to move the discussion on web2py 
>>>>> developers.
>>>>>
>>>>>
>>>>> On Friday, 21 September 2012 12:22:57 UTC-5, Yarin wrote:
>>>>>>
>>>>>> Here's a complete example of our own implementation (simplified, 
>>>>>> untested) using the proposed auth settings:
>>>>>>
>>>>>> *In our model:*
>>>>>>
>>>>>> def force_https(trust_proxy = False, secure_session = False):
>>>>>>     """ Enforces HTTPS in appropriate environments
>>>>>>
>>>>>>     Args:
>>>>>>         trust_proxy: Can we trust proxy header 
>>>>>> 'http_x_forwarded_proto' to determine SSL.
>>>>>>         (Set this only if ALL your traffic comes via trusted proxy.)
>>>>>>         secure_session: Secure the session as well. 
>>>>>>         (Do this only when enforcing SSL throughout the session)
>>>>>>     """
>>>>>>
>>>>>>     # If cronjob or scheduler, exit:
>>>>>>     cronjob = request.global_settings.cronjob
>>>>>>     cmd_options = request.global_settings.cmd_options
>>>>>>     if cronjob or (cmd_options and cmd_options.scheduler):
>>>>>>         return
>>>>>>
>>>>>>     # If local host, exit:
>>>>>>     if request.env.remote_addr == "127.0.0.1":
>>>>>>         return
>>>>>>
>>>>>>     # If already HTTPS, exit:
>>>>>>     if request.env.wsgi_url_scheme in ['https', 'HTTPS']:
>>>>>>         if secure_session:
>>>>>>             current.session.secure()
>>>>>>         return
>>>>>>
>>>>>>     # If HTTPS request forwarded over HTTP via a SSL-terminating 
>>>>>> proxy, exit:
>>>>>>     if trust_proxy and request.env.http_x_forwarded_proto in ['https'
>>>>>> , 'HTTPS']: 
>>>>>>         if secure_session:
>>>>>>             current.session.secure()
>>>>>>         return
>>>>>>
>>>>>>     # Redirect to HTTPS:
>>>>>>     redirect(URL(scheme='https', args=request.args, vars=request.vars
>>>>>> ))
>>>>>>
>>>>>> # If a login function, force SSL:
>>>>>> if request.controller == 'default' and request.function == 'user' andauth
>>>>>> .settings.force_ssl_login:
>>>>>>     force_https(trust_proxy = auth.settings.is_proxied, secure_session 
>>>>>> = auth.settings.force_ssl_session)
>>>>>> # If user is logged in and we're enforcing a full SSL session:
>>>>>> elif auth.is_logged_in() and auth.settings.force_ssl_session:
>>>>>>     force_https(trust_proxy = auth.settings.is_proxied,secure_session 
>>>>>> = True)
>>>>>>
>>>>>> def on_login(form):
>>>>>>     """ Post login redirection"""
>>>>>>
>>>>>>     # If we're enforcing SSL on login only, redirect from HTTPS to 
>>>>>> HTTP immediately after login:
>>>>>>     if auth.settings.force_ssl_login is True and 
>>>>>> auth.settings.force_ssl_session 
>>>>>> is False:
>>>>>>         if request.env.wsgi_url_scheme in ['https', 'HTTPS'] orrequest
>>>>>> .env.http_x_forwarded_proto in ['https', 'HTTPS']:
>>>>>>
>>>>>>             # Extract the post-login url value from auth 
>>>>>>             # (hack - look at end of login() function in tools.py. 
>>>>>> This belongs in Auth itself.):
>>>>>>             login_next_path = auth.next or auth.settings.login_next
>>>>>>             # Build an absolute, HTTP url from it:
>>>>>>             login_next_url = URL(scheme='http',c='default',f='index') 
>>>>>> + login_next_path[1:]
>>>>>>             # Redirect to the HTTP URL:
>>>>>>             redirect(login_next_url)
>>>>>>
>>>>>> auth.settings.login_onaccept = on_login
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Friday, September 21, 2012 12:35:37 PM UTC-4, Yarin wrote:
>>>>>>>
>>>>>>> You can't detect this- it must be a setting. Please see my previous 
>>>>>>> answer:
>>>>>>> https://groups.google.com/forum/#!msg/web2py/me1e5d6Dudk/VQRQhdiryccJ
>>>>>>>
>>>>>>> "you cannot detect whether proxied traffic is real because headers 
>>>>>>> are unreliable. Instead you must securely set up a server behind a 
>>>>>>> proxy 
>>>>>>> and set the .is_proxied flag explicitly."
>>>>>>>
>>>>>>> "you can't mix direct and proxied traffic. To be able to handle 
>>>>>>> proxy-terminated SSL, we need to know that *all* the traffic is via 
>>>>>>> a trusted proxy."
>>>>>>>
>>>>>>>
>>>>>>> On Friday, September 21, 2012 12:05:56 PM UTC-4, Massimo Di Pierro 
>>>>>>> wrote:
>>>>>>>>
>>>>>>>> Yes but how do you detect if is_proxied reliably?
>>>>>>>>
>>>>>>>> On Friday, 21 September 2012 10:28:26 UTC-5, Yarin wrote:
>>>>>>>>>
>>>>>>>>> FYI this is the enforcer function we wrote for our implementation- 
>>>>>>>>> basically a rewrite of request.requires_https():
>>>>>>>>>
>>>>>>>>> def force_https(trust_proxy = False):
>>>>>>>>>  """ Enforces HTTPS in appropriate environments
>>>>>>>>>  
>>>>>>>>>  Args:
>>>>>>>>>      trust_proxy: Can we trust proxy header 
>>>>>>>>> 'http_x_forwarded_proto' to determine SSL.
>>>>>>>>>      (Set this only if ALL your traffic comes via trusted proxy.)
>>>>>>>>>  """
>>>>>>>>>  
>>>>>>>>>  # If cronjob or scheduler, exit:
>>>>>>>>>  cronjob = request.global_settings.cronjob
>>>>>>>>>  cmd_options = request.global_settings.cmd_options
>>>>>>>>>  if cronjob or (cmd_options and cmd_options.scheduler):
>>>>>>>>>      return
>>>>>>>>>
>>>>>>>>>  # If local host, exit:
>>>>>>>>>  if request.env.remote_addr == "127.0.0.1":
>>>>>>>>>      return
>>>>>>>>>  
>>>>>>>>>  # If already HTTPS, exit:
>>>>>>>>>  if request.env.wsgi_url_scheme in ['https', 'HTTPS']:
>>>>>>>>>      return
>>>>>>>>>  
>>>>>>>>>  # If HTTPS request forwarded over HTTP via SSL-terminating 
>>>>>>>>> proxy, exit:
>>>>>>>>>  if trust_proxy and request.env.http_x_forwarded_proto in ['https'
>>>>>>>>> , 'HTTPS']: 
>>>>>>>>>      return
>>>>>>>>>  
>>>>>>>>>  # Redirect to HTTPS:
>>>>>>>>>  redirect(URL(scheme='https', args=request.args, vars=request.vars
>>>>>>>>> ))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Friday, September 21, 2012 9:53:36 AM UTC-4, Yarin wrote:
>>>>>>>>>>
>>>>>>>>>> The completely naive approach would be to do: 
>>>>>>>>>>
>>>>>>>>>> if request.env.http_x_forwarded_for and \
>>>>>>>>>>     request.env.http_x_forwarded_proto in ['https', 'HTTPS']:
>>>>>>>>>>      # Is HTTPS...
>>>>>>>>>>
>>>>>>>>>> But you cannot detect whether proxied traffic is real because 
>>>>>>>>>> headers are unreliable. Instead it is up to the user to securely set 
>>>>>>>>>> up a 
>>>>>>>>>> server behind a proxy and set the .is_proxied flag themselves.
>>>>>>>>>>
>>>>>>>>>> *Example:*
>>>>>>>>>> We put our app server behind an SSL-terminating load balancer on 
>>>>>>>>>> the cloud. The domain app.example.com points to the 
>>>>>>>>>> loadbalancer, so we configure app server's Apache to allow traffic 
>>>>>>>>>> from 
>>>>>>>>>> that domain only, and block any outside direct traffic. Then we set 
>>>>>>>>>> *auth.settings.is_proxied* to tell web2py "this proxy traffic is 
>>>>>>>>>> legit"
>>>>>>>>>>
>>>>>>>>>> HTTPS/443 requests will hit the loadbalancer, and be transformed 
>>>>>>>>>> to HTTP/80 traffic with *http_x_forwarded_for* and *
>>>>>>>>>> http_x_forwarded_proto* headers set. Now we can confidently 
>>>>>>>>>> check:
>>>>>>>>>>
>>>>>>>>>> if auth.settings.is_proxied and \
>>>>>>>>>>     request.env.http_x_forwarded_proto in ['https', 'HTTPS']:
>>>>>>>>>>     # Is HTTPS...
>>>>>>>>>>
>>>>>>>>>> In other words *http_x_forwarded_for* header is useless and you 
>>>>>>>>>> can't mix direct and proxied traffic. To be able to handle 
>>>>>>>>>> proxy-terminated 
>>>>>>>>>> SSL, we need to know that *all* the traffic is via a trusted 
>>>>>>>>>> proxy.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Friday, September 21, 2012 8:40:35 AM UTC-4, Massimo Di Pierro 
>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Can you suggest a way to detect that?
>>>>>>>>>>>
>>>>>>>>>>> On Thursday, 20 September 2012 13:56:55 UTC-5, Yarin wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> @Massimo - that'd be great. 
>>>>>>>>>>>>
>>>>>>>>>>>> One more kink to throw in is recognizing proxied SSL calls. 
>>>>>>>>>>>> This requires knowing whether you can trust the traffic headers 
>>>>>>>>>>>> (e.g. 
>>>>>>>>>>>> having apache locked down to all traffic except your load 
>>>>>>>>>>>> balancer), so 
>>>>>>>>>>>> maybe we need a trust_proxied_ssl or is_proxied setting somewhere?
>>>>>>>>>>>>
>>>>>>>>>>>> if request.env.http_x_forwarded_for and 
>>>>>>>>>>>> request.env.http_x_forwarded_proto 
>>>>>>>>>>>> in ['https', 'HTTPS'] and auth.settings.is_proxied:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Thursday, September 20, 2012 12:52:22 PM UTC-4, Massimo Di 
>>>>>>>>>>>> Pierro wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> I think we should do something like this. 
>>>>>>>>>>>>>
>>>>>>>>>>>>> I think we should have auth.settings.force_ssl_login 
>>>>>>>>>>>>> and  auth.settings.force_ssl_login.
>>>>>>>>>>>>> We could add secure=True option to existing requires 
>>>>>>>>>>>>> validators.
>>>>>>>>>>>>>
>>>>>>>>>>>>> This should not be enforced from localhost.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thursday, 20 September 2012 09:07:14 UTC-5, Yarin wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> A proposal for improving SSL support in web2py 
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> For authenticated web applications, there are two "grades" of 
>>>>>>>>>>>>>> SSL implementions: Forcing SSL on login, vs forcing SSL on the 
>>>>>>>>>>>>>> entire 
>>>>>>>>>>>>>> authenticated session.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> In the first case, HTTPS is forced on login/registration, but 
>>>>>>>>>>>>>> reverts back to HTTP upon authentication. This protects against 
>>>>>>>>>>>>>> passwords 
>>>>>>>>>>>>>> from being sent unencrypted, but won't prevent session hijacking 
>>>>>>>>>>>>>> as the 
>>>>>>>>>>>>>> session cookie can still be compromised on subsequent HTTP 
>>>>>>>>>>>>>> requests. (See 
>>>>>>>>>>>>>> Firesheep <http://codebutler.com/firesheep> for details). 
>>>>>>>>>>>>>> Nonetheless, many sites choose this approach for performance 
>>>>>>>>>>>>>> reasons, as 
>>>>>>>>>>>>>> SSL-delivered content is not cached by browsers as efficiently 
>>>>>>>>>>>>>> (discussed 
>>>>>>>>>>>>>> on 37signals 
>>>>>>>>>>>>>> blog<http://37signals.com/svn/posts/1431-mixed-content-warning-how-i-loathe-thee>
>>>>>>>>>>>>>> ).
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> In the second case, the entire authenticated session is 
>>>>>>>>>>>>>> secured by forcing all traffic to go over HTTPS while a user is 
>>>>>>>>>>>>>> logged in 
>>>>>>>>>>>>>> *and* by securing the session cookie so that it will only be 
>>>>>>>>>>>>>> sent by the browser over HTTPS.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> (Also discussed in web2py users group - Auth over 
>>>>>>>>>>>>>> SSL<https://groups.google.com/d/msg/web2py/7qoHMs-4Va8/jRFOqYHri4gJ>
>>>>>>>>>>>>>> )
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> web2py should make it easier to deal with these scenarios. I 
>>>>>>>>>>>>>> just implemented a case-1 type solution and it took quite a bit 
>>>>>>>>>>>>>> of work.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Moreover, web2py currently provides two SSL-control 
>>>>>>>>>>>>>> functions, which, taken on their own, can lead to problems for 
>>>>>>>>>>>>>> the 
>>>>>>>>>>>>>> uninitiated:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>    - session.secure() will ensure that the session cookie is 
>>>>>>>>>>>>>>    only transmitted over HTTPS, but doesn't force HTTPS, so that 
>>>>>>>>>>>>>> for any 
>>>>>>>>>>>>>>    subsequent session calls made over HTTP will simply not have 
>>>>>>>>>>>>>> access to the 
>>>>>>>>>>>>>>    auth session, but this is not obvious (Correct me if I'm 
>>>>>>>>>>>>>> wrong)
>>>>>>>>>>>>>>    - request.requires_https() (undocumented?) is a misnomer, 
>>>>>>>>>>>>>>    because if forces HTTPS but then assumes a case-2 
>>>>>>>>>>>>>>    scenario and secures the session cookie
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> *Proposals:*
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>    - SSL auth settings
>>>>>>>>>>>>>>       - auth.settings.force_ssl_login - Forces HTTPS for 
>>>>>>>>>>>>>>       login/registration
>>>>>>>>>>>>>>       - auth.settings.force_ssl_session - Forces HTTPS 
>>>>>>>>>>>>>>       throughout an authenticated session, and secure the 
>>>>>>>>>>>>>> session cookie (If 
>>>>>>>>>>>>>>       True, force_ssl_login not necessary)
>>>>>>>>>>>>>>    - Other more granular controls
>>>>>>>>>>>>>>       - @requires_https() - decorator for controller 
>>>>>>>>>>>>>>       functions that forces HTTPS for that function only
>>>>>>>>>>>>>>       - 'secure=True' option on forms ensures submission 
>>>>>>>>>>>>>>       over HTTPS
>>>>>>>>>>>>>>    
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>

-- 



Reply via email to