1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-28 02:25:27 +03:00

Merge pull request #5812 from AlanCoding/no_loops_for_hackers

Block loops in querystring filters
This commit is contained in:
Alan Rominger 2017-03-21 10:50:35 -04:00 committed by GitHub
commit 83bc654b15
2 changed files with 15 additions and 1 deletions

View File

@ -92,6 +92,9 @@ class FieldLookupBackend(BaseFilterBackend):
# sure user cannot query using objects he could not view.
new_parts = []
# Store of all the fields used to detect repeats
field_set = set([])
for name in parts[:-1]:
# HACK: Make project and inventory source filtering by old field names work for backwards compatibility.
if model._meta.object_name in ('Project', 'InventorySource'):
@ -124,6 +127,10 @@ class FieldLookupBackend(BaseFilterBackend):
raise PermissionDenied(_('Filtering on %s is not allowed.' % name))
elif getattr(field, '__prevent_search__', False):
raise PermissionDenied(_('Filtering on %s is not allowed.' % name))
if field in field_set:
# Field traversed twice, could create infinite JOINs, DoSing Tower
raise ParseError(_('Loops not allowed in filters, detected on field {}.').format(field.name))
field_set.add(field)
model = getattr(field, 'related_model', None) or field.model
if parts:

View File

@ -2,7 +2,7 @@
import pytest
from rest_framework.exceptions import PermissionDenied
from rest_framework.exceptions import PermissionDenied, ParseError
from awx.api.filters import FieldLookupBackend
from awx.main.models import (AdHocCommand, AuthToken, CustomInventoryScript,
Credential, Job, JobTemplate, SystemJob,
@ -77,3 +77,10 @@ def test_filter_sensitive_fields_and_relations(model, query):
with pytest.raises(PermissionDenied) as excinfo:
field, new_lookup = field_lookup.get_field_from_lookup(model, query)
assert 'not allowed' in str(excinfo.value)
def test_looping_filters_prohibited():
field_lookup = FieldLookupBackend()
with pytest.raises(ParseError) as loop_exc:
field_lookup.get_field_from_lookup(Job, 'job_events__job__job_events')
assert 'job_events' in str(loop_exc.value)