Using nonce now, preventing OAuth replay attacks

This commit is contained in:
xray7224 2013-07-14 16:24:04 +01:00
parent e49263564b
commit cfe7054c13
3 changed files with 28 additions and 5 deletions

View File

@ -161,6 +161,16 @@ class AccessToken(Base):
updated = Column(DateTime, nullable=False, default=datetime.datetime.now) updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
class NonceTimestamp(Base):
"""
A place the timestamp and nonce can be stored - this is for OAuth1
"""
__tablename__ = "core__nonce_timestamps"
nonce = Column(Unicode, nullable=False, primary_key=True)
timestamp = Column(DateTime, nullable=False, primary_key=True)
class MediaEntry(Base, MediaEntryMixin): class MediaEntry(Base, MediaEntryMixin):
""" """
TODO: Consider fetching the media_files using join TODO: Consider fetching the media_files using join
@ -636,8 +646,8 @@ with_polymorphic(
[ProcessingNotification, CommentNotification]) [ProcessingNotification, CommentNotification])
MODELS = [ MODELS = [
User, Client, RequestToken, AccessToken, MediaEntry, Tag, MediaTag, User, Client, RequestToken, AccessToken, NonceTimestamp, MediaEntry, Tag,
MediaComment, Collection, CollectionItem, MediaFile, FileKeynames, MediaTag, MediaComment, Collection, CollectionItem, MediaFile, FileKeynames,
MediaAttachmentFile, ProcessingMetaData, Notification, CommentNotification, MediaAttachmentFile, ProcessingMetaData, Notification, CommentNotification,
ProcessingNotification, CommentSubscription] ProcessingNotification, CommentSubscription]

View File

@ -18,7 +18,7 @@ from oauthlib.common import Request
from oauthlib.oauth1 import (AuthorizationEndpoint, RequestValidator, from oauthlib.oauth1 import (AuthorizationEndpoint, RequestValidator,
RequestTokenEndpoint, AccessTokenEndpoint) RequestTokenEndpoint, AccessTokenEndpoint)
from mediagoblin.db.models import Client, RequestToken, AccessToken from mediagoblin.db.models import NonceTimestamp, Client, RequestToken, AccessToken
@ -65,7 +65,12 @@ class GMGRequestValidator(RequestValidator):
def validate_timestamp_and_nonce(self, client_key, timestamp, def validate_timestamp_and_nonce(self, client_key, timestamp,
nonce, request, request_token=None, nonce, request, request_token=None,
access_token=None): access_token=None):
return True # TODO!!! - SECURITY RISK IF NOT DONE nc = NonceTimestamp.query.filter_by(timestamp=timestamp, nonce=nonce)
nc = nc.first()
if nc is None:
return True
return False
def validate_client_key(self, client_key, request): def validate_client_key(self, client_key, request):
""" Verifies client exists with id of client_key """ """ Verifies client exists with id of client_key """

View File

@ -32,7 +32,7 @@ from mediagoblin.federation.forms import AuthorizeForm
from mediagoblin.federation.exceptions import ValidationException from mediagoblin.federation.exceptions import ValidationException
from mediagoblin.federation.oauth import GMGRequestValidator, GMGRequest from mediagoblin.federation.oauth import GMGRequestValidator, GMGRequest
from mediagoblin.federation.tools.request import decode_authorization_header from mediagoblin.federation.tools.request import decode_authorization_header
from mediagoblin.db.models import Client, RequestToken, AccessToken from mediagoblin.db.models import NonceTimestamp, Client, RequestToken, AccessToken
# possible client types # possible client types
client_types = ["web", "native"] # currently what pump supports client_types = ["web", "native"] # currently what pump supports
@ -215,6 +215,14 @@ def request_token(request):
rv = RequestTokenEndpoint(request_validator) rv = RequestTokenEndpoint(request_validator)
tokens = rv.create_request_token(request, authorization) tokens = rv.create_request_token(request, authorization)
# store the nonce & timestamp before we return back
nonce = authorization[u"oauth_nonce"]
timestamp = authorization[u"oauth_timestamp"]
timestamp = datetime.datetime.fromtimestamp(int(timestamp))
nc = NonceTimestamp(nonce=nonce, timestamp=timestamp)
nc.save()
return form_response(tokens) return form_response(tokens)
class WTFormData(dict): class WTFormData(dict):