Introduce safer_staticfiles app as user-friendly security measure for #260 (#261)

* Introduce safer_staticfiles app to ignore .py,.html as security measure. Docs up-to-date

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
adriaan 2023-04-11 13:55:11 +02:00 committed by GitHub
parent 2fa8b46936
commit fa41387a53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 7 deletions

View file

@ -20,12 +20,44 @@ Read on to learn about the details!
# Release notes
*Version 0.27* includes an additional installable app *django_components.safer_staticfiles*. It provides the same behavior as *django.contrib.staticfiles* but with extra security guarantees (more info below in Security Notes).
*Version 0.26* changes the syntax for `{% slot %}` tags. From now on, we separate defining a slot (`{% slot %}`) from filling a slot with content (`{% fill %}`). This means you will likely need to change a lot of slot tags to fill. We understand this is annoying, but it's the only way we can get support for nested slots that fill in other slots, which is a very nice feature to have access to. Hoping that this will feel worth it!
*Version 0.22* starts autoimporting all files inside components subdirectores, to simplify setup. An existing project might start to get AlreadyRegistered-errors because of this. To solve this, either remove your custom loading of components, or set "autodiscover": False in settings.COMPONENTS.
*Version 0.17* renames `Component.context` and `Component.template` to `get_context_data` and `get_template_name`. The old methods still work, but emit a deprecation warning. This change was done to sync naming with Django's class based views, and make using django-components more familiar to Django users. `Component.context` and `Component.template` will be removed when version 1.0 is released.
# Security notes 🚨
*You are advised to read this section before using django-components in production.*
## Static files
Components can be organized however you prefer.
That said, our prefered way is to keep the files of a component close together by bundling them in the same directory.
This means that files containing backend logic, such as Python modules and HTML templates, live in the same directory as static files, e.g. JS and CSS.
If your are using _django.contrib.staticfiles_ to collect static files, no distinction is made between the different kinds of files.
As a result, your Python code and templates may inadvertently become available on your static file server.
You probably don't want this, as parts of your backend logic will be exposed, posing a __potential security vulnerability__.
As of *v0.27*, django-components ships with an additional installable app *django_components.__safer_staticfiles__*.
It is a drop-in replacement for *django.contrib.staticfiles*.
Its behavior is 100% identical except it ignores .py and .html files, meaning these will not end up on your static files server.
To use it, add it to INSTALLED_APPS and remove _django.contrib.staticfiles_.
```python
INSTALLED_APPS = [
# django.contrib.staticfiles # <-- REMOVE
"django_components",
"django_components.safer_staticfiles" # <-- ADD
]
```
If you are on an older version of django-components, your alternatives are a) passing `--ignore <pattern>` options to the _collecstatic_ CLI command, or b) defining a subclass of StaticFilesConfig.
Both routes are described in the official [docs of the _staticfiles_ app](https://docs.djangoproject.com/en/4.2/ref/contrib/staticfiles/#customizing-the-ignored-pattern-list).
# Installation
Install the app into your environment:

View file

@ -0,0 +1,18 @@
from django.contrib.staticfiles.apps import StaticFilesConfig
class SaferStaticFilesConfig(StaticFilesConfig):
"""
Extend the `ignore_patterns` class attr of StaticFilesConfig to include Python
modules and HTML files.
When this class is registered as an installed app,
`$ ./manage.py collectstatic` will ignore .py and .html files,
preventing potentially sensitive backend logic from being leaked
by the static file server.
"""
default = (
True # Ensure that _this_ app is registered, as opposed to parent cls.
)
ignore_patterns = StaticFilesConfig.ignore_patterns + ["*.py", "*.html"]

View file

@ -194,7 +194,7 @@ class SlotNode(Node):
else:
fill_node = fill_node_stack.pop()
nodelist = fill_node.nodelist
# context[FILLED_SLOTS_CONTEXT_KEY].pop(self.name)
if fill_node.alias_var is not None:
aliased_slot_var = UserSlotVar(self, context)
resolved_alias_name = fill_node.alias_var.resolve(context)

View file

@ -19,18 +19,20 @@ DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# Replaced by django_components.safer_staticfiles as of v0.27:
# "django.contrib.staticfiles",
"django_components",
"django_components.safer_staticfiles",
"calendarapp",
]
# Application definition
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
@ -122,11 +124,11 @@ USE_TZ = True
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = "static/"
STATICFILES_DIRS = [
BASE_DIR / "components",
]
STATICFILES_DIRS = [BASE_DIR / "components"]
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
STATIC_ROOT = "staticfiles"