fix: Reject nul characters in ipr search parameters (#6292)
* fix: Reject nul characters in ipr search parameters Really ought to rework this as a form, but in the meantime this should prevent 500s. Could probably reduce the number of places we check the value. * fix: Guard against absent parameters * fix: Remove stray junk * fix: Use correct response code (400, not 405) * test: Test handling of null chars in IPR search * refactor: Simplify branch statements This helps my code validator see that "start" is always set.
This commit is contained in:
parent
febdeff85f
commit
18a1af22f8
|
@ -209,6 +209,24 @@ class IprTests(TestCase):
|
|||
r = self.client.get(url + "?submit=iprtitle&iprtitle=%s" % quote(ipr.title))
|
||||
self.assertContains(r, ipr.title)
|
||||
|
||||
def test_search_null_characters(self):
|
||||
"""IPR search gracefully rejects null characters in parameters"""
|
||||
# Not a combinatorially exhaustive set, but tries to exercise all the parameters
|
||||
bad_params = [
|
||||
"option=document_search&document_search=draft-\x00stuff"
|
||||
"submit=dra\x00ft",
|
||||
"submit=draft&id=some\x00id",
|
||||
"submit=draft&id_document_tag=some\x00id",
|
||||
"submit=draft&id=someid&state=re\x00moved",
|
||||
"submit=draft&id=someid&state=posted&state=re\x00moved",
|
||||
"submit=draft&id=someid&state=removed&draft=draft-no\x00tvalid",
|
||||
"submit=rfc&rfc=rfc\x00123",
|
||||
]
|
||||
url = urlreverse("ietf.ipr.views.search")
|
||||
for query_params in bad_params:
|
||||
r = self.client.get(f"{url}?{query_params}")
|
||||
self.assertEqual(r.status_code, 400, f"querystring '{query_params}' should be rejected")
|
||||
|
||||
def test_feed(self):
|
||||
ipr = HolderIprDisclosureFactory()
|
||||
r = self.client.get("/feed/ipr/")
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.contrib import messages
|
|||
from django.db.models import Q
|
||||
from django.forms.models import inlineformset_factory, model_to_dict
|
||||
from django.forms.formsets import formset_factory
|
||||
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
||||
from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse as urlreverse
|
||||
|
@ -629,11 +629,16 @@ def post(request, id):
|
|||
|
||||
def search(request):
|
||||
search_type = request.GET.get("submit")
|
||||
if search_type and "\x00" in search_type:
|
||||
return HttpResponseBadRequest("Null characters are not allowed")
|
||||
|
||||
# query field
|
||||
q = ''
|
||||
# legacy support
|
||||
if not search_type and request.GET.get("option", None) == "document_search":
|
||||
docname = request.GET.get("document_search", "")
|
||||
if docname and "\x00" in docname:
|
||||
return HttpResponseBadRequest("Null characters are not allowed")
|
||||
if docname.startswith("draft-"):
|
||||
search_type = "draft"
|
||||
q = docname
|
||||
|
@ -643,18 +648,24 @@ def search(request):
|
|||
if search_type:
|
||||
form = SearchForm(request.GET)
|
||||
docid = request.GET.get("id") or request.GET.get("id_document_tag") or ""
|
||||
if docid and "\x00" in docid:
|
||||
return HttpResponseBadRequest("Null characters are not allowed")
|
||||
docs = doc = None
|
||||
iprs = []
|
||||
related_iprs = []
|
||||
|
||||
# set states
|
||||
states = request.GET.getlist('state',settings.PUBLISH_IPR_STATES)
|
||||
if any("\x00" in state for state in states if state):
|
||||
return HttpResponseBadRequest("Null characters are not allowed")
|
||||
if states == ['all']:
|
||||
states = IprDisclosureStateName.objects.values_list('slug',flat=True)
|
||||
|
||||
# get query field
|
||||
if request.GET.get(search_type):
|
||||
q = request.GET.get(search_type)
|
||||
if q and "\x00" in q:
|
||||
return HttpResponseBadRequest("Null characters are not allowed")
|
||||
|
||||
if q or docid:
|
||||
# Search by RFC number or draft-identifier
|
||||
|
@ -664,13 +675,12 @@ def search(request):
|
|||
|
||||
if docid:
|
||||
start = DocAlias.objects.filter(name__iexact=docid)
|
||||
else:
|
||||
if search_type == "draft":
|
||||
q = normalize_draftname(q)
|
||||
start = DocAlias.objects.filter(name__icontains=q, name__startswith="draft")
|
||||
elif search_type == "rfc":
|
||||
start = DocAlias.objects.filter(name="rfc%s" % q.lstrip("0"))
|
||||
|
||||
elif search_type == "draft":
|
||||
q = normalize_draftname(q)
|
||||
start = DocAlias.objects.filter(name__icontains=q, name__startswith="draft")
|
||||
else: # search_type == "rfc"
|
||||
start = DocAlias.objects.filter(name="rfc%s" % q.lstrip("0"))
|
||||
|
||||
# one match
|
||||
if len(start) == 1:
|
||||
first = start[0]
|
||||
|
|
Loading…
Reference in a new issue