AgeCommit message (Collapse)AuthorLines
Accept only a local path as the way back inBryce Kwon-4/+6
is_safe_redirect looked at the first two characters alone, so it accepted https://evil.example/ and javascript:x. Neither could be signed today only because cgit always signs a url that starts with virtual-root, and nothing tested that. A target now has to start with a single slash, which needs virtual-root to be a path for logins to work, as it is by default.
Read the login form table as layoutBryce Kwon-1/+1
Point the install notes at distribution packagesBryce Kwon-19/+17
Debian, Ubuntu, Fedora and Alpine package luaossl, luaposix and lpeg for the Lua versions they ship, which leaves LuaRocks for the rest. Scintillua comes as a release zip whose lexers directory is what the filter looks for, so its steps say where to put that.
Log failed loginsBryce Kwon-0/+7
The login posts outside any repository, so the log line names the repository by the page its signed way back leads to.
Say that logging in needs httpsBryce Kwon-2/+9
Only HTTPS=on counts, the same test cgit makes before it writes an https link of its own.
Tell a signed-in visitor they have no accessBryce Kwon-0/+6
Say when logins are unavailableBryce Kwon-6/+19
The way back was signed part way through the form, so while the secret's directory did not exist, or a library was missing, cgit's error landed inside the hidden input and the page broke off there with no fields.
Say the auth filters match a repository's urlBryce Kwon-5/+9
A list keyed on the name the index shows matched nothing, so the repository it meant to protect stayed public.
Say where an edited auth filter belongsBryce Kwon-0/+5
make install copies every filter into the filters directory with mode 0644, so an edited auth-inline.lua there lost its lists on the next install, which turned every protected repository public, and until then showed its password hashes to every local user.
Spell url in the Lua comments as the docs doBryce Kwon-2/+2
Write a session's expiry in whole secondsBryce Kwon-0/+5
On Lua 5.3 and later a length worked out with a fraction, such as 1.5 * 24 * 60 * 60, is a float, so the signed expiry came out as 1793609024.0, which validate_value refuses, and every login failed. Max-Age took the same .0, which makes a browser ignore it.
Say what really differs between the auth filtersBryce Kwon-3/+4
The lookups were never the only difference, since the configuration and trim's place differ as well. The configuration is now set off by blank lines, as in the other extensions, instead of a heading.
Drop auth guards for input cgit never sendsBryce Kwon-10/+4
cgit passes an empty string, never nil, when a request names no repository, so the check that the index stays up proved nothing, and auth-file in fact refuses the index too while its repos file cannot be read. A session_seconds of 0 signs a session that has expired by the time it comes back, so it needs no branch of its own in set_cookie.
Strip control characters from the location aloneBryce Kwon-9/+6
set_cookie only ever writes an empty value or a token secure_value built from url-encoded text, digits and hex, so stripping it changed nothing.
Drop the URL helpers' guards that cannot fireBryce Kwon-9/+1
Every caller hands the helpers a string, and a value with a line break is refused by validate_value whether or not CR LF is folded on the way.
Keep only the request fields the auth filters readBryce Kwon-21/+5
Seven of the twelve fields filter_open stored were never read. Naming all twelve parameters keeps the order cgit passes them in on record.
Take a signed cookie apart with one matchBryce Kwon-41/+5
The loop let a valid cookie through with a field appended, a doubled separator or a zero in front of its expiry. The payload now carries the expiry as written, so only the spelling secure_value issues verifies.
Say when a login fails, and line up the formBryce Kwon-8/+22
A wrong password sent the reader back to the same empty form, which looked no different from a crash. The redirect now carries a flag the form reads, the same for an unknown user as for a wrong password, and the form leaves the flag out of the way back it signs.
Claim and test Lua 5.5 for every extensionBryce Kwon-3/+3
luaossl from release 20260910 and luaposix load under Lua 5.5, and cgit renders the same pages under it as under LuaJIT. Running the suites there already caught a write to a for loop's control variable, which 5.5 makes read-only.
Say that a protected repository stays on the indexBryce Kwon-0/+4
Name the auth cookie __Host- where it can beBryce Kwon-2/+10
Without the prefix any host under the same domain could set a cgitauth cookie of its own, signing a visitor in as someone else or out.
End a session when its account's hash changesBryce Kwon-29/+44
A session stayed good for its whole week after the password changed or the account went away, which is when ending it matters most.
Load auth libraries only when a request needs oneBryce Kwon-6/+10
Required at the top, a missing luaossl or luaposix failed every request to the site, public pages included, and each public page paid to load both.
Say which hash kinds each system's crypt checksBryce Kwon-2/+14
The one recipe given, SHA-512 from Debian's mkpasswd, cannot log anyone in on OpenBSD, whose crypt checks only bcrypt, or on macOS, and libxcrypt, which most Linux distributions use, recommends yescrypt instead.
Spend a missing account's login on a real hashBryce Kwon-12/+17
The fixed SHA-512 stand-in matched only the documented setup, so a site hashing with yescrypt, other rounds or bcrypt answered for missing and real names in different times, and on OpenBSD it failed at once.
Turn down passwords past 256 bytes uncheckedBryce Kwon-1/+5
SHA-crypt hashes the password in most of its rounds, so the 4 KB that cgit's POST limit lets through cost about fifteen ordinary logins per anonymous attempt.
Read the auth cookie in linear timeBryce Kwon-9/+21
Splitting the header with patterns that backtrack over spaces cost a quarter of a second per request at the 8 KB line most web servers allow, and a second at 16 KB, without any login. auth-file's trim had the same shape and now reads the cookie as well.
Refuse every repository when auth-file loses reposBryce Kwon-11/+14
A repos file the filter could not open read as listing nothing, so a permission slip or a mistyped path made every protected repository public. A line naming a repository with no groups was skipped the same way, where auth-inline's empty list denies everyone.
Unify the docs, samples and extensionsBryce Kwon-1/+1
Clean up the whole treeBryce Kwon-22/+11
Give the login inputs explicit field typesBryce Kwon-1/+1
Trim the comments and dead code across the treeBryce Kwon-44/+29
Let password managers fill the login formBryce Kwon-4/+4
Restyle the filter extension headers and markupBryce Kwon-158/+183
Move the cookie-signing secret out of the cache v2.3.0Bryce Kwon-1/+1
Trim the lua headers and fix the Scintillua notesBryce Kwon-29/+2
Fix cookie name escaping and stored hash trimmingBryce Kwon-2/+16
Reorganise the tree into vendor/ and custom/Bryce Kwon-0/+0
Harden and reorganise the auth filtersBryce Kwon-187/+345
Harden the auth filter headers and session cookieBryce Kwon-5/+31
The filters signed the request url and later wrote it into a Location header, and the signing step re-encoded a newline that the verifying step decoded back, so a crafted url could smuggle CR and LF into the response. The cookie HMAC was also checked with a short-circuiting comparison, and the cookie carried no SameSite attribute.
Prune and rename the filter extensionsBryce Kwon-2/+15
The Gentoo LDAP filter is distro specific, the owner example only restates what cgit already renders, and the about converters are superseded by the built-in markdown rendering. The two auth filters do the same job and differ only in where their accounts live, so they become auth-inline for accounts kept in the script and auth-file for accounts kept on disk.
Reorganise into source, assets and librariesBryce Kwon-0/+0
Everything the build generates now lands in build/, so a clean is a single remove and the source tree stays free of build output.
filters: migrate from luacrypto to luaosslJason A. Donenfeld-12/+19
luaossl has no upstream anymore and doesn't support OpenSSL 1.1, whereas luaossl is quite active. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
auth-filters: add simple file-based authentication schemeJason A. Donenfeld-20/+65
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
auth-filters: use crypt() in simple-authenticationJason A. Donenfeld-13/+6
There's no use in giving a silly example to folks who will just copy it, so instead try to do something slightly better. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
auth-filters: generate secret securelyJason A. Donenfeld-8/+42
This is much better than having the user generate it themselves. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
auth-filters: do not use HMAC-SHA1Jason A. Donenfeld-2/+2
Though SHA1 is broken, HMAC-SHA1 is still fine. But let's not push our luck; SHA256 is more sensible anyway. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
simple-authentication.lua: tie secure cookies to field namesJason A. Donenfeld-13/+21
simple-authentication: styleJason A. Donenfeld-1/+1
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
auth: document tweakables in lua scriptJason A. Donenfeld-0/+10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>