1
0
Fork 0
forked from 0x2E/fusion
Commit graph

30 commits

Author SHA1 Message Date
Yuan
e0938da00b
feat: redirect to the feed page after creation (#155) 2025-04-26 16:59:15 +08:00
Yuan
bc8109fe39
refactor: replace zap log with slog (#150)
* refactor: replace zap log with slog

* fix
2025-04-25 17:18:25 +08:00
Yuan
dd0d2e7d7d
feat: make the password optional (#128)
* feat: make the password optional

* fix: put the check outside HashPassword

* refactor: change PasswordHash to a pointer type for better checking
2025-04-05 20:14:31 +08:00
Michael Lynch
01cc024981 Fix a session checking bug
Resolves #53

This fixes a bug I accidentally introduced by misunderstanding the echo session package. I thought that calling session.Get would return an error if no session existed for the session token valule. It seems that instead, if a session doesn't exist, session.Get creates one on-demand.

To fix this, we have to check the IsNew field of the session to see if calling session.Get created this session on-demand or if this was a session that was previously created in the Create function.

I introduced this bug in #43.
2025-01-19 16:08:53 -05:00
Michael Lynch
bfd4e8c66b Check passwords based on hashes rather than plaintext
fusion's current password mechanism is vulnerable to a timing attack:

https://en.wikipedia.org/wiki/Timing_attack

Because fusion checks passwords using simple character-by-character string comparison, a password attempt that begins with the correct characters will take longer to evaluate than one that starts with incorrect characters. For example, if the correct password is 'platypus123' then a password attempt of 'plates' will take longer to evaluate than 'spoons' because 'plates' and 'platypus' share a common prefix. An attacker who attempts the password 'plates' will know that they likely have the correct prefix.

To prevent the timing attack, this change hashes the user's password using PBKDF2 and compares hashes using subtle.ConstantTimeCompare, which is specifically designed to prevent timing attacks.
2025-01-12 11:31:01 -05:00
Michael Lynch
5d9f8df0b7 Tell browser to delete invalid session tokens
Currently, if the user logs in to the server with the correct password, they get a cookie called session-token. If the server's password changes, the server (correctly) responds with an HTTP 401 Unauthorized when the user tries to use the token associated with the old password.

The problem is that the server's HTTP 401 response doesn't tell the client's browser to delete the old session token cookie, so it keeps sending it on every request even though the server knows it's bad.

Currently, it doesn't cause any noticeable problems, but I'm working on a change that will affect the data that we store in the session token, so it can lock the user out even if they have the same password because the password will be correct but they'll be using a session token that's invalid.
2025-01-10 20:44:54 -05:00
Michael Lynch
15caa9988b Get rid of global state for config 2025-01-04 20:00:25 -05:00
Michael Lynch
41784ec681 Make conf settings read-only
It feels a bit messy that the entire program has write access to the configuration as a shared global object. Shared globals make it more difficult to reason about a program's behavior.

This rewrite reduces the problem a bit by making the shared global state read-only after the client calls conf.Load.
2025-01-02 20:24:36 -05:00
Yuan
8a5f83f814
Merge pull request #43 from mtlynch/password-is-key
Simplify password authentication
2024-12-29 13:39:59 +08:00
Michael Lynch
ea4471f959 Fix undefined variable 2024-12-28 08:20:33 -05:00
Michael Lynch
1f6a9c14c6 Simplify password authentication
fusion's existing session handling logic is a bit incorrect but it still works due to workarounds.

sessions.NewCookieStore is supposed to receive a secure, random value:

https://pkg.go.dev/github.com/gorilla/sessions#section-readme

fusion currently passes it a fixed string baked into source. The result is that an attacker can forge a valid session token (they know the secret key) and send it to a fusion server, and the server would accept it.

The reason this isn't a problem right now is that fusion works around this by storing an additional copy of the password in the session and then checking the password on each authenticated request.

The current implementation works, but I think it's a bit more dangerous and complicated than what's ideal. Ideally, an attacker shouldn't be able to forge a session token at all.

This change makes it so that the session cookie store derives session cookies using the server password as the secure secret. That way, an attacker can't forge session tokens unless they know the server password, but if they know the server password, it's game over anyway.

Because we can trust the session store to reject requests with invalid session tokens, we don't need to store additional copies of the server password. We can trust that if the request has a valid session token, it's a token that the server created.
2024-12-28 08:16:49 -05:00
Michael Lynch
b797c5d1d3 Check for error on retrieving the session
We are currently ignoring the error when we retrieve the session for a given HTTP cookie. I don't see any reason to ignore the error, as the value of the Session object is undefined unless err == nil.

This change updates the code so that we return an error if session.Get returns a non-nil error code.
2024-12-27 15:14:36 -05:00
Michael Lynch
04359e3a20 Adjust name of session key 2024-12-27 06:25:37 -05:00
Michael Lynch
64b071b47a Use a constant for the session key name
We're using a 'magic string' for the echo session key name, which makes it easy for the different instances of the string to go out of sync. Using a named constant makes the intent clear and ensures all copies of the key name in the code stay in sync.
2024-12-27 05:23:43 -05:00
rook1e
8beb858c40
feat(#5): create groups and import feeds into them, based on opml 2024-08-25 18:40:34 +08:00
rook1e
27d8161538
feat: add logout (#18) 2024-08-24 17:11:06 +08:00
rook1e
8a25ffa154
refactor: list only the feeds that match the condition 2024-08-04 17:35:31 +08:00
rook1e
a26c8e0bf7
feat: support hosting as a TLS server directly 2024-08-01 21:20:07 +08:00
linjiaqing
27eb100556 feat: add an env param "InSecure" to allow non-https deploy 2024-08-01 12:48:55 +08:00
rook1e
fb1eb67cd6
refactor: repo should correspond to the domain, not the db table 2024-06-01 15:29:50 +08:00
rook1e
4c7889deff
refactor: use uber-go/zap 2024-03-18 22:10:57 +08:00
rook1e
39072600d3
refactor: derive context from user's request 2024-03-18 18:17:43 +08:00
rook1e
0328848074
feat: add static content cache 2024-03-17 20:12:38 +08:00
rook1e
d91a5a5e3c
refactor: error handling 2024-03-12 22:57:53 +08:00
rook1e
f9f17f71c7
feat: add batch markasread action 2024-03-12 21:52:46 +08:00
rook1e
b43a17767d
feat: add bookmark 2024-03-12 01:51:46 +08:00
rook1e
5dee1de132
feat: add support for suspending/resuming a feed 2024-03-12 01:00:35 +08:00
rook1e
7754e83091
fix: static fallback 2024-03-10 21:11:08 +08:00
rook1e
a60e89129d
refactor: embed pages 2024-03-06 22:33:17 +08:00
rook1e
e9b065e9fb
init 2024-03-06 16:54:13 +08:00