[GH-ISSUE #22] Special characters in VIKUNJA_DATABASE_PASSWORD #5832

Closed
opened 2026-04-20 16:11:03 -05:00 by GiteaMirror · 13 comments
Owner

Originally created by @xrhstosmour on GitHub (Mar 9, 2022).
Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/22

I am trying to deploy via docker-compose the vikunja/api image, using as database PostgreSQL.
When the VIKUNJA_DATABASE_PASSWORD environment variable contains any special character like:

  • #
  • $
  • !
  • @

the deployment fails with the following error: pq: password authentication failed for user "<my_database_user>" usermod: no changes.
Only if i remove every special character the deployment suceeds.
I also tried escaping the password but nothing changed. A tool you can use for escaping the password can be found here.
Below you can find an example of the docker-compose.yml i tried:

vikunja_api:
  image: "vikunja/api:latest"
  container_name: "vikunja_api"
  restart: "unless-stopped"
  networks:
    - "public"
    - "local"
  ports:
    - "${VIKUNJA_API_PORT?Variable not set}:${VIKUNJA_API_PORT?Variable not set}"
  depends_on:
    - "postgresql"
  environment:
    - "VIKUNJA_DATABASE_TYPE=${VIKUNJA_DATABASE_TYPE?Variable not set}"
    - "VIKUNJA_DATABASE_HOST=${POSTGRESQL_SERVER?Variable not set}:${POSTGRESQL_PORT?Variable not set}"
    # Escape special charactes in passwords using the following tool: https://www.urlencoder.org/.
    - "VIKUNJA_DATABASE_PASSWORD=${VIKUNJA_DATABASE_ESCAPED_PASSWORD?Variable not set}"
    - "VIKUNJA_DATABASE_USER=${VIKUNJA_DATABASE_USER?Variable not set}"
    - "VIKUNJA_DATABASE_DATABASE=${VIKUNJA_DATABASE?Variable not set}"
    - "VIKUNJA_SERVICE_ENABLEREGISTRATION=${VIKUNJA_API_ENABLE_REGISTRATION?Variable not set}"
    - "VIKUNJA_SERVICE_TIMEZONE=${DOCKER_TIMEZONE?Variable not set}"
    - "PUID=${DOCKER_USER_UID?Variable not set}"
    - "PGID=${DOCKER_USER_UID?Variable not set}"
    - "VIKUNJA_FIRST_CHILD=${VIKUNJA_FIRST_CHILD?Variable not set}"
  volumes:
    - "vikunja_api_data:/app/vikunja/files"
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.vikunja_api.rule=Host(`${VIKUNJA_API_HOST?Variable not set}`) && PathPrefix(`/api/v1`, `/dav/`, `/.well-known/`)"
    - "traefik.http.routers.vikunja_api.service=vikunja_api"
    - "traefik.http.routers.vikunja_api.tls=true"
    - "traefik.http.routers.vikunja_api.entrypoints=web_secure"
    - "traefik.http.services.vikunja_api.loadbalancer.server.port=${VIKUNJA_API_PORT?Variable not set}"

How should i face this problem and proceed with the deployment?
Thank you in advance.

Originally created by @xrhstosmour on GitHub (Mar 9, 2022). Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/22 I am trying to deploy via docker-compose the `vikunja/api` image, using as database PostgreSQL. When the VIKUNJA_DATABASE_PASSWORD environment variable contains any special character like: - `#` - `$` - `!` - `@` the deployment fails with the following error: `pq: password authentication failed for user "<my_database_user>" usermod: no changes`. Only if i remove every special character the deployment suceeds. I also tried escaping the password but nothing changed. A tool you can use for escaping the password can be found [here](https://www.urlencoder.org/). Below you can find an example of the docker-compose.yml i tried: ``` vikunja_api: image: "vikunja/api:latest" container_name: "vikunja_api" restart: "unless-stopped" networks: - "public" - "local" ports: - "${VIKUNJA_API_PORT?Variable not set}:${VIKUNJA_API_PORT?Variable not set}" depends_on: - "postgresql" environment: - "VIKUNJA_DATABASE_TYPE=${VIKUNJA_DATABASE_TYPE?Variable not set}" - "VIKUNJA_DATABASE_HOST=${POSTGRESQL_SERVER?Variable not set}:${POSTGRESQL_PORT?Variable not set}" # Escape special charactes in passwords using the following tool: https://www.urlencoder.org/. - "VIKUNJA_DATABASE_PASSWORD=${VIKUNJA_DATABASE_ESCAPED_PASSWORD?Variable not set}" - "VIKUNJA_DATABASE_USER=${VIKUNJA_DATABASE_USER?Variable not set}" - "VIKUNJA_DATABASE_DATABASE=${VIKUNJA_DATABASE?Variable not set}" - "VIKUNJA_SERVICE_ENABLEREGISTRATION=${VIKUNJA_API_ENABLE_REGISTRATION?Variable not set}" - "VIKUNJA_SERVICE_TIMEZONE=${DOCKER_TIMEZONE?Variable not set}" - "PUID=${DOCKER_USER_UID?Variable not set}" - "PGID=${DOCKER_USER_UID?Variable not set}" - "VIKUNJA_FIRST_CHILD=${VIKUNJA_FIRST_CHILD?Variable not set}" volumes: - "vikunja_api_data:/app/vikunja/files" labels: - "traefik.enable=true" - "traefik.http.routers.vikunja_api.rule=Host(`${VIKUNJA_API_HOST?Variable not set}`) && PathPrefix(`/api/v1`, `/dav/`, `/.well-known/`)" - "traefik.http.routers.vikunja_api.service=vikunja_api" - "traefik.http.routers.vikunja_api.tls=true" - "traefik.http.routers.vikunja_api.entrypoints=web_secure" - "traefik.http.services.vikunja_api.loadbalancer.server.port=${VIKUNJA_API_PORT?Variable not set}" ``` How should i face this problem and proceed with the deployment? Thank you in advance.
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

Are you sure this is a vikunja specific problem and not one of docker compose?

Does it work if you run the container manually with the docker command?

<!-- gh-comment-id:1063247545 --> @kolaente commented on GitHub (Mar 9, 2022): Are you sure this is a vikunja specific problem and not one of docker compose? Does it work if you run the container manually with the docker command?
Author
Owner

@xrhstosmour commented on GitHub (Mar 9, 2022):

Just tested it, using the same PostgreSQL database, which works for all the other containers i use.
I forgot to say that i use a different port for the database which is exposed at the postgresql service at the docker-compose.yml as follows:

ports:
  - "${POSTGRESQL_PORT?Variable not set}:${POSTGRESQL_PORT?Variable not set}"
expose:
  - "${POSTGRESQL_PORT?Variable not set}"
command: "-p ${POSTGRESQL_PORT?Variable not set}"

and provide it to the vikunja service at the docker-compose.yml, at the VIKUNJA_DATABASE_HOST environment variable as i described before:

  environment:
    - "VIKUNJA_DATABASE_HOST=${POSTGRESQL_SERVER?Variable not set}:${POSTGRESQL_PORT?Variable not set}"

Furthermore i got again the same error, when doing what you suggested, as you can see below:

image

The config.yml file i used has the below format:

database:
  type: "postgres"
  # The database existed vikunja user
  user: "my_database_user"
  # Database password containing the described special characters.
  password: "my_not_escaped_password_containing_#$!@"
  # Database host
  host: "PostgreSQL_IP:PostgreSQL_Port_Not_5432"
  # Database to use
  database: "my_database"

If i try to connect via pgAdmin to the above database, using the config.yml credentials without escaping anything, the connection succeeds.
What am i doing wrong?

<!-- gh-comment-id:1063323206 --> @xrhstosmour commented on GitHub (Mar 9, 2022): Just tested it, using the same PostgreSQL database, which works for all the other containers i use. I forgot to say that i use a different port for the database which is exposed at the postgresql service at the docker-compose.yml as follows: ``` yml ports: - "${POSTGRESQL_PORT?Variable not set}:${POSTGRESQL_PORT?Variable not set}" expose: - "${POSTGRESQL_PORT?Variable not set}" command: "-p ${POSTGRESQL_PORT?Variable not set}" ``` and provide it to the vikunja service at the docker-compose.yml, at the VIKUNJA_DATABASE_HOST environment variable as i described before: ``` yml environment: - "VIKUNJA_DATABASE_HOST=${POSTGRESQL_SERVER?Variable not set}:${POSTGRESQL_PORT?Variable not set}" ``` Furthermore i got again the same error, when doing what you suggested, as you can see below: ![image](https://user-images.githubusercontent.com/47348646/157524787-dfa75b3e-0bbe-4f26-9b5b-be63bcc6fdf6.png) The config.yml file i used has the below format: ``` yml database: type: "postgres" # The database existed vikunja user user: "my_database_user" # Database password containing the described special characters. password: "my_not_escaped_password_containing_#$!@" # Database host host: "PostgreSQL_IP:PostgreSQL_Port_Not_5432" # Database to use database: "my_database" ``` If i try to connect via pgAdmin to the above database, using the config.yml credentials without escaping anything, the connection succeeds. What am i doing wrong?
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

Can you check with the postgres container if there's an error about a failed password attempt? I think you won't be able to reach the postgres container in your test with docker run since the two containers are not on the same network and the api container won't be able to reach any ports on exposed to the host by default.

I tried reproducing your problem with this compose file:

version: '3'

services:
  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: 'passwordwith#$!@test'
      POSTGRES_USER: vikunja
    volumes:
      - ./db:/var/lib/postgresql/data
    restart: unless-stopped
  api:
    image: vikunja/api
    environment:
      VIKUNJA_DATABASE_HOST: db
      VIKUNJA_DATABASE_PASSWORD: 'passwordwith#$!@test'
      VIKUNJA_DATABASE_TYPE: postgres
      VIKUNJA_DATABASE_USER: vikunja
      VIKUNJA_DATABASE_DATABASE: vikunja
    ports:
      - 3456:3456
    depends_on:
      - db
    restart: unless-stopped

but it failed to start with the error Invalid interpolation format for "environment" option in service "db": "passwordwith#$!@test" - I think docker compose's yaml parser is to blame here. I then moved the password to a .env file and it didn't work either. I don't know if the password it ended up setting in the db was the one I provided in the .env file though, probably not.

May I ask what your attack vector is here for using special characters in a db password? I think you could easily use a very long password (200+ characters) instead and be as secure, especially if you have your network properly secured so nobody can access it from the outside of your server.

<!-- gh-comment-id:1063334581 --> @kolaente commented on GitHub (Mar 9, 2022): Can you check with the postgres container if there's an error about a failed password attempt? I think you won't be able to reach the postgres container in your test with `docker run` since the two containers are not on the same network and the api container won't be able to reach any ports on exposed to the host by default. I tried reproducing your problem with this compose file: ```yaml version: '3' services: db: image: postgres:13 environment: POSTGRES_PASSWORD: 'passwordwith#$!@test' POSTGRES_USER: vikunja volumes: - ./db:/var/lib/postgresql/data restart: unless-stopped api: image: vikunja/api environment: VIKUNJA_DATABASE_HOST: db VIKUNJA_DATABASE_PASSWORD: 'passwordwith#$!@test' VIKUNJA_DATABASE_TYPE: postgres VIKUNJA_DATABASE_USER: vikunja VIKUNJA_DATABASE_DATABASE: vikunja ports: - 3456:3456 depends_on: - db restart: unless-stopped ``` but it failed to start with the error `Invalid interpolation format for "environment" option in service "db": "passwordwith#$!@test"` - I think docker compose's yaml parser is to blame here. I then moved the password to a .env file and it didn't work either. I don't know if the password it ended up setting in the db was the one I provided in the .env file though, probably not. May I ask what your attack vector is here for using special characters in a db password? I think you could easily use a very long password (200+ characters) instead and be as secure, especially if you have your network properly secured so nobody can access it from the outside of your server.
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

Ah can you make sure the password you configured in Vikunja's config works? With the psql cli tool?

<!-- gh-comment-id:1063335305 --> @kolaente commented on GitHub (Mar 9, 2022): Ah can you make sure the password you configured in Vikunja's config works? With the `psql` cli tool?
Author
Owner

@xrhstosmour commented on GitHub (Mar 9, 2022):

Yeap there is an error about failed password:

image

I made sure to use the appropriate network for the connection between the containers.
I pass the password through a .env file too like so:

# Vikunja's docker environment configuration.
VIKUNJA_API_HOST="my_vikunja_host"
VIKUNJA_API_PORT=1234
VIKUNJA_API_ENABLE_REGISTRATION=False
VIKUNJA_DATABASE_TYPE="postgres"
VIKUNJA_DATABASE="my_vikunja_database"
VIKUNJA_DATABASE_USER="my_vikunja_user"
VIKUNJA_DATABASE_PASSWORD='#AP@$$wordToUse!1234' #Also tried with double quotes.
VIKUNJA_DATABASE_ESCAPED_PASSWORD='The_Above_Password_Escaped_For_Testing_If_It_Works'
VIKUNJA_FIRST_CHILD=True

As for the reason i use special characters is because i am a maniac 🤣and this image:

image

As for the psql cli tool, i can't test it, but it says:

image

which is what exactly have tried through the docker-compose.yml .env and nothing worked.

<!-- gh-comment-id:1063356782 --> @xrhstosmour commented on GitHub (Mar 9, 2022): Yeap there is an error about failed password: ![image](https://user-images.githubusercontent.com/47348646/157530987-ac7d3167-530d-4735-a5b1-99e8af905f9d.png) I made sure to use the appropriate network for the connection between the containers. I pass the password through a .env file too like so: ``` .env # Vikunja's docker environment configuration. VIKUNJA_API_HOST="my_vikunja_host" VIKUNJA_API_PORT=1234 VIKUNJA_API_ENABLE_REGISTRATION=False VIKUNJA_DATABASE_TYPE="postgres" VIKUNJA_DATABASE="my_vikunja_database" VIKUNJA_DATABASE_USER="my_vikunja_user" VIKUNJA_DATABASE_PASSWORD='#AP@$$wordToUse!1234' #Also tried with double quotes. VIKUNJA_DATABASE_ESCAPED_PASSWORD='The_Above_Password_Escaped_For_Testing_If_It_Works' VIKUNJA_FIRST_CHILD=True ``` As for the reason i use special characters is because i am a maniac 🤣and this image: ![image](https://user-images.githubusercontent.com/47348646/157531964-7783e0bc-9286-4c31-bb40-efa267802756.png) As for the `psql` cli tool, i can't test it, but it says: ![image](https://user-images.githubusercontent.com/47348646/157532944-e63503fe-aa31-4092-b77c-59079aa40415.png) which is what exactly have tried through the docker-compose.yml .env and nothing worked.
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

As for the reason i use special characters is because i am a maniac rofland this image:

Nice image :) I doubt is will make a difference in practice whether it takes 23qd years or 1qt years to crack a password for a local Vikunja database. Again, if you secured your network properly that means someone who will make this much effort to get your Vikunja tasks probably sits on your pc already and knows everything about you. If I were targeted by someone with this much resources I doubt there's a lot I can do to protect myself. Other than turning everything off and moving to the woods of course.

I'm going to be a bit rude here and will close this issue as it does not seem to be related to a Problem in Vikunja. You might want to move this problem to the docker-compose or postgres projects.

Feel free to ping though if you have other issues or find a solution 👋

<!-- gh-comment-id:1063373148 --> @kolaente commented on GitHub (Mar 9, 2022): > As for the reason i use special characters is because i am a maniac rofland this image: Nice image :) I doubt is will make a difference in practice whether it takes 23qd years or 1qt years to crack a password for a local Vikunja database. Again, if you secured your network properly that means someone who will make this much effort to get your Vikunja tasks probably sits on your pc already and knows everything about you. If I were targeted by someone with this much resources I doubt there's a lot I can do to protect myself. Other than turning everything off and moving to the woods of course. I'm going to be a bit rude here and will close this issue as it does not seem to be related to a Problem in Vikunja. You might want to move this problem to the docker-compose or postgres projects. Feel free to ping though if you have other issues or find a solution :wave:
Author
Owner

@xrhstosmour commented on GitHub (Mar 9, 2022):

As i said maniac 🤣.

As for the issue i will look to it some more, as i think it has to do with the way the PostgreSQL URI being used at the backend of the Vikunja application, because the same special character password strategy is being used to all the other containers i use, for instance pgAdmin, Joplin and VaultWarden (which says it needs the password encoded) and every one of them worked like charm, at the same docker-compose.yml.

So yes it's a bit rude, but i understand.

Goodbye.

<!-- gh-comment-id:1063387249 --> @xrhstosmour commented on GitHub (Mar 9, 2022): As i said maniac 🤣. As for the issue i will look to it some more, as i think it has to do with the way the PostgreSQL URI being used at the backend of the Vikunja application, because the same special character password strategy is being used to all the other containers i use, for instance pgAdmin, Joplin and VaultWarden (which says it needs the password encoded) and every one of them worked like charm, at the same docker-compose.yml. So yes it's a bit rude, but i understand. Goodbye.
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

Please keep me posted if you find anything!

<!-- gh-comment-id:1063392942 --> @kolaente commented on GitHub (Mar 9, 2022): Please keep me posted if you find anything!
Author
Owner

@xrhstosmour commented on GitHub (Mar 9, 2022):

That is the last comment i do, i promise!
Is there any case the the problem has to do with the url.PathEscape function here.

I have no experience with Go but when i tried to run what my .env should probably pass to the vikunja API, that is what it came back:

image

As you can see characters @ and $ are not escaped and if i escape them manually by changing them to %40 and %24 accordingly at the .env file, then the function escapes the %, messing up the connection string more.

<!-- gh-comment-id:1063430858 --> @xrhstosmour commented on GitHub (Mar 9, 2022): That is the last comment i do, i promise! Is there any case the the problem has to do with the url.PathEscape function [here](https://github.com/go-vikunja/api/blob/86b7d224aba34d3a731e098f02db1568074c953c/pkg/db/db.go#L157). I have no experience with Go but when i tried to run what my .env should probably pass to the vikunja API, that is what it came back: ![image](https://user-images.githubusercontent.com/47348646/157545103-c74a7a91-88ee-435b-b373-c85c4afb28a1.png) As you can see characters `@` and `$` are not escaped and if i escape them manually by changing them to `%40` and `%24` accordingly at the .env file, then the function escapes the `%`, messing up the connection string more.
Author
Owner

@kolaente commented on GitHub (Mar 9, 2022):

Very interesting, that's probably the cause here. I'm not sure how to fix this though. One way would be to remove the call to url.PathEscape but I don't think that'd be a good way to fix this since we'd loose the escaping. I don't remember exactly why I put it in there in the first place though so maybe we're safe to remove it. Reopening this issue though since it does seem to be a problem in Vikunja.

How do others solve it?

<!-- gh-comment-id:1063438928 --> @kolaente commented on GitHub (Mar 9, 2022): Very interesting, that's probably the cause here. I'm not sure how to fix this though. One way would be to remove the call to `url.PathEscape` but I don't think that'd be a good way to fix this since we'd loose the escaping. I don't remember exactly why I put it in there in the first place though so maybe we're safe to remove it. Reopening this issue though since it does seem to be a problem in Vikunja. How do others solve it?
Author
Owner

@xrhstosmour commented on GitHub (Mar 9, 2022):

Again I am not sure if that is the real case, because both escaping and encoding should cooperate with the PostgreSQL engine you use for the connection, so as to keep the password the same both when receiving and when authenticating.

I am not sure what is the right solution without breaking any other part of the code, maybe trying to use some Encode function that Go might have.

Some containers I use, I think they encode/escape all the characters.

On the other hand VaultWarden, let the user percentage encode the password, if there are any special characters in, details can be found here.

Again, just to be clear all of the above are guesses, I just really like the interface (a dark theme also would be nice 😂) and the concept of Vikunja (also I love Dart/Flutter), so I wanted to try it, in a home server project.

<!-- gh-comment-id:1063452258 --> @xrhstosmour commented on GitHub (Mar 9, 2022): Again I am not sure if that is the real case, because both escaping and encoding should cooperate with the PostgreSQL engine you use for the connection, so as to keep the password the same both when receiving and when authenticating. I am not sure what is the right solution without breaking any other part of the code, maybe trying to use some Encode function that Go might have. Some containers I use, I think they encode/escape all the characters. On the other hand VaultWarden, let the user percentage encode the password, if there are any special characters in, details can be found [here](https://github.com/dani-garcia/vaultwarden/wiki/Using-the-PostgreSQL-Backend). Again, just to be clear all of the above are guesses, I just really like the interface (a dark theme also would be nice 😂) and the concept of Vikunja (also I love Dart/Flutter), so I wanted to try it, in a home server project.
Author
Owner

@AmitPr commented on GitHub (Mar 20, 2022):

Can confirm that I wasn't able to connect to postgres when my user password had special characters, but when I changed the password to only contain alphanumeric characters everything worked as expected. Seems like an issue within vikunja or one of the libraries it's pulling from.

<!-- gh-comment-id:1073290896 --> @AmitPr commented on GitHub (Mar 20, 2022): Can confirm that I wasn't able to connect to postgres when my user password had special characters, but when I changed the password to only contain alphanumeric characters everything worked as expected. Seems like an issue within vikunja or one of the libraries it's pulling from.
Author
Owner

@kolaente commented on GitHub (Jul 7, 2022):

I did some more digging and it looks like this works without issues when I remove the escaping all together. I went ahead and did just that in 230478aae9. My guess is the db driver will also escape the passwords implicitly and would therefore double-escape everything with the escaping in Vikunja as well.

<!-- gh-comment-id:1177858419 --> @kolaente commented on GitHub (Jul 7, 2022): I did some more digging and it looks like this works without issues when I remove the escaping all together. I went ahead and did just that in 230478aae947c86f4c6f1f251dcb30aeb1293283. My guess is the db driver will also escape the passwords implicitly and would therefore double-escape everything with the escaping in Vikunja as well.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vikunja#5832