From 072222996fce5828079eb2007a8f4970436b5469 Mon Sep 17 00:00:00 2001 From: Rinkit Adhana Date: Wed, 9 Apr 2025 17:44:00 +0530 Subject: [PATCH 1/5] HTML rendering fixed --- website/templates/blog/post_detail.html | 2 +- website/views/blog.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/website/templates/blog/post_detail.html b/website/templates/blog/post_detail.html index f183f3e373..a113f4a217 100644 --- a/website/templates/blog/post_detail.html +++ b/website/templates/blog/post_detail.html @@ -22,7 +22,7 @@

{{ post.title }}

By {{ post.author }} on {{ post.created_at }}

-
{{ post.content }}
+
{{ post.content | safe }}
{% if post.image %}
Date: Sat, 3 May 2025 02:23:06 +0530 Subject: [PATCH 2/5] fixed XSS vulnerability --- website/templates/blog/post_detail.html | 2 +- website/views/blog.py | 40 ++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/website/templates/blog/post_detail.html b/website/templates/blog/post_detail.html index a113f4a217..f183f3e373 100644 --- a/website/templates/blog/post_detail.html +++ b/website/templates/blog/post_detail.html @@ -22,7 +22,7 @@

{{ post.title }}

By {{ post.author }} on {{ post.created_at }}

-
{{ post.content | safe }}
+
{{ post.content }}
{% if post.image %}
Date: Sat, 3 May 2025 02:45:48 +0530 Subject: [PATCH 3/5] django-bleach added --- poetry.lock | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 157d9ca4c9..23e19b1535 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -344,6 +344,27 @@ d = ["aiohttp (>=3.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "bleach" +version = "5.0.1" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, + {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, +] + +[package.dependencies] +six = ">=1.9.0" +tinycss2 = {version = ">=1.1.0,<1.2", optional = true, markers = "extra == \"css\""} +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.2)"] +dev = ["Sphinx (==4.3.2)", "black (==22.3.0) ; implementation_name == \"cpython\"", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961) ; implementation_name == \"cpython\"", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] + [[package]] name = "cachetools" version = "5.5.1" @@ -907,6 +928,22 @@ files = [ Django = ">=1.11" six = "*" +[[package]] +name = "django-bleach" +version = "3.1.0" +description = "Easily use bleach with Django models and templates" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "django-bleach-3.1.0.tar.gz", hash = "sha256:766405a32b877a5beb6b377ace0d8bbe2a7d4d6304f04542aa14fd74b14398a7"}, + {file = "django_bleach-3.1.0-py2.py3-none-any.whl", hash = "sha256:8d9117ca08c182ee20daaf99abbf800154db5cdbcb66ef1252dd7bb542dcf19d"}, +] + +[package.dependencies] +bleach = {version = ">=5,<6", extras = ["css"]} +Django = ">=3.2" + [[package]] name = "django-braces" version = "1.16.0" @@ -3430,6 +3467,25 @@ xls = ["xlrd", "xlwt"] xlsx = ["openpyxl (>=2.6.0)"] yaml = ["pyyaml"] +[[package]] +name = "tinycss2" +version = "1.1.1" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "tinycss2-1.1.1-py3-none-any.whl", hash = "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8"}, + {file = "tinycss2-1.1.1.tar.gz", hash = "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["coverage[toml]", "pytest", "pytest-cov", "pytest-flake8", "pytest-isort"] + [[package]] name = "tld" version = "0.13" @@ -3790,6 +3846,18 @@ packaging = "*" python-dotenv = "*" requests = "*" +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + [[package]] name = "websocket-client" version = "1.8.0" @@ -4033,4 +4101,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.1" python-versions = ">=3.11.2,<3.14" -content-hash = "c7bab7fbcc63a6e274e7527c7253987b18d3411b1ba494e9082a2f91600358fd" +content-hash = "12b0f8f12f60e1de63a42a1cff74b0db659d0faa47e039ff72b818f92c1de1ea" diff --git a/pyproject.toml b/pyproject.toml index a5ecceb364..2b819389db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,7 @@ python-dateutil = "^2.9.0.post0" pyzipper = "^0.3.6" tweepy = "^4.15.0" better-profanity = "^0.7.0" +django-bleach = "^3.1.0" [tool.poetry.group.dev.dependencies] From b8003165ae76dde15f48e2c6fe2fddd5e63a5e86 Mon Sep 17 00:00:00 2001 From: Rinkit Adhana Date: Sat, 3 May 2025 03:32:20 +0530 Subject: [PATCH 4/5] fixed using django-bleach --- website/templates/blog/post_detail.html | 2 +- website/views/blog.py | 62 +++++++++++-------------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/website/templates/blog/post_detail.html b/website/templates/blog/post_detail.html index f183f3e373..a113f4a217 100644 --- a/website/templates/blog/post_detail.html +++ b/website/templates/blog/post_detail.html @@ -22,7 +22,7 @@

{{ post.title }}

By {{ post.author }} on {{ post.created_at }}

-
{{ post.content }}
+
{{ post.content | safe }}
{% if post.image %}
Date: Sat, 3 May 2025 03:39:17 +0530 Subject: [PATCH 5/5] pre-commit fix --- website/views/blog.py | 68 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/website/views/blog.py b/website/views/blog.py index db3095834d..434f36c4b5 100644 --- a/website/views/blog.py +++ b/website/views/blog.py @@ -1,13 +1,13 @@ +import bleach import markdown from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.contenttypes.models import ContentType -from django.utils.safestring import mark_safe from django.utils.text import slugify from django.views import generic -import bleach from website.models import Post + class PostListView(generic.ListView): model = Post template_name = "blog/post_list.html" @@ -21,38 +21,65 @@ class PostDetailView(generic.DetailView): def get_object(self): post = super().get_object() - + html_content = markdown.markdown( post.content, - extensions=["markdown.extensions.fenced_code", - "markdown.extensions.tables", - "markdown.extensions.nl2br"], + extensions=["markdown.extensions.fenced_code", "markdown.extensions.tables", "markdown.extensions.nl2br"], ) - + allowed_tags = [ - 'p', 'b', 'i', 'u', 'em', 'strong', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'pre', 'code', 'span', 'div', 'blockquote', 'hr', 'br', 'ul', 'ol', 'li', - 'dd', 'dt', 'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td', + "p", + "b", + "i", + "u", + "em", + "strong", + "a", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "pre", + "code", + "span", + "div", + "blockquote", + "hr", + "br", + "ul", + "ol", + "li", + "dd", + "dt", + "img", + "table", + "thead", + "tbody", + "tr", + "th", + "td", ] - + allowed_attributes = { - 'a': ['href', 'title', 'rel'], - 'img': ['src', 'alt', 'title', 'width', 'height'], - 'code': ['class'], - '*': ['class', 'id'], + "a": ["href", "title", "rel"], + "img": ["src", "alt", "title", "width", "height"], + "code": ["class"], + "*": ["class", "id"], } - - allowed_protocols = ['http', 'https', 'mailto', 'tel'] - + + allowed_protocols = ["http", "https", "mailto", "tel"] + post.content = bleach.clean( html_content, tags=allowed_tags, attributes=allowed_attributes, protocols=allowed_protocols, strip=True, - strip_comments=True + strip_comments=True, ) - + return post def get_context_data(self, **kwargs): @@ -61,6 +88,7 @@ def get_context_data(self, **kwargs): context["all_comment"] = self.object.comments.all() return context + class PostCreateView(LoginRequiredMixin, generic.CreateView): model = Post fields = ["title", "content", "image"]