properly enforce CSRF validation

see: https://github.com/ansible/tower/issues/2339
This commit is contained in:
Ryan Petrello 2018-06-27 15:50:07 -04:00
parent 39bc64d089
commit 504dfd32ee
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
5 changed files with 17 additions and 21 deletions

View File

@ -39,9 +39,6 @@ class SessionAuthentication(authentication.SessionAuthentication):
def authenticate_header(self, request): def authenticate_header(self, request):
return 'Session' return 'Session'
def enforce_csrf(self, request):
return None
class LoggedOAuth2Authentication(OAuth2Authentication): class LoggedOAuth2Authentication(OAuth2Authentication):

View File

@ -24,7 +24,8 @@ from django.shortcuts import get_object_or_404
from django.utils.encoding import smart_text from django.utils.encoding import smart_text
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.timezone import now from django.utils.timezone import now
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.http import HttpResponse from django.http import HttpResponse
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -229,6 +230,7 @@ class ApiRootView(APIView):
versioning_class = None versioning_class = None
swagger_topic = 'Versioning' swagger_topic = 'Versioning'
@method_decorator(ensure_csrf_cookie)
def get(self, request, format=None): def get(self, request, format=None):
''' List supported API versions ''' ''' List supported API versions '''

View File

@ -207,6 +207,8 @@ SESSION_COOKIE_AGE = 1209600
# Note: This setting may be overridden by database settings. # Note: This setting may be overridden by database settings.
SESSIONS_PER_USER = -1 SESSIONS_PER_USER = -1
CSRF_USE_SESSIONS = False
# Disallow sending csrf cookies over insecure connections # Disallow sending csrf cookies over insecure connections
CSRF_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True

View File

@ -42,21 +42,13 @@ export default
return $rootScope.userLoggedIn; return $rootScope.userLoggedIn;
}, },
retrieveToken: function (username, password) { retrieveToken: function (username, password) {
var getCSRFToken = $http({ return $http({
method: 'GET', method: 'POST',
url: `/api/login/` url: `/api/login/`,
}); data: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&next=%2fapi%2f`,
headers: {
return getCSRFToken.then(function({data}) { 'Content-Type': 'application/x-www-form-urlencoded'
var csrfmiddlewaretoken = /name='csrfmiddlewaretoken' value='([0-9a-zA-Z]+)' \//.exec(data)[1]; }
return $http({
method: 'POST',
url: `/api/login/`,
data: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&csrfmiddlewaretoken=${csrfmiddlewaretoken}&next=%2fapi%2f`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}); });
}, },
deleteToken: function () { deleteToken: function () {

View File

@ -11,11 +11,14 @@
*************************************************/ *************************************************/
export default export default
[ '$rootScope', '$q', '$injector', [ '$rootScope', '$q', '$injector', '$cookies',
function ($rootScope, $q, $injector) { function ($rootScope, $q, $injector, $cookies) {
return { return {
request: function (config) { request: function (config) {
config.headers['X-Requested-With'] = 'XMLHttpRequest'; config.headers['X-Requested-With'] = 'XMLHttpRequest';
if (['GET', 'HEAD', 'OPTIONS'].indexOf(config.method)===-1) {
config.headers['X-CSRFToken'] = $cookies.get('csrftoken');
}
return config; return config;
}, },
response: function(config) { response: function(config) {