Skip to content

Commit

Permalink
fix: prevent html tags from input
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Fiedler <miketheman@gmail.com>
  • Loading branch information
miketheman committed Nov 21, 2024
1 parent ff45489 commit c95eb9c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ parallel = true
exclude_lines = [
"pragma: no cover",
"class \\w+\\(Interface\\):",
"if (typing\\.)?TYPE_CHECKING:",
"if (typing\\.|t\\.)?TYPE_CHECKING:",
]

[tool.curlylint]
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/packaging/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,16 @@ def test_summary_too_long(self, pyramid_request):

assert not form.validate()
assert "summary" in form.errors

def test_summary_contains_html_tags(self, pyramid_request):
pyramid_request.POST = MultiDict(
{
"inspector_link": self.inspector_link,
"summary": '<img src="https://example.com/image.png">',
}
)

form = SubmitMalwareObservationForm(pyramid_request.POST)

assert not form.validate()
assert "summary" in form.errors
31 changes: 30 additions & 1 deletion tests/unit/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
from webob.multidict import MultiDict
from wtforms.validators import ValidationError

from warehouse.forms import PasswordStrengthValidator, SetLocaleForm, URIValidator
from warehouse.forms import (
PasswordStrengthValidator,
PreventHTMLTagsValidator,
SetLocaleForm,
URIValidator,
)


class TestURIValidator:
Expand Down Expand Up @@ -83,6 +88,30 @@ def test_invalid_password(self, password, expected):
assert str(exc.value) == expected


class TestPreventHTMLTagsValidator:
def test_valid(self):
validator = PreventHTMLTagsValidator()
validator(pretend.stub(), pretend.stub(data="https://example.com"))

def test_invalid(self):
validator = PreventHTMLTagsValidator()
with pytest.raises(ValidationError) as exc:
validator(
pretend.stub(), pretend.stub(data="<img src='https://example.com'>")
)

assert str(exc.value) == "HTML tags are not allowed"

def test_custom_message(self):
validator = PreventHTMLTagsValidator(message="No HTML allowed")
with pytest.raises(ValidationError) as exc:
validator(
pretend.stub(), pretend.stub(data="<img src='https://example.com'>")
)

assert str(exc.value) == "No HTML allowed"


class TestSetLocaleForm:
def test_validate(self):
form = SetLocaleForm(MultiDict({"locale_id": "es"}))
Expand Down
24 changes: 24 additions & 0 deletions warehouse/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import typing as t

from html import escape

from wtforms import Form as BaseForm, StringField
from wtforms.validators import InputRequired, ValidationError
from zxcvbn import zxcvbn

from warehouse.i18n import KNOWN_LOCALES
from warehouse.utils.http import is_valid_uri

if t.TYPE_CHECKING:
from wtforms.fields import Field


class URIValidator:
def __init__(
Expand Down Expand Up @@ -75,6 +84,21 @@ def __call__(self, form, field):
raise ValidationError(msg)


class PreventHTMLTagsValidator:
"""
Validate the field to ensure that it does not contain any HTML tags.
"""

def __init__(self, message: str | None = None):
if message is None:
message = "HTML tags are not allowed"
self.message = message

def __call__(self, form: BaseForm, field: Field):
if escape(field.data) != field.data:
raise ValidationError(self.message)


class SetLocaleForm(BaseForm):
__params__ = ["locale_id"]

Expand Down
2 changes: 2 additions & 0 deletions warehouse/packaging/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import wtforms

from warehouse.forms import PreventHTMLTagsValidator
from warehouse.i18n import localize as _


Expand All @@ -32,6 +33,7 @@ class SubmitMalwareObservationForm(wtforms.Form):
validators=[
wtforms.validators.InputRequired(),
wtforms.validators.Length(min=10, max=2000),
PreventHTMLTagsValidator(),
],
)

Expand Down

0 comments on commit c95eb9c

Please sign in to comment.