Skip to content

basicauth: Allow htpasswd= to be used to fetch both username and password from a .htaccess file #1402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
magikstm opened this issue Feb 5, 2017 · 17 comments
Labels
discussion 💬 The right solution needs to be found

Comments

@magikstm
Copy link

magikstm commented Feb 5, 2017

Currently the "htpasswd=" parameter can only be used to retrieve a password for a username.

I would suggest editing it's functionality to allow for such usage:
basicauth htpasswd= {
resources
}

As well as:
basicauth /path htpasswd=.htpasswd

Which could retrieve both usernames and passwords from a .htaccess file.

Ref: https://caddyserver.com/docs/basicauth

If it's accepted, I could probably submit a pull request.

@mholt
Copy link
Member

mholt commented Feb 7, 2017

So, now that you've brought this up, and I really value this feedback/suggestion, I want to start a serious discussion about replacing .htpasswd entirely. It's kind weird that Caddy supports .htpasswd which was designed for Apache server. I also think .htpasswd is a little difficult to use, and we could come up with something more Caddy-esque to work with the basicauth directive, and perhaps other auth directives that may crop up in the future.

In other words, rather than improve .htpasswd support, I want to remove it, and replace it with something different. What do you think?

@magikstm
Copy link
Author

magikstm commented Feb 8, 2017

I agree that basicauth is old and it would be a good idea to replace it with something better. There hasn't been a real solid alternative that is "as easy to use" and that provides a "level of security around that level". It is far from perfect, but it works "relatively well enough" for some specific use cases.

I personally use it for some clients website for:

  • Staging sites
  • To protect some "non-sensitive" folders or apps
  • Member's area (based on my experience, most of the time, it's not more vulnerable than WordPress, any other CMS or a custom solution as long as there is a brute-force block from fail2ban or another tool)

My suggestion would be to deprecate it from Caddy and maybe remove it from the main build now or eventually, but I wouldn't remove it. I think some users do have some use cases for it and a similar feature would be requested.

@mholt
Copy link
Member

mholt commented Feb 8, 2017

I didn't mean to replace/remove HTTP Basic Authentication, I meant to replace the htpasswd file. (Or maybe you were also talking about the .htpasswd file, then don't mind me.)

Anyway, yeah, I agree -- we at least need something to replace it with.

@magikstm
Copy link
Author

magikstm commented Feb 8, 2017

Oh. That could be a good idea. It's vulnerable as-is if someone gets the file and it's kinda lacking some basic features for some situations (user info, creation date, expiration date, etc.).

I would be really interested in a "Basicauth v2" that is Caddy specific if it adds some additional features.

A lot of basicauth users don't use a brute-force protection (such as fail2ban) and that would be amongst the first one I would consider. I've had to help harden such solutions quite some times as it was never though about.

@mholt
Copy link
Member

mholt commented Feb 8, 2017

As long as it's compatible with HTTP Basic Authentication, we could make the basicauth middleware work any way we want. It hasn't changed much since my initial implementation a couple years ago. Would be happy to discuss specific proposals for changes to it.

@mholt mholt added the discussion 💬 The right solution needs to be found label Feb 8, 2017
@jheiselman
Copy link

I was thinking about replacing the .htpasswd file and I was wondering if a solution that doesn't have external dependencies is preferred over one that depends on something like a file format reader/writer (INI, TOML, XML, etc...)

I think that a having any sort of file that requires lists of usernames/passwords is going to need to have two things:

  1. Easily human readable (preferably with comments)
  2. Strict structure to make machine parsing easy

That said, I think XML, JSON, and YAML are out. They are just too easy to get wrong if a novice user is hand-jamming them in via vim. Something like INI or TOML would be nice. TOML allows for some slightly more complex data types while INI is just less feature-rich TOML.

The downsides to INI or TOML is that there isn't any support in the standard library for them unlike XML, JSON, or even CSV, however, they do have some mature libraries.

@skorokithakis
Copy link

I think #1507 is a very good idea on this topic.

@jheiselman
Copy link

@skorokithakis so an authentication middleware that handles third-party authentication services sounds good, but I still think a local, file-based approach is necessary too for simple use cases.

@skorokithakis
Copy link

@jheiselman Definitely, I was just linking that issue because it's interesting. For a file-based approach, I don't see something much different than an htpasswd-style file being necessary. Maybe something like:

<username>:bcrypt$<salt>$<digest>:<path>
<username2>:scrypt$<salt>$<digest>:<path>

I don't think any new format should support any hash format (i.e. MD5, SHA, etc). It should only support KDFs like PBKDF, bcrypt, scrypt, as those are the only secure formats for password storage.

A new format could optionally have a path designator at the end, so permissions could go in the file itself rather than in the server config, maybe? But then you get the problem of wanting to support the same users across different hostnames.

@jheiselman
Copy link

Just so I'm clear, you are suggesting per-entry algorithm selection as opposed to it being defined along with the path in the server config?

Regarding having permissions in the user database, that would be against standard best practices of separating the concepts of authentication and authorization.

@skorokithakis
Copy link

skorokithakis commented Mar 10, 2017

Yes, I am. How would you define the algorithm along with the path? The algorithm is a property of the hash, not of the authentication entry.

I tend to agree with your second point.

@jheiselman
Copy link

In Postfix, configuration databases are specified with the file format and the path. For Caddy, I see specifying the hashing algo (instead of the file format) being useful.

basicauth <endpoint to protect> <hash>:<path to user db>

@skorokithakis
Copy link

Hmm, how would that work with multiple hashing algorithms? Where would you specify the bcrypt rounds? What if you upgraded some of your users to scrypt but couldn't get the others' passwords? Etc.

@jheiselman
Copy link

The two approaches would not be compatible. Either the user db has the algo specified in the server config and all entries use the same one, or it's specified per-entry in the db itself. I think it would come down to a matter of desired complexity.

In my example, it would be a single scan of the user db to determine if the user passed good credentials because the server would already have knowledge of how to hash their supplied password. In your example, it would be a slightly more complex effort as you'd have to retrieve the hashing method and then you'd can compare values.

In my experience, your method would be preferable so that you can easily migrate to new algos as time goes on without having to migrate everything all at once. My only concern here is with simplicity.

In my comment above, I stressed simplicity for a user manually making entries. I strongly believe that this should be a goal.

@skorokithakis
Copy link

You don't hash the password before looking up the username, though. You look up the username, see the hash you have stored for the password, and just hash it once.

@jheiselman
Copy link

I have little experience there, so I'll defer to you. In the past, I've done it the other way, but that could have just been my poor inexperience informing my design decision.

@mholt
Copy link
Member

mholt commented May 9, 2019

Authentication in Caddy 2 is probably being revamped, so, closing this for now.

@mholt mholt closed this as completed May 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 💬 The right solution needs to be found
Projects
None yet
Development

No branches or pull requests

4 participants