From 9fc30643cae55598c71e8c4aaace58fb19b09f45 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Mon, 3 Oct 2016 16:15:06 -0400 Subject: [PATCH] Prevent filtering on password fields. --- awx/api/filters.py | 7 +++++-- awx/main/tests/unit/api/test_filters.py | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/awx/api/filters.py b/awx/api/filters.py index 55155224c4..08a26735d2 100644 --- a/awx/api/filters.py +++ b/awx/api/filters.py @@ -14,7 +14,7 @@ from django.contrib.contenttypes.models import ContentType from django.utils.encoding import force_text # Django REST Framework -from rest_framework.exceptions import ParseError +from rest_framework.exceptions import ParseError, PermissionDenied from rest_framework.filters import BaseFilterBackend # Ansible Tower @@ -97,7 +97,10 @@ class FieldLookupBackend(BaseFilterBackend): new_parts.append(name) - if name == 'pk': + + if name in getattr(model, 'PASSWORD_FIELDS', ()): + raise PermissionDenied('Filtering on password fields is not allowed.') + elif name == 'pk': field = model._meta.pk else: field = model._meta.get_field_by_name(name)[0] diff --git a/awx/main/tests/unit/api/test_filters.py b/awx/main/tests/unit/api/test_filters.py index 8f045db877..55ef257567 100644 --- a/awx/main/tests/unit/api/test_filters.py +++ b/awx/main/tests/unit/api/test_filters.py @@ -1,7 +1,8 @@ import pytest +from rest_framework.exceptions import PermissionDenied from awx.api.filters import FieldLookupBackend -from awx.main.models import JobTemplate +from awx.main.models import Credential, JobTemplate @pytest.mark.parametrize(u"empty_value", [u'', '']) def test_empty_in(empty_value): @@ -15,3 +16,21 @@ def test_valid_in(valid_value): field_lookup = FieldLookupBackend() value, new_lookup = field_lookup.value_to_python(JobTemplate, 'project__in', valid_value) assert 'foo' in value + +@pytest.mark.parametrize('lookup_suffix', ['', 'contains', 'startswith', 'in']) +@pytest.mark.parametrize('password_field', Credential.PASSWORD_FIELDS) +def test_filter_on_password_field(password_field, lookup_suffix): + field_lookup = FieldLookupBackend() + lookup = '__'.join(filter(None, [password_field, lookup_suffix])) + with pytest.raises(PermissionDenied) as excinfo: + field, new_lookup = field_lookup.get_field_from_lookup(Credential, lookup) + assert 'not allowed' in str(excinfo.value) + +@pytest.mark.parametrize('lookup_suffix', ['', 'contains', 'startswith', 'in']) +@pytest.mark.parametrize('password_field', Credential.PASSWORD_FIELDS) +def test_filter_on_related_password_field(password_field, lookup_suffix): + field_lookup = FieldLookupBackend() + lookup = '__'.join(filter(None, ['credential', password_field, lookup_suffix])) + with pytest.raises(PermissionDenied) as excinfo: + field, new_lookup = field_lookup.get_field_from_lookup(JobTemplate, lookup) + assert 'not allowed' in str(excinfo.value)