Merge pull request #674 from paperless-ngx/feature-django4-csrf

Add `PAPERLESS_URL` env variable & CSRF var
This commit is contained in:
Felix E 2022-04-08 21:00:57 +02:00 committed by GitHub
commit dde7771dc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 11 deletions

View File

@ -22,6 +22,10 @@
# Docker setup does not use the configuration file. # Docker setup does not use the configuration file.
# A few commonly adjusted settings are provided below. # A few commonly adjusted settings are provided below.
# This is required if you will be exposing Paperless-ngx on a public domain
# (if doing so please consider security measures such as reverse proxy)
#PAPERLESS_URL=https://paperless.example.com
# Adjust this key if you plan to make paperless available publicly. It should # Adjust this key if you plan to make paperless available publicly. It should
# be a very long sequence of random characters. You don't need to remember it. # be a very long sequence of random characters. You don't need to remember it.
#PAPERLESS_SECRET_KEY=change-me #PAPERLESS_SECRET_KEY=change-me

View File

@ -142,7 +142,24 @@ PAPERLESS_SECRET_KEY=<key>
Default is listed in the file ``src/paperless/settings.py``. Default is listed in the file ``src/paperless/settings.py``.
PAPERLESS_ALLOWED_HOSTS<comma-separated-list> PAPERLESS_URL=<url>
This setting can be used to set the three options below (ALLOWED_HOSTS,
CORS_ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS). If the other options are
set the values will be combined with this one. Do not include a trailing
slash. E.g. https://paperless.domain.com
Defaults to empty string, leaving the other settings unaffected.
PAPERLESS_CSRF_TRUSTED_ORIGINS=<comma-separated-list>
A list of trusted origins for unsafe requests (e.g. POST). As of Django 4.0
this is required to access the Django admin via the web.
See https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins
Can also be set using PAPERLESS_URL (see above).
Defaults to empty string, which does not add any origins to the trusted list.
PAPERLESS_ALLOWED_HOSTS=<comma-separated-list>
If you're planning on putting Paperless on the open internet, then you If you're planning on putting Paperless on the open internet, then you
really should set this value to the domain name you're using. Failing to do really should set this value to the domain name you're using. Failing to do
so leaves you open to HTTP host header attacks: so leaves you open to HTTP host header attacks:
@ -151,12 +168,16 @@ PAPERLESS_ALLOWED_HOSTS<comma-separated-list>
Just remember that this is a comma-separated list, so "example.com" is fine, Just remember that this is a comma-separated list, so "example.com" is fine,
as is "example.com,www.example.com", but NOT " example.com" or "example.com," as is "example.com,www.example.com", but NOT " example.com" or "example.com,"
Can also be set using PAPERLESS_URL (see above).
Defaults to "*", which is all hosts. Defaults to "*", which is all hosts.
PAPERLESS_CORS_ALLOWED_HOSTS<comma-separated-list> PAPERLESS_CORS_ALLOWED_HOSTS=<comma-separated-list>
You need to add your servers to the list of allowed hosts that can do CORS You need to add your servers to the list of allowed hosts that can do CORS
calls. Set this to your public domain name. calls. Set this to your public domain name.
Can also be set using PAPERLESS_URL (see above).
Defaults to "http://localhost:8000". Defaults to "http://localhost:8000".
PAPERLESS_FORCE_SCRIPT_NAME=<path> PAPERLESS_FORCE_SCRIPT_NAME=<path>

View File

@ -92,6 +92,14 @@ echo ""
echo "1. Application configuration" echo "1. Application configuration"
echo "============================" echo "============================"
echo ""
echo "The URL paperless will be available at. This is required if the"
echo "installation will be accessible via the web, otherwise can be left blank."
echo ""
ask "URL" ""
URL=$ask_result
echo "" echo ""
echo "The port on which the paperless webserver will listen for incoming" echo "The port on which the paperless webserver will listen for incoming"
echo "connections." echo "connections."
@ -278,6 +286,7 @@ if [[ "$DATABASE_BACKEND" == "postgres" ]] ; then
fi fi
fi fi
echo "" echo ""
echo "URL: $URL"
echo "Port: $PORT" echo "Port: $PORT"
echo "Database: $DATABASE_BACKEND" echo "Database: $DATABASE_BACKEND"
echo "Tika enabled: $TIKA_ENABLED" echo "Tika enabled: $TIKA_ENABLED"
@ -313,6 +322,9 @@ SECRET_KEY=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 64 | head -n 1)
DEFAULT_LANGUAGES="deu eng fra ita spa" DEFAULT_LANGUAGES="deu eng fra ita spa"
{ {
if [[ ! $URL == "" ]] ; then
echo "PAPERLESS_URL=$URL"
fi
if [[ ! $USERMAP_UID == "1000" ]] ; then if [[ ! $USERMAP_UID == "1000" ]] ; then
echo "USERMAP_UID=$USERMAP_UID" echo "USERMAP_UID=$USERMAP_UID"
fi fi

View File

@ -27,8 +27,10 @@
# Security and hosting # Security and hosting
#PAPERLESS_SECRET_KEY=change-me #PAPERLESS_SECRET_KEY=change-me
#PAPERLESS_ALLOWED_HOSTS=example.com,www.example.com #PAPERLESS_URL=https://example.com
#PAPERLESS_CORS_ALLOWED_HOSTS=http://example.com,http://localhost:8000 #PAPERLESS_CSRF_TRUSTED_ORIGINS=https://example.com # can be set using PAPERLESS_URL
#PAPERLESS_ALLOWED_HOSTS=example.com,www.example.com # can be set using PAPERLESS_URL
#PAPERLESS_CORS_ALLOWED_HOSTS=https://localhost:8080,https://example.com # can be set using PAPERLESS_URL
#PAPERLESS_FORCE_SCRIPT_NAME= #PAPERLESS_FORCE_SCRIPT_NAME=
#PAPERLESS_STATIC_URL=/static/ #PAPERLESS_STATIC_URL=/static/
#PAPERLESS_AUTO_LOGIN_USERNAME= #PAPERLESS_AUTO_LOGIN_USERNAME=

View File

@ -4,6 +4,7 @@ import multiprocessing
import os import os
import re import re
from typing import Final from typing import Final
from urllib.parse import urlparse
from concurrent_log_handler.queue import setup_logging_queues from concurrent_log_handler.queue import setup_logging_queues
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -219,7 +220,15 @@ if DEBUG:
else: else:
X_FRAME_OPTIONS = "SAMEORIGIN" X_FRAME_OPTIONS = "SAMEORIGIN"
# We allow CORS from localhost:8080
# The next 3 settings can also be set using just PAPERLESS_URL
_csrf_origins = os.getenv("PAPERLESS_CSRF_TRUSTED_ORIGINS")
if _csrf_origins:
CSRF_TRUSTED_ORIGINS = _csrf_origins.split(",")
else:
CSRF_TRUSTED_ORIGINS = []
# We allow CORS from localhost:8000
CORS_ALLOWED_ORIGINS = tuple( CORS_ALLOWED_ORIGINS = tuple(
os.getenv("PAPERLESS_CORS_ALLOWED_HOSTS", "http://localhost:8000").split(","), os.getenv("PAPERLESS_CORS_ALLOWED_HOSTS", "http://localhost:8000").split(","),
) )
@ -228,6 +237,22 @@ if DEBUG:
# Allow access from the angular development server during debugging # Allow access from the angular development server during debugging
CORS_ALLOWED_ORIGINS += ("http://localhost:4200",) CORS_ALLOWED_ORIGINS += ("http://localhost:4200",)
_allowed_hosts = os.getenv("PAPERLESS_ALLOWED_HOSTS")
if _allowed_hosts:
ALLOWED_HOSTS = _allowed_hosts.split(",")
else:
ALLOWED_HOSTS = ["*"]
_paperless_url = os.getenv("PAPERLESS_URL")
if _paperless_url:
_paperless_uri = urlparse(_paperless_url)
CSRF_TRUSTED_ORIGINS.append(_paperless_url)
CORS_ALLOWED_ORIGINS += (_paperless_url,)
if _allowed_hosts:
ALLOWED_HOSTS.append(_paperless_uri.hostname)
else:
ALLOWED_HOSTS = [_paperless_uri.hostname]
# The secret key has a default that should be fine so long as you're hosting # The secret key has a default that should be fine so long as you're hosting
# Paperless on a closed network. However, if you're putting this anywhere # Paperless on a closed network. However, if you're putting this anywhere
# public, you should change the key to something unique and verbose. # public, you should change the key to something unique and verbose.
@ -236,12 +261,6 @@ SECRET_KEY = os.getenv(
"e11fl1oa-*ytql8p)(06fbj4ukrlo+n7k&q5+$1md7i+mge=ee", "e11fl1oa-*ytql8p)(06fbj4ukrlo+n7k&q5+$1md7i+mge=ee",
) )
_allowed_hosts = os.getenv("PAPERLESS_ALLOWED_HOSTS")
if _allowed_hosts:
ALLOWED_HOSTS = _allowed_hosts.split(",")
else:
ALLOWED_HOSTS = ["*"]
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{ {
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",