Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSRF verification failed for docker after update to seafile 11.0.0 #2707

Closed
FeralFox opened this issue Sep 15, 2023 · 20 comments
Closed

CSRF verification failed for docker after update to seafile 11.0.0 #2707

FeralFox opened this issue Sep 15, 2023 · 20 comments

Comments

@FeralFox
Copy link

FeralFox commented Sep 15, 2023

Hello,

I have deployed Seafile using docker compose. After updating from 10.0.1 to 11.0.0 I cannot login anymore. I get a "403 - CSRF verification failed".

This is my Apache Virtualhost file

<IfModule mod_ssl.c>
<VirtualHost *:443>
RewriteEngine on
ServerName <myserver>
ProxyPreserveHost On
ProxyRequests Off


ProxyPass /seafhttp http://localhost:34539
ProxyPassReverse /seafhttp http://localhost:34539
RewriteRule ^/seafhttp - [QSA,L]

ProxyPass / http://localhost:34538/
ProxyPassReverse / http://localhost:34538/

SSLCertificateFile /etc/letsencrypt/live/<myserver>/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/<myserver>/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

There is also a non-SSL variant of that file too with (almost) equal content.

This here is the docker compose file:

version: '2.0'
services:
  db:
    image: mariadb:10.5
    restart: always
    container_name: seafile-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=SuperSecretPassword  # Requested, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
    volumes:
      - /home/me/seafile/db:/var/lib/mysql  # Requested, specifies the path to MySQL data persistent store.
    networks:
      - seafile-net

  memcached:
    image: memcached:1.6
    restart: always
    container_name: seafile-memcached
    entrypoint: memcached -m 256
    networks:
      - seafile-net

  seafile:
    image: seafileltd/seafile-mc:11.0.0
    restart: always
    container_name: seafile
    ports:
      - "34538:80"
      - "34539:8082"
    volumes:
      - /home/me/seafile/data:/shared   # Requested, specifies the path to Seafile data persistent store.
    environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=SuperSecretPassword  # Requested, the value shuold 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.
      - [email protected] # Specifies Seafile admin user, default is '[email protected]'.
      - SEAFILE_ADMIN_PASSWORD=OtherSuperSecretPassword     # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false
      - DEBUG=True
    depends_on:
      - db
      - memcached
    networks:
      - seafile-net

networks:
  seafile-net:

Is there something I can do to solve this issue?

Thank you in advance!

@cchriso
Copy link

cchriso commented Sep 18, 2023

same for me

@yrd
Copy link

yrd commented Sep 24, 2023

Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

@FeralFox
Copy link
Author

Thank you yrd, that helped.
A short notice to other readers facing the same issue: The mentioned settings file is exposed to the local file system. If you use the docker-compose file as mentioned above, the file is located outside of the container at
/home/me/seafile/data/seafile/conf/seahub_settings.py

@blaine07
Copy link

Thank, all, for posting this resolution.

(this needs to be made more aware; I have been jacking around with this for 3 hours now... LOL)

@Bjorkan
Copy link

Bjorkan commented Nov 19, 2023

Thank you so much for this, made my Seafile instance work again!

Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

@ggogel
Copy link

ggogel commented Nov 20, 2023

The cause of this issue arises from the SERVICE_URL being configured incorrectly. When Seafile is initially set up, the bootstrapping script setup-seafile-mysql.py defaults this URL to http://.... However, if Seafile operates behind an HTTPS reverse proxy and the SERVICE_URL hasn't been manually updated in the admin settings this problem will occur after updating to Seafile 11. The newer version of Django required for Seafile 11 forces strict adherence to this URL, including the correct protocol.

This will probably be a common issue when upgrading and should therefore be addressed in the docs.

@blaine07
Copy link

My service URL has been set as “HTTPS://xxxxxx.com” the entire time in admin settings…

@ggogel
Copy link

ggogel commented Nov 20, 2023

Another cause could be your reverse proxy not setting the headers correctly, see this answer on StackOverflow https://stackoverflow.com/a/71482883

For nginx this would be:

proxy_set_header X-Forwarded-Proto https;

The need for CSRF_TRUSTED_ORIGINS suggests that there is a misconfiguration somewhere in the setup. With that parameter, you essentially force overwrite this security check.

@blaine07
Copy link

Another cause could be your reverse proxy not setting the headers correctly, see this answer on StackOverflow https://stackoverflow.com/a/71482883

For nginx this would be:

proxy_set_header X-Forwarded-Proto https;

The need for CSRF_TRUSTED_ORIGINS suggests that there is a misconfiguration somewhere in the setup. With that parameter, you essentially force overwrite this security check.

Since I am using SeaFile in a container in Unraid it appears Nginx runs with container?; could your proxy_set_header directive need overridden here:

Screenshot 2023-11-20 060533

@cchriso
Copy link

cchriso commented Nov 20, 2023

Thanks, that helped after the upgrade from v10 to v11
IMO that should be stated somewhere in the official upgrading docs, because this will cause almost every instance to not working properly after the update...

Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

@adrinux
Copy link

adrinux commented Dec 8, 2023

Since I am using SeaFile in a container in Unraid it appears Nginx runs with container?; could your proxy_set_header directive need overridden here:

It's likely Unraid is setup much the same way my podman managed seafile is, with the host nginx managing the https connection using a wildcard SSL cert and proxying to nginx/seafile inside the container using http. This change of forwarded protocol won't work, you'd need to adjust proxy_pass to https and more importantly set up seafile in the container to communicate with the reverse proxy over https.

Setting CSRF_TRUSTED_ORIGINS is the way to go.

@blaine07
Copy link

blaine07 commented Dec 8, 2023

Since I am using SeaFile in a container in Unraid it appears Nginx runs with container?; could your proxy_set_header directive need overridden here:

It's likely Unraid is setup much the same way my podman managed seafile is, with the host nginx managing the https connection using a wildcard SSL cert and proxying to nginx/seafile inside the container using http. This change of forwarded protocol won't work, you'd need to adjust proxy_pass to https and more importantly set up seafile in the container to communicate with the reverse proxy over https.

Setting CSRF_TRUSTED_ORIGINS is the way to go.

Yes, I have SeaFile in Unraid too and this was fix; to edit Nginx in container:

ggogel/seafile-containerized#138 (comment)

@dhlavaty
Copy link

Unfortunatelly this does not help when trying/playing with server on localhost. Any other idea how to fix it?

Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

@haris2887
Copy link

haris2887 commented Dec 12, 2023

There are two potential problems/solutions here.

  1. `Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

  1. if you are using custom port mappings in your docker container (Other than 443 and 80) you need to edit the nginx file.
    `Seafile 10 is using django 3.2, while Seafile 11 is using django 4.2.

Compared to django 3.2, django 4.* has introduced a new check for the origin http header in CSRF verification (Django 4.0 release notes | Django documentation | Django). It now compares the values of the origin http header and the request host (https://github.com/django/django/blob/stable/4.2.x/django/middleware/csrf.py#L287). If they are different, an error is triggered.

In your case, you modified the port mapping, causing the origin http header to be http{s}://{ip_or_domain}:20080 and the request host remains {ip_or_domain} without the custom port. This mismatch results in a CSRF error.

For Nginx, you can change your nginx config to the following to fix this problem:

location / {
    ...
    proxy_set_header Host $host:**20080**; <-----# I am using port 20080 in my setup hence I must change this.
    ....`

@sansbyte
Copy link

Try adding your Domain to the corresponding Django setting inside conf/seahub_settings.py:

CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]

Tip for others who repeat my mistake, make sure you don't have a trailing slash in the URL.

@yrd
Copy link

yrd commented Jan 8, 2024

Unfortunatelly this does not help when trying/playing with server on localhost. Any other idea how to fix it?

localhost should be anything special in this case and CSRF_TRUSTED_ORIGINS should work. If you are running on something other than port 80, you will need to include the port:

CSRF_TRUSTED_ORIGINS = ["http://localhost:3000"]

Also make sure you're accessing Seafile using http://localhost:3000 instead of http://127.0.0.1:3000 (or similar) so the browser correctly sets the Host header.

@Cricx
Copy link

Cricx commented Jan 13, 2024

same problem... and adding my seafile url in CSRF_TRUSTED_ORIGINS resolve the issue. But it is not the best solution.
After verifying my conf, i'm noticed a trailing slash in the url. After removing this slash, no more issue after removing my site in CSRF_TRUSTED_ORIGINS.
Unfortunately don't work for sys admin via web interface...

@moritzj29
Copy link

After verifying my conf, i'm noticed a trailing slash in the url.

Exactly! Would it be possible to remove the trailing slash when the SERVICE_URL is generated?

Example of Docker bootstrapping which adds the trailing slash:
https://github.com/haiwen/seafile-docker/blob/efff562342036212bee746aa203b152ee0bf9420/scripts/scripts_11.0/setup-seafile-mysql.py#L1048

@freeplant freeplant reopened this Mar 24, 2024
@freeplant
Copy link
Member

Thanks for reporting the trailing slash problem. It has been fixed in haiwen/seafile-docker#383 and haiwen/seahub#5997

@xlrshubham
Copy link

@freeplant Could you modify the /opt/seafile/seafile-server-latest/setup-seafile.sh to add CSRF_TRUSTED_ORIGINS also in seahub_setting.py ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests