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