-
Notifications
You must be signed in to change notification settings - Fork 874
Strip NUL characters from tagged #7291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,7 @@ | |
| get_mobile_product_from_ua, | ||
| ) | ||
| from kitsune.sumo.decorators import ratelimit | ||
| from kitsune.sumo.i18n import normalize_language | ||
| from kitsune.sumo.templatetags.jinja_helpers import urlparams | ||
| from kitsune.sumo.urlresolvers import reverse | ||
| from kitsune.sumo.utils import ( | ||
|
|
@@ -69,6 +70,7 @@ | |
| paginate, | ||
| set_aaq_context, | ||
| simple_paginate, | ||
| strip_nul_bytes, | ||
| ) | ||
| from kitsune.tags.models import SumoTag | ||
| from kitsune.tags.utils import add_existing_tag | ||
|
|
@@ -173,9 +175,9 @@ def question_list(request, product_slug=None, topic_slug=None): | |
| if show not in FILTER_GROUPS: | ||
| show = "needs-attention" | ||
|
|
||
| tagged = request.GET.get("tagged") | ||
| tagged = strip_nul_bytes(request.GET.get("tagged")) | ||
| tags = None | ||
| topic_slug = request.GET.get("topic", "") or topic_slug | ||
| topic_slug = strip_nul_bytes(request.GET.get("topic")) or topic_slug | ||
|
|
||
| order = request.GET.get("order", "updated") | ||
| if order not in ORDER_BY: | ||
|
|
@@ -587,7 +589,7 @@ def aaq(request, product_slug=None, step=1, is_loginless=False): | |
|
|
||
| # Check if the user is using a mobile device, | ||
| # render step 2 if they are | ||
| product_slug = product_slug or request.GET.get("product") | ||
| product_slug = product_slug or strip_nul_bytes(request.GET.get("product")) | ||
| if product_slug is None: | ||
| change_product = False | ||
| if request.GET.get("q") == "change_product": | ||
|
|
@@ -702,7 +704,7 @@ def aaq(request, product_slug=None, step=1, is_loginless=False): | |
| ) | ||
|
|
||
| if ( | ||
| (from_locale := request.GET.get("from_locale")) | ||
| (from_locale := normalize_language(request.GET.get("from_locale"))) | ||
| and from_locale != request.LANGUAGE_CODE | ||
| and product.questions_enabled(locale=from_locale) | ||
| ): | ||
|
|
@@ -1008,7 +1010,7 @@ def solve(request, question_id, answer_id): | |
| """Accept an answer as the solution to the question.""" | ||
|
|
||
| if not ( | ||
| ((request.method == "GET") and (watch_secret := request.GET.get("watch", None))) | ||
| ((request.method == "GET") and (watch_secret := strip_nul_bytes(request.GET.get("watch", None)))) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| or ( | ||
| (request.method == "POST") | ||
| and (request.user.is_authenticated and request.user.is_active) | ||
|
|
@@ -1100,11 +1102,11 @@ def question_vote(request, question_id): | |
| vote.save() | ||
|
|
||
| if "referrer" in request.GET: | ||
| referrer = request.GET.get("referrer") | ||
| referrer = strip_nul_bytes(request.GET.get("referrer")) | ||
| vote.add_metadata("referrer", referrer) | ||
|
|
||
| if referrer == "search" and "query" in request.GET: | ||
| vote.add_metadata("query", request.GET.get("query")) | ||
| vote.add_metadata("query", strip_nul_bytes(request.GET.get("query"))) | ||
|
|
||
| ua = request.META.get("HTTP_USER_AGENT") | ||
| if ua: | ||
|
|
@@ -1166,11 +1168,11 @@ def answer_vote(request, question_id, answer_id): | |
| vote.save() | ||
|
|
||
| if "referrer" in request.GET: | ||
| referrer = request.GET.get("referrer") | ||
| referrer = strip_nul_bytes(request.GET.get("referrer")) | ||
| vote.add_metadata("referrer", referrer) | ||
|
|
||
| if referrer == "search" and "query" in request.GET: | ||
| vote.add_metadata("query", request.GET.get("query")) | ||
| vote.add_metadata("query", strip_nul_bytes(request.GET.get("query"))) | ||
|
|
||
| ua = request.META.get("HTTP_USER_AGENT") | ||
| if ua: | ||
|
|
@@ -1594,7 +1596,7 @@ def metrics(request, locale_code=None): | |
| """The Support Forum metrics dashboard.""" | ||
| template = "questions/metrics.html" | ||
|
|
||
| product = request.GET.get("product") | ||
| product = strip_nul_bytes(request.GET.get("product")) | ||
| if product: | ||
| product = get_object_or_404(Product, slug=product) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -160,6 +160,13 @@ class TruncationException(Exception): | |
| pass | ||
|
|
||
|
|
||
| def strip_nul_bytes(value): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My main concern with this PR is that we need to remember to sanitize which leaves a lot of room for errors. For example this PR already missed a call I believe in wiki/views. I suspect this will happen often. We could use a middleware for
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @escattone thoughts on this? |
||
| """Strip NUL bytes from a string to prevent database errors.""" | ||
| if value is None: | ||
| return None | ||
| return value.replace("\x00", "") | ||
|
|
||
|
|
||
| def truncated_json_dumps(obj, max_length, key, ensure_ascii=False): | ||
| """Dump an object to JSON, and ensure the dump is less than ``max_length``. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| from kitsune.questions.utils import num_answers, num_questions, num_solutions | ||
| from kitsune.sumo.api_utils import DateTimeUTCField, OrderingFilter, PermissionMod | ||
| from kitsune.sumo.decorators import json_view | ||
| from kitsune.sumo.utils import strip_nul_bytes | ||
| from kitsune.users.models import Profile, Setting | ||
| from kitsune.users.templatetags.jinja_helpers import profile_avatar | ||
|
|
||
|
|
@@ -54,8 +55,8 @@ def to_internal_value(self, data): | |
| @json_view | ||
| def usernames(request): | ||
| """An API to provide auto-complete data for user names.""" | ||
| term = request.GET.get("term", "") | ||
| query = request.GET.get("query", "") | ||
| term = strip_nul_bytes(request.GET.get("term", "")) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some calls like this one, pass an empty string as a default value and others rely on None. We should be consistent
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A good way to enforce this is by adding a |
||
| query = strip_nul_bytes(request.GET.get("query", "")) | ||
| pre = term or query | ||
|
|
||
| if not pre: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noneis not needed in theget()method. It's the default value