Forbidden (403) CSRF verification failed - on docker 11.0.1

EDIT: I just tried a fresh install from the 11.0.1 docker using the docker-compose.yml and apache configs below (used seafile-mc:11.0.1 instead of seafile-mc:latest) and I got the same error. So the problem seems to be in v11 and not in my v10 upgrade. The v10 docker worked just fine with the same docker-compose.yml and apache config.


I already searched and looked at all threads about CSRF issues in here, particularly this one and no suggested fix worked for me.

I’m using Apache with a reverse proxy, and everything worked just fine before on the v10 docker before the upgrade.

Upgraded docker to 11.0.1: stopped containers, edited docker-compose.yml and replaced seafile-mc:latest with seafile-mc:11.0.1, did a docker-compose up -d, entered seafile docker, stopped seahub and seafile services, ran the upgrade_10_11 bash script, restarted docker.

Now I get the error in the title in all browsers (chrome, firefox, etc) when I attempt to login on the web.

NOTE: desktop client sync’ing seems to work just fine … it’s the web client that croaks.

Anyone knows of a fix?

apache conf on the host

<VirtualHost *:80>
ServerName sf.example.com
Redirect permanent / https://sf.example.com/
</VirtualHost>

<VirtualHost *:443>
# enable HTTP/2, if available
#Protocols h2 http/1.1

ServerName sf.example.com
ServerAdmin noreply@example.com

RequestHeader set X-Forwarded-Proto "https"
ProxyVia On
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://localhost:20080/
ProxyPassReverse / http://localhost:20080/

# Possible values: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel notice
#LogLevel notice rewrite:trace3

ErrorLog ${APACHE_LOG_DIR}/sf-error.log
CustomLog ${APACHE_LOG_DIR}/sf-access.log combined

SSLEngine on

SSLCertificateFile /etc/ssl/acme.sh/example.com.fullchain.pem
SSLCertificateKeyFile /etc/ssl/acme.sh/example.com.key.pem

<FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
  SSLOptions +StdEnvVars
</Directory>

</VirtualHost>

docker-compose.yml

services:
  db:
    image: mariadb:10.11
    container_name: seafile-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=blablabla  # Requested, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
    volumes:
      - /var/seafile/mysql/db:/var/lib/mysql  # Requested, specifies the path to MySQL data persistent store.
    networks:
      - seafile-net

  memcached:
    image: memcached:1.6.18
    container_name: seafile-memcached
    entrypoint: memcached -m 256
    networks:
      - seafile-net

  seafile:
    image: seafileltd/seafile-mc:11.0.1
    container_name: seafile
    ports:
      - 20080:80
      #- 20443:443  # If https is enabled, cancel the comment.
    extra_hosts:
      - host.docker.internal:host-gateway  # allow the docker to reach host servies by using the dns name "host.docker.internal" instead of extracting the host's IP address 172
    volumes:
      - /var/seafile/data:/shared   # Requested, specifies the path to Seafile data persistent store.
    environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=blablabla  # Requested, the value should be root's password of MySQL service.
      - TIME_ZONE=Etc/UTC  # Optional, default is UTC. Should be uncomment and set to your local time zone.
      - SEAFILE_ADMIN_EMAIL=seafile.admin@example.com # Specifies Seafile admin user, default is 'me@example.com'.
      - SEAFILE_ADMIN_PASSWORD=blablabla     # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false   # Whether to use https or not.
      - SEAFILE_SERVER_HOSTNAME=sf.example.com  # Specifies your host name if https is enabled.
      - FORCE_HTTPS_IN_CONF=true  # if you want a reverse proxy with its own ssl cert then enable this, and SEAFILE_SERVER_LETSENCRYPT as well as port 443:443
    depends_on:
      - db
      - memcached
    networks:
      - seafile-net

networks:
  seafile-net:

seahub_settings.py in docker

# -*- coding: utf-8 -*-
DEBUG = True
SECRET_KEY = "b'blablabla'"
SERVICE_URL = "https://sf.example.com/"
CSRF_TRUSTED_ORIGINS = ['sf.example.com']  # tried without [], etc

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'seahub_db',
        'USER': 'seafile',
        'PASSWORD': 'blablabla',
        'HOST': 'db',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}


CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached:11211',
    },
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    },
}
COMPRESS_CACHE_BACKEND = 'locmem'
TIME_ZONE = 'Etc/UTC'
FILE_SERVER_ROOT = "https://sf.example.com/seafhttp"

EMAIL_USE_TLS=False
EMAIL_HOST="host.docker.internal"
#EMAIL_HOST_USER="AKIAXXXXXXXXXX"
#EMAIL_HOST_PASSWORD="xxxxxxxxxxxxxxxxxxxx"
EMAIL_PORT=25
DEFAULT_FROM_EMAIL="seafile.admin@example.com"
SERVER_EMAIL="seafile.admin@example.com"

nginx conf in docker

# -*- mode: nginx -*-
# Auto generated at 10/19/2023 17:40:03
server {
listen 80;
server_name sf.example.com;

    client_max_body_size 10m;

    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_read_timeout 310s;
        proxy_set_header Host $host;
        proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection "";
        proxy_http_version 1.1;

        client_max_body_size 0;
        access_log      /var/log/nginx/seahub.access.log seafileformat;
        error_log       /var/log/nginx/seahub.error.log;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        client_max_body_size 0;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
        proxy_request_buffering off;
        access_log      /var/log/nginx/seafhttp.access.log seafileformat;
        error_log       /var/log/nginx/seafhttp.error.log;
    }

    location /notification/ping {
        proxy_pass http://127.0.0.1:8083/ping;
        access_log      /var/log/nginx/notification.access.log seafileformat;
        error_log       /var/log/nginx/notification.error.log;
    }

    location /notification {
        proxy_pass http://127.0.0.1:8083/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        access_log      /var/log/nginx/notification.access.log seafileformat;
        error_log       /var/log/nginx/notification.error.log;
    }

    location /seafdav {
        proxy_pass         http://127.0.0.1:8080;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout  1200s;
        client_max_body_size 0;

        access_log      /var/log/nginx/seafdav.access.log seafileformat;
        error_log       /var/log/nginx/seafdav.error.log;
    }

    location /media {
        root /opt/seafile/seafile-server-latest/seahub;
    }

}

Same here - I have Seafile behind the nginx proxy that adds https, but that worked before with v10.

The solution seems to be here: github - haiwen/seafile/issues/2707

2 Likes

CSRF verification failed for docker after update to seafile 11.0.0 · Issue #2707 · haiwen/seafile · GitHub