On 10/28/06, Nadav Samet <[EMAIL PROTECTED]> wrote:
On 10/28/06, Andrew Grover < [EMAIL PROTECTED]> wrote:Can anyone advice if this is a security risk to accept both encrypted password and the plain-text one?
On 10/27/06, Nadav Samet <[EMAIL PROTECTED]> wrote:
> You can always send the username/password as a cookie (tg_remember_me), and
> use it as a way of authentication. This will not require any new table.
Is saving username and password in a cookie an OK thing to do?
In many situations not. Actually, the code attached saves the password encrypted using the provider's encryption algorithm, which is better (but the default is plain-text).
Unfortunately, validate_password() wants the password in plain-text, so I had to monkey-patch the providers again to accept either encrypted password or plain-text password:
def validate_password(self, user, user_name, password):
return user.password in (password, self.encrypt_password(password))
and in IdentityVisitPlugin.__init__, I've added:
self.provider.__class__.validate_password = validate_password
(the full version is attached).
The only thing I see that might turn into a security problem, is that if someone got the encrypted password by hacking to the SQL server. Then he'll be able to login without knowing the real password. But any other autologin solution I know is vulnerable when the SQL server is hacked.
--
Sincerely yours,
Nadav
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "TurboGears Trunk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears-trunk
-~----------~----~----~----~------~----~------~--~---
from turbogears import identity from turbogears.config import get from turbogears.identity.visitor import log import cherrypy import time
BaseIdentityVisitPlugin = identity.visitor.IdentityVisitPlugin
def validate_password(self, user, user_name, password):
return user.password in (password, self.encrypt_password(password))
class IdentityVisitPlugin(BaseIdentityVisitPlugin):
def __init__(self):
self.remember_me_field = get( "identity.form.remember_me", "remember_me" )
# Default name for remember me cookie
self.remember_me_cookie_name = get( 'identity.remember_me.cookie.name', 'tg_remember_me')
self.remember_me_cookie_path = get( 'identity.remember_me.cookie.path', '/')
self.remember_me_cookie_domain = get( 'identity.remember_me.cookie.path', None)
self.remember_me_enabled = get( 'identity.remember_me.on', True)
super(IdentityVisitPlugin, self).__init__()
if self.remember_me_enabled:
self.identity_sources.append(self.identity_from_remember_me)
self.provider.__class__.validate_password = validate_password
def identity_from_remember_me( self, visit_key ):
'''
Inspect the remember me cookie to pull out identity information.
Returns an identity dictionary or none if the cookie contained no identity
information or the information was incorrect.
'''
cookies = cherrypy.request.simple_cookie
if self.remember_me_cookie_name in cookies:
value = cookies[self.remember_me_cookie_name].value.split('\n')
if len(value)!=2:
return None
identity= self.provider.validate_identity(
user_name=value[0],
password = value[1],
visit_key = visit_key )
if identity is None:
log.warning( "The credentials specified weren't valid" )
return None
return identity
else:
return None
def identity_from_form( self, visit_key ):
identity = super(IdentityVisitPlugin, self).identity_from_form(visit_key)
if (identity and self.remember_me_enabled and
cherrypy.request.params.pop(self.remember_me_field, False)):
self.send_remember_me_cookie(identity.user.user_name, identity.user.password)
return identity
def send_remember_me_cookie(self, user_name, password):
'''
Sends a remember me cookie back to the browser
'''
cookies = cherrypy.response.simple_cookie
password = self.provider.encrypt_password(password)
cookies[self.remember_me_cookie_name] = user_name+'\n'+password
cookies[self.remember_me_cookie_name]['path'] = self.remember_me_cookie_path
gmt_expiration_time = time.gmtime(time.time() +
(365 * 24 * 60 * 60)) # 1 year, in seconds
cookies[self.remember_me_cookie_name]['expires'] = time.strftime(
"%a, %d-%b-%Y %H:%M:%S GMT", gmt_expiration_time)
if self.remember_me_cookie_domain:
cookies[self.remember_me_cookie_name]['domain'] = self.remember_me_cookie_domain
log.debug("Sending remember_me cookie")
def identity_from_request(self, visit_key):
'''
Retrieve identity information from the HTTP request. Checks first for
form fields defining the identity then for a cookie. If no identity
is found, returns an anonymous identity.
'''
identity= None
log.debug( "Retrieving identity for visit: %s", visit_key )
for source in self.identity_sources:
identity= source(visit_key)
if identity and not identity.anonymous:
return identity
log.debug( "No identity found" )
# No source reported an identity
identity= self.provider.anonymous_identity()
return identity
# We now replace the framework class with our derived class.
identity.visitor.IdentityVisitPlugin = IdentityVisitPlugin
def clear_remember_me_cookie():
'''
Clears any remember me cookie.
'''
cookies= cherrypy.response.simple_cookie
remember_me_cookie_name = get( 'identity.remember_me.cookie.name', 'tg_remember_me')
remember_me_cookie_path = get( 'identity.remember_me.cookie.path', '/')
# clear the cookie
log.debug( "Clearing remember_me cookie" )
cookies[remember_me_cookie_name]= ''
cookies[remember_me_cookie_name]['path']= remember_me_cookie_path
cookies[remember_me_cookie_name]['expires']= 0
