mirror of
https://github.com/photoprism/photoprism.git
synced 2026-03-02 22:57:18 -05:00
Security: Log User Login / Logout #739
Labels
No labels
ai
android
api
auth
awesome
bug
bug
ci
cli
config
database
declined
deprecated
docker
docs 📚
documents
duplicate
easy
enhancement
enhancement
enhancement
epic
faces
feedback wanted
frontend
hacktoberfest
help wanted
idea
in-progress
incomplete
index
invalid
ios
labels
live
live
low-priority
macos
member-feature
metadata
mobile
nas
needs-analysis
no-coding-required
no-coding-required
observability
performance
places
please-test
plus-feature
priority
pro-feature
question
raspberry-pi
raw
released
released
released
research
resolved
security
sharing
tested
tests
third-party-issue
thumbnails
upgrade
upstream-issue
ux
vector
video
waiting
won't fix
won't fix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/photoprism#739
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @y0grt on GitHub (Jan 23, 2021).
Originally assigned to: @lastzero on GitHub.
Include this information in log output in order to block IPs with too many attemps.
This can be implemented in Photoprism itself, but simply with this information in the log output existing solutions like fail2ban can be used for this purpose.
@lastzero commented on GitHub (Jan 23, 2021):
Did you try a brute force attack?
@y0grt commented on GitHub (Jan 23, 2021):
Not a proper one.
Simply tried like 10 times with wrong credentials and debug enabled, but couldn't see anything on the log output.
I couldn't find any information either.
@lastzero commented on GitHub (Jan 23, 2021):
How long did you have to wait for each attempt?
@y0grt commented on GitHub (Jan 23, 2021):
I've realised about the throttling on the login process, it's a mitigation indeed.
But would be great to be able to provide a more fine grain control, like to be able to trigger a full IP block through iptables rules.
I discovered as well that the username can be easily guessed since an existing username triggers an instant fail (400 from /api/v1/session).
@lastzero commented on GitHub (Jan 23, 2021):
Well, there's only one user right now - so that'd be easy to guess anyway. Logging logins is OK if not all users can see this as it also leaks information. Brute force should not be an issue with each attempt getting slower.
@pjft commented on GitHub (Jun 14, 2021):
Came here to ask about the same. Certainly throttling is useful, but given that we're exposing this to the outside world, I'd be more confident monitoring attempts and being able to jail those IPs. Not to mention that given that the username is hardcoded to "admin", they only have to guess a password.
@lastzero commented on GitHub (Jun 14, 2021):
Try guessing the password and see what happens 🌼
@lastzero commented on GitHub (Jul 22, 2021):
Took a look at this issue again due to popular demand:
users.login_attemptscolumn, you'll also find alogin_attimestamp in theuserstable which shows when the last successful login was.POST /api/v1/sessionAPI endpoint for error 400 responses as then block the source IP. No need to reinvent the wheel.@pjft commented on GitHub (Jul 22, 2021):
Thanks.
I don't think it's an emergency at all. It's important, not urgent.
As far as the reverse proxy suggestion goes, may that's an option, but as an individual user I don't think I have a reverse proxy set up.
I run things from a Raspberry Pi, and use fail2ban to block login attempts to the only services that are exposed externally. I genuinely don't know what other users use or not and their network configuration, but fail2ban seems to be the normally-recommended IP/login blocking tool for anything from SSH, OpenVPN, Nextcloud and other services I run on Linux, docker or not. It monitors a logfile and creates a jail for specific IPs - many in syslog, others in other app-specific log files.
I don't know what others use, so maybe I'm in the minority here. I see @jmlgo seems to run a similar setup.
But, as I said, I personally don't think it's an emergency. I appreciate the flexibility and openness in exposing the multiple scenarios, and I understand the challenge of leaking the IPs in the demo environment.
I don't know where the actual logfile is stored right now, for me to even explore options there - is it all stored in MariaDB?
Thanks.
@lastzero commented on GitHub (Jul 22, 2021):
The logs are sent to Docker (run
docker-compose logs --tail=25 -fto see them) as well as browsers via websocket if PhotoPrism is running in public mode or users are authenticated. As explained above, there isn't a separate log for each user or browser at the moment.If you don't (want to) use Docker, you may send logs to a file using the config option
PHOTOPRISM_LOG_FILENAME, see https://docs.photoprism.org/getting-started/config-options/.Note that there should always be an HTTPS reverse proxy in place when using PhotoPrism outside a secure network, so that your password and files won't be sent in plain text over the public internet. That's a huge security issue in itself. Otherwise you also have to use a separate port for each app, which is a major inconvenience.
@lastzero commented on GitHub (Jul 22, 2021):
In a future release, we may implement a separate security log (file) for messages that shouldn't go to the regular logs. Ideally in a standard format consumable by tools like "fail2ban". You're welcome to share specific requirements for this.
@pjft commented on GitHub (Jul 22, 2021):
Thank you for the explanation. I am using docker, this helps.
I'll try to look into setting up some sort of reverse proxy - hadn't considered the http/https issue, but it's a completely fair remark. I will look into setting it up there, as I have nginx running locally.
I don't have any specific suggestion for the log format. Usually it's something that has the date/time, type of log, description text, user and source. Something like:
2021-07-17 02:58:15 WARNING (photoprism) Login attempt or request with invalid authentication from 192.168.86.14 for user 'admin'.
could probably work - fail2ban uses regexp, so I'm sure it'd just be a matter of figuring the right one out.
Thank you, and keep up the great work.
@pjft commented on GitHub (Jul 26, 2021):
@lastzero Apologies, just came here to thank you for the reverse proxy tip. It had been quite understated when reading the documentation, but indeed - especially after you spelled out the challenge with http - it made perfect sense.
I already had existing certificates and nginx running, so it was just a matter of setting it up appropriately to use the certificates. Took me 30 mins or so on Saturday, without having ever done so in the past, and even though the HTTP to HTTPS redirect isn't quite working, at least it no longer works on HTTP and I just need to access HTTPS explicitly, which is completely fine for me.
Thank you!
For anyone who needs guidance setting up HTTPS, this reddit thread was helpful, and I imagine that if you don't have a certificate, then this might help (untested).
@F1orian commented on GitHub (Aug 23, 2022):
For anyone interested: I got fail2ban to work with PhotoPrism by directing it at the nginx access.log of my reverse proxy.
I'm using the following filter in fail2ban:
@thelpfy commented on GitHub (Sep 6, 2023):
With the latest docker image and swag i got it to work with:
So i had to change the response code to 401 and swap "auth" with "library"
@pjft commented on GitHub (Sep 7, 2023):
Thank you @TheLPfy ! Works great.
@klack commented on GitHub (Aug 2, 2024):
Here is what I ended up using with the Traefik access log for all 400 errors
@jbouwens commented on GitHub (Apr 17, 2025):
PhotoPrism users who use Caddy 2 can add logging to Caddyfile config:
Then for the filter, photoprism-auth.conf: