{"id":13721554,"url":"https://github.com/lixmal/keepass4web","last_synced_at":"2025-05-07T13:33:22.974Z","repository":{"id":7125827,"uuid":"54359574","full_name":"lixmal/keepass4web","owner":"lixmal","description":"[deprecated] KeePass databases served on the web","archived":true,"fork":false,"pushed_at":"2023-10-27T13:38:46.000Z","size":1731,"stargazers_count":161,"open_issues_count":13,"forks_count":20,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-08-23T20:16:39.786Z","etag":null,"topics":["crypto","dropbox","javascript","keepass","keepass4web","ldap","password","password-manager","perl","seafile","web"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lixmal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-03-21T04:19:44.000Z","updated_at":"2024-07-06T18:18:10.000Z","dependencies_parsed_at":"2024-01-10T21:01:04.373Z","dependency_job_id":"5395097e-1df4-4195-a023-63848863da48","html_url":"https://github.com/lixmal/keepass4web","commit_stats":{"total_commits":197,"total_committers":3,"mean_commits":65.66666666666667,"dds":"0.060913705583756306","last_synced_commit":"e5e08f1e68ea7abe84cd14c4d1b7f9ce1dffd611"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixmal%2Fkeepass4web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixmal%2Fkeepass4web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixmal%2Fkeepass4web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lixmal%2Fkeepass4web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lixmal","download_url":"https://codeload.github.com/lixmal/keepass4web/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224605033,"owners_count":17339249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto","dropbox","javascript","keepass","keepass4web","ldap","password","password-manager","perl","seafile","web"],"created_at":"2024-08-03T01:01:18.524Z","updated_at":"2024-11-14T10:31:45.133Z","avatar_url":"https://github.com/lixmal.png","language":"Perl","readme":"# ⚠ [DEPRECATED]\n\n*This repo is not maintained anymore.*\n\n**Please see the (not yet feature-complete) [rewrite in Rust](https://github.com/lixmal/keepass4web-rs).\nThe rewrite has better security and supports kdbx4 databases.**\n\n\n#\n#\n#\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [KeePass4Web](#keepass4web)\n  - [FEATURES](#features)\n  - [INSTALL](#install)\n  - [BUILD FRONTEND](#build-frontend)\n  - [MODULE INSTALLATION](#module-installation)\n  - [CONFIGURATION](#configuration)\n  - [DEPLOYMENT](#deployment)\n    - [Container](#container)\n    - [Classic](#classic)\n        - [Running apache2 using mod_perl2/Plack with TLS:](#running-apache2-using-mod_perl2plack-with-tls)\n        - [Using the standalone server](#using-the-standalone-server)\n        - [Open `https://\u003cdomain\u003e/keepass/` (notice the trailing slash)](#open-httpsdomainkeepass-notice-the-trailing-slash)\n        - [Refer to Dancer2::Manual::Deployment for more options.](#refer-to-dancer2manualdeployment-for-more-options)\n  - [BUNDLING](#bundling)\n  - [BACKENDS](#backends)\n    - [Authentication](#authentication)\n        - [LDAP](#ldap)\n        - [Htpasswd](#htpasswd)\n        - [PAM (planned)](#pam-planned)\n        - [SQL (planned)](#sql-planned)\n    - [Database](#database)\n        - [Filesystem](#filesystem)\n        - [Seafile](#seafile)\n        - [LWP](#lwp)\n        - [Dropbox](#dropbox)\n        - [WebDAV (planned)](#webdav-planned)\n  - [MISCELLANEOUS](#miscellaneous)\n  - [LIMITATIONS](#limitations)\n  - [BUGS / CAVEATS / TODO](#bugs--caveats--todo)\n  - [APP DETAILS / BACKGROUND](#app-details--background)\n    - [Sequence of client/server operations](#sequence-of-clientserver-operations)\n    - [Packages used](#packages-used)\n        - [Libraries / Packages](#libraries--packages)\n        - [Perl modules](#perl-modules)\n          - [Core](#core)\n          - [Backend LDAP](#backend-ldap)\n          - [Backend Htpasswd](#backend-htpasswd)\n          - [Backend Seafile](#backend-seafile)\n          - [Backend LWP](#backend-lwp)\n          - [Backend Dropbox](#backend-dropbox)\n          - [Bundled modules, may become external](#bundled-modules-may-become-external)\n  - [COPYRIGHT AND LICENSING](#copyright-and-licensing)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# KeePass4Web\n\nA mobile-friendly web application which serves KeePass database entries on a web frontend.\n\nWritten in Perl and JavaScript.\n\n\n## FEATURES\n\n- Users need to authenticate with one of the auth backends (LDAP, Htpasswd, SQL, ...) before they can open a database\n- Server can fetch databases from various locations (Filesystem, Seafile, Dropbox, ...)\n- Either all users get access to the same database or each user gets access to his/her own\n- Doesn't save master password, uses a new and unique encryption key to cache the database\n- Caches encrypted databases in shared memory (so it works with multiple web server workers)\n- Encryption key is stored in the kernel keyring and therefore doesn't swap to disk\n- Passwords, protected fields and files are encrypted separately (also the ones in history). The web server only decrypts requested information. This way other passwords don't stay in memory in plain text and don't leave the server\n- Server revokes encryption keys after a configurable user idle time, effectively removing access to the cached database\n- Web interface offers entry search and access to files stored inside the database. Also displays custom entry icons\n- Highly configurable\n\n\n![Login](doc/img/login.png)\n\n![App](doc/img/app.png)\n\n\n## INSTALL\n\n- From container image:\nSee [DEPLOYMENT](#deployment)\n\n- From source:\n    - Clone the repo to some dir\n        \u003e git clone https://github.com/lixmal/keepass4web.git\n\n        \u003e cd keepass4web\n\n    - Follow [BUILD FRONTEND](#build-frontend), [MODULE INSTALLATION](#module-installation), [CONFIGURATION](#configuration), [DEPLOYMENT](#deployment) in that order\n\n\n## BUILD FRONTEND\n\nThe minified, bundled file will be written to public/scripts/bundle.js\n\n- Install Node/npm, e.g. for Ubuntu\n    \u003e sudo apt-get install npm\n\n- Install js modules\n    \u003e npm install\n\n- Copy bootstrap font files\n    \u003e cp node_modules/bootstrap/fonts/* public/fonts/\n\n- Build js bundle\n    \u003e npm run build\n\n- For a non-uglified version you can run\n    \u003e npm run dev\n\n## MODULE INSTALLATION\n\nE.g. for Ubuntu 22.04 with mod_perl2:\n\n- Install distro packages\n    \u003e sudo apt-get install build-essential libkeyutils-dev libkeyutils1 libmagic1 libmagic-dev libapache2-mod-perl2 cpanminus\n\n- Install dependencies with all backends, the recommended modules (for performance) and the suggested session engine (`Cookie`)\n    \u003e cpanm --sudo --installdeps . --with-all-features --with-recommends --with-suggests\n\n- Alternatively, install dependencies with selected backends only\n    \u003e cpanm --sudo --installdeps . --with-feature Dropbox --with-feature LDAP --with-recommends\n\n\n## CONFIGURATION\n\n- Copy or rename `config.yml` to `config_local.yml`\n    \u003e cp config.yml config_local.yml\n\n- Make changes in `config_local.yml`. Settings in `config_local.yml` override those in `config.yml`\n\n- Change `session_cookie_key` to a **long** and **random** value if using `Cookie` in `session`, e.g.\n    \u003e pwgen -ysN1 128\n\n\n## DEPLOYMENT\n\n### Container\n\nSee [GitHub Packages](https://ghcr.io/lixmal/keepass4web)\n\nThe image ships with the default config in `/conf/config.yml`, which should be overwritten with a mount/volume.\n\nThe app makes use of the [Linux kernel keyring](https://man7.org/linux/man-pages/man7/keyrings.7.html).\n\nThe keyring is currently not namespaced, hence container tooling deactivate the specific syscalls by default.\nTo make the app run you will need to activate the syscalls by creating a custom seccomp profile and passing the path to the container runtime:\n\n- [Docker](https://docs.docker.com/engine/security/seccomp/)\n- [podman](https://docs.podman.io/en/v4.6.0/markdown/options/seccomp-policy.html)\n\nA base file for extension can be found [here](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json), see the `syscalls` section.\n\nThe required syscalls are:\n\n- keyctl\n- add_key\n- request_key\n\n\n**Make sure no other containers are running under the same user, or they will be able to access keys stored for keepass4web**.\n\nThis is best achieved by running rootless containers with a dedicated user for keepass4web.\n\n- [Docker](https://docs.docker.com/engine/security/rootless/)\n- [podman](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md)\n\n\n### Classic\n\nRunning this app on a web server with mod_perl2 or fcgi is **recommended** but running as standalone app is possible as well (with Dancer2's capabilities).\n\n- Create the log directory (as defined in `config_local.yml`)\n    \u003e sudo mkdir /var/log/keepass4web/\n\n- The directory the app lives in has to be readable by the user running the web server, e.g.\n    \u003e sudo chown -R root:www-data /opt/keepass4web/ /var/log/keepass4web/\n\n    \u003e chmod g+r -R /opt/keepass4web/\n\n- Addtionally, it needs write permissions on the log directory, e.g.\n    \u003e chmod g+w /var/log/keepass4web/\n\n- Remove permissions on sensitive data for everyone else\n    \u003e chmod o= /opt/keepass4web/config*.yml /var/log/keepass4web/\n\n- For apache, enable the perl mod and ssl\n    \u003e sudo a2enmod perl\n\n    \u003e sudo a2enmod ssl\n\n    \u003e sudo a2ensite default-ssl\n\n\n##### Running apache2 using mod_perl2/Plack with TLS:\n\nExample config default-ssl:\n\n```apache\nPerlSwitches -I/opt/keepass4web/lib/\nPerlModule KeePass4Web::Apache2\nPerlPostConfigHandler KeePass4Web::Apache2::post_config\n\n\u003cIfModule mod_ssl.c\u003e\n    \u003cVirtualHost _default_:443\u003e\n    ServerName example.org\n\n    SSLEngine on\n    SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem\n    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\n    PerlOptions +Parent\n    \u003cLocation /keepass/\u003e\n        SetHandler perl-script\n        PerlResponseHandler Plack::Handler::Apache2\n        PerlSetVar psgi_app /opt/keepass4web/bin/app.psgi\n    \u003c/Location\u003e\n\n\n    \u003c/VirtualHost\u003e\n\u003c/IfModule\u003e\n```\n\n##### Using the standalone server\n\n- Run (as correct user)\n    \u003e plackup bin/app.psgi --port 8080 --host localhost\n\n- Or\n    \u003e DANCER_PORT=8080 DANCER_SERVER=localhost bin/app.psgi\n\n- Options for plackup can be found in `man plackup` or [online](https://metacpan.org/pod/distribution/Plack/script/plackup)\n\n- As there is no TLS, it is recommonded to run a front-end web server with reverse proxy, example config for apache:\n    ```apache\n    \u003cIfModule mod_ssl.c\u003e\n        \u003cVirtualHost _default_:443\u003e\n        ServerName example.org\n\n        SSLEngine on\n        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem\n        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\n        ProxyPass        /keepass/ http://localhost:8080/\n        ProxyPassReverse /keepass/ http://localhost:8080/\n\n\n        \u003c/VirtualHost\u003e\n    \u003c/IfModule\u003e\n    ```\n\n##### Open `https://\u003cdomain\u003e/keepass/` (notice the trailing slash)\n\n##### Refer to [Dancer2::Manual::Deployment](https://metacpan.org/pod/Dancer2::Manual::Deployment) for more options.\n\n## BUNDLING\n\nOutput will be a `KeePass4Web-{VERSION}.tar.gz` file, which includes all files required to run the app but without the development/build files\n\n- Follow `BUILDING` first, then run the perl make file\n    \u003e perl Makefile.PL\n\n- Bundle the app to a tar\n    \u003e make dist\n\n- Clean up afterwards\n    \u003e make clean\n\n\n\n## BACKENDS\n\n### Authentication\n\nCredentials may be further passed to the database backend via `auth_reuse_cred` config option.\nThis way users don't have to enter their credentials twice (for auth backend and database backend) if they are identical.\nUseful when the database backend server uses the same auth backend internally.\n\n##### LDAP\n\nAttempts to authenticate the user against an (external, not built-in) LDAP server (Microsoft AD, 389 Directory Server, OpenLDAP, ...)\n\n##### Htpasswd\n\nAuthentication using apache htpasswd files.\nSupport for plain, sha1, crypt, md5 and bcrypt. Only bcrypt is considered secure.\n\n##### PAM (planned)\n\n##### SQL (planned)\n\n### Database\n\n##### Filesystem\n\nGrabs the KeePass database from the local filesystem. No support for local key files if configured statically (in `config_local.yml`).\nCan get database and key file location from auth backend.\nWeb server needs read access to the files.\n\n##### Seafile\n\nKeePass database is stored in the private cloud.\n\nLocations for the database and the key file can be configured in `config_local.yml` (global for all users) or fetched from auth backend (individually per user).\nLocation syntax is '\\\u003crepository-id\u003e/\\\u003cpath-to-database\u003e', see `config_local.yml` for an example.\n\nThe server uses the (possibly auth backend) credentials to fetch a token from Seafile which is used for consequent requests.\nNo user credentials are saved anywhere at any time!\n\nRight now the server does all Seafile requests. It is planned to migrate to a model where the client fetches the token from the Seafile server (if on the same domain) and passes it to the app server.\nLogging into some service on behalf of the user is an anti-pattern, therefore it is not recommended for non private servers.\n\n##### LWP\n\nBackend to fetch database from http, ftp or any other protocol supported by the LWP module collection (see [LWP NETWORK SUPPORT](http://search.cpan.org/dist/libwww-perl/lib/LWP.pm#NETWORK_SUPPORT)).\nAdditional protocols can be added by installing corresponding modules (see [LWP::Protocol modules](https://metacpan.org/search?p=1\u0026q=LWP%3A%3AProtocol%3A%3A\u0026search_type=modules\u0026size=30)).\nSupports per-user database and key file location from auth backend. No support for key files if configured statically (in `config_local.yml`).\nBasic auth is supported for http, but only globally (same for all users, even if urls differ). Otherwise it would be necessary to store the user credentials in the session, which might be not a good idea.\nDatabase upload (saving) is only implemented for http right now.\n\nUsername and password may also be supplied in the form of `ftp://username:password@example.org/db.kdbx`\n\n##### Dropbox\n\nFirst you need to register the app with Dropbox: [Create App](https://www.dropbox.com/developers/apps/create).\nChoose the type of access you need, give it a name (e.g. `KeePass4Web`).\nAdd an redirect url pointing to you application, followed by `callback`, e.g. `https://example.org/keepass/callback`.\nOptionally, generate an access token.\nPutting the token into the config will limit all users to that one Dropbox account (unless they open the Dropbox link by themselves, for which they would need to know the app key).\nPut the displayed app key, the app secret and the redirect url into `config_local.yml`.\n\nNow, once users log into the web application, they will be redirected to the Dropbox login page (unless already logged in).\nAfter logging in and granting the app access to Dropbox, they will be redirected back to the app.\n\nThe backend also can fetch key files from Dropbox, if per-user databases are supported by the auth backend.\n\nFor the format to use in `config_local.yml`/`db_location` or the auth backend see the [Dropbox HTTP doc](https://www.dropbox.com/developers/documentation/http/documentation) under `Path formats` or [HTTP download](https://www.dropbox.com/developers/documentation/http/documentation#files-download) next to `Paramaters`\n\n##### WebDAV (planned)\n\n\n## MISCELLANEOUS\n\n- Show currently used shared segments\n    \u003e sudo ipcs\n\n- Removing segments (effectively closing user databases)\n    \u003e sudo ipcrm -M `key`\n\n- Show kernel keyrings in use (as root)\n    \u003e sudo cat /proc/keys\n\n    \u003e sudo cat /proc/key-users\n\n- Adding users to .htpasswd, using bcrypt (needs apache2-utils/httpd-tools)\n    \u003e touch .htpasswd               # create file\n\n    \u003e htpasswd -B .htpasswd \u003cusername\u003e\n\n    \u003e sudo chown root:www-data .htpasswd # change group\n\n    \u003e chmod g+r,o-rwx .htpasswd     # remove permission of others, add read to webserver user\n\n\n## LIMITATIONS\n\n- Doesn't support [kdbx 4](https://keepass.info/help/kb/kdbx_4.html) yet\n- KeePass databases are read-only for now\n- Caching of KeePass databases happens in SysV IPC shared memory, whose maximum size depends on the OS. Defined by `shmall` and `shmmni` kernel variables\n    \u003e sudo cat /proc/sys/kernel/shmmni\n\n    \u003e sudo cat /proc/sys/kernel/shmall\n- Limits of kernel keyring apply\n- Right now all cached databases are seralised and deserialised together. This means more *simultaneously active* users will make fetching databases from IPC slower for every user. A better approach would be using one shared segment per user, which would make one roundtrip perpetual\n\n\n## BUGS / CAVEATS / TODO\n\n- Using mod_perl, apache may create two kernel session keyrings, because it restarts directly after startup, effectively executing KeePass4Web::KeePass twice\n\n- Log may have 'Key has been revoked' messages: happens when session keyring gets revoked once user (who (re)started the server) logs out. Please file a bug report in this case.\n\n- More tests\n\n\n## APP DETAILS / BACKGROUND\n### Sequence of client/server operations\n\n```\nClient                                                       Server\n\n\nLoad website /\n                              request KeePass tree\n                              --------------------\u003e\n\n                                                        Check sesssion\n\n                              not authenticated\n                              \u003c--------------------\n\nRedirect to /user_login\nShow credentials dialog\n\n                              user credentials\n                              --------------------\u003e\n\n                                                        User auth (LDAP, SQL, ...)\n\n                                           login OK\n                              \u003c--------------------\n\nRedirect to /backend_login\nShow backend login dialog\n\n                              backend credentials\n                              --------------------\u003e\n\n                                                        Init DB backend / receive backend token\n                                           login OK\n                              \u003c--------------------\n\nRedirect to /db_login\nShow KeePass password dialog\n\n                              KeePass credentials\n                              --------------------\u003e\n                                                        Possibly decrypt backend repo\n                                                        Get KeePass database from backend\n                                                        Possibly get Key file from backend\n                                                        Decrypt KeePass database with master key + key file\n                                                        Encrypt all password fields\n                                                        Encrypt serialised string with newly generated key\n                                                        Put encryption key into kernel keyring\n                                                        Write keyring ids to session\n                                                        Put encrypted database into IPC shared memory\n                                      decryption OK\n                              \u003c--------------------\n\nRedirect to /\n                              request KeePass tree\n                              --------------------\u003e\n\n                                                        Get database from IPC shared memory\n                                                        Get encryption key from session\n                                                        Decrypt database with key\n\n                                  Send KeePass tree\n                              \u003c--------------------\nShow KeePass tree\n\n...\n\nPassword request by user\n                              Request pw entry\n                              --------------------\u003e\n\n                                                        Get keyring id from session\n                                                        Get encryption key from kernel keyring\n                                                        Get database from IPC shared memory\n                                                        Decrypt database\n                                                        Decrypt requested password\n\n                                  Send pw entry\n                              \u003c--------------------\nShow cleartext pw\n\n\n\n...\n\n\nPage reload\n\n                              Request KeePass tree\n                              --------------------\u003e\n                                                        Get database from IPC shared memory\n\n                                  Send KeePass tree\n                              \u003c--------------------\nShow KeePass tree\n\n```\n\n### Packages used\n\n##### Libraries / Packages\n\n- build-essential *(building XS modules)*\n- libkeyutils-dev\n- libkeyutils1\n- libapache2-mod-perl2 *(if running mod_perl2 with apache2)*\n- libmagic1\n- libmagic-dev\n- cpanminus *(module installation)*\n\n##### Perl modules\n\n###### Core\n- Kernel::Keyring\n- Dancer2\n- Dancer2::Plugin::Ajax\n- Dancer2::Session::Cookie *(default session engine, `Cookie` in config)*\n- IPC::ShareLite\n- File::KeePass\n- Crypt::URandom\n- File::LibMagic\n- Sereal::Encoder\n- Sereal::Decoder\n- Crypt::Mode::CBC\n- Crypt::Mac::HMAC\n- URI::Escape\n\n###### Backend LDAP\n- Net::LDAP\n\n###### Backend Htpasswd\n- Crypt::Eksblowfish::Bcrypt *(bcrypt)*\n- Authen::Htpasswd  *(md5, sha1, crypt, plain)*\n\n###### Backend Seafile\n- JSON\n- REST::Client\n- URI::Escape\n\n###### Backend LWP\n- LWP::UserAgent\n- HTTP::Request::Common\n- URI::Escape\n\n###### Backend Dropbox\n- WebService::Dropbox\n\n###### Bundled modules, may become external\n- File::KeePass::Web\n- Auth::LDAP\n- Seafile::Client::REST\n\n\n\n## COPYRIGHT AND LICENSING\n\nThis software is copyright (c) by Viktor Liu.\nIt is released under the terms of the GPL version 3.\n\nMost of the icons in the `public/img/icons` directory are released under the LGPL version 2, the licence can be found in the same directory.\nThe remaining icons are public domain.\nAs these icons are the same as the ones used by the original KeePass software, you can refer to the info there: [Icon Acknowledgements](http://keepass.info/help/base/credits.html#icons).\n\nThe Seafile logo is copyright (c) by Seafile Ltd.\n","funding_links":[],"categories":["Clients"],"sub_categories":["Web clients"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flixmal%2Fkeepass4web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flixmal%2Fkeepass4web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flixmal%2Fkeepass4web/lists"}