typemill / typemill

Typemill is a lightweight, flat-file CMS designed for simple, fast, and flexible website and eBook creation using Markdown.
https://typemill.net
MIT License
427 stars 60 forks source link

Authentication with htpasswd breaks typemill #178

Closed bugsse closed 3 years ago

bugsse commented 3 years ago

I tried putting a typemill site behind authentication with Apache and htpasswd. The authentication itself works fine, but as soon as I try to save a setting in Typemill I get the error "illegal referer". It seems like the authentication makes typemill see the referer as "https://username:password@typemill.server/tm/settings" which triggers the "security, users should not be able to fake post with settings from other typemill pages" code that compares the referer to the baseurl. I've made it work by commenting out the referer checks in the code, but that's not the correct way to fix it.

trendschau commented 3 years ago

Good question. I think it is ok to uncomment this check because I will replace it with an access control list in the next release. The check was a quick workaround because typemill has no propper rights management so far.

bugsse commented 3 years ago

I've also noticed that using htpasswd sets the "Google sitemap" variable in settings to "https://username:password@typemill.server/cache/sitemap.xml" I'm not totally comfortable with the fact that it displays the password in plain text in a Google sitemap URL.

trendschau commented 3 years ago

well, that is a no go of course.

I am not into your setup and did not test typemill with htpasswd. But if the url contains the username and password, then it is definately not a good idea, because typemill generates at least the sitemap with absolute urls and the sitemap is located in public cache-folder. That is the nature of a google sitemap, it has to be reached publicly by google.

What exactly do you want to achieve? Protect the whole website and show content only to registered users?

As I said I am working on user rights management and maybe I can implement something like "show website only to certain user groups". Not super sure if it is easy possible, but I think there is a way.

For time being I would not use htaccess for password protection at all that way....

trendschau commented 3 years ago

a short look into mozilla documentation: Showing credentials in the url is deprecated at least in chrome browsers and highly insecure, so you should look for another solution or implement the htpasswd in a different way: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

bugsse commented 3 years ago

I'm not using the credentials in the URL. I configure basic authentication in apache, so when going to http://typemill.server I get a username and password prompt from the server. I login, and the URL still shows just http://typemill.server If I go into the admin section, the URL in the browser shows http://typemill.server/tm/settings, BUT the Google Sitemap URL shows https://username:password@typemill.server/cache/sitemap.xml. Also, if I try to save any settings, I get the "illegal referer" error. Somehow, Typemill is using an environment variable that contains the username and password, in cleartext.

What I'm trying to achieve is a documentation site that might contain some passwords, so I would like to only allow access from authenticated users. If you want to, I'll give you access to the site and all configs so you can look at it, I'll send you an email with my contact information.

trendschau commented 3 years ago

I have checked it but not clear to me what happens there. Just to be super clear: It stores the password of htpasswd in the xml, not the password of typemill, correct?

Typemill uses the request-object of slim version 3 to create those urls: http://www.slimframework.com/docs/v3/objects/request.html#the-request-uri

Here is the code: https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Uri.php

Slim supports basic authentication and includes the password and username in the base-path. I suppose that the authentication call was the first call of the typemill website and it generated the the xml with it. The sitemap refreshes every 24 hours. Maybe you can check it and delete the cache folder and call the site again so that the cache recreates. I suppose that it is gone then. And I have to look into it and prevent typemill from generating any navigations/sitemaps if a username/password-scheme is in the uri.

With the other problem: If typemill alerts because of an illegal referrer, then the referrer in the request is different from your actual url. I suppose it is caused by some kind of redirect or alias on server side, but I am not an expert in those server configurations.

I will try to look deeper into that topic but it will take some time, sorry. Generally I would wait for the next release, then you can protect the content of pages with user rights. It will take some time to finish the next release.

Anyway, thank you for reporting this!

bugsse commented 3 years ago

Yes, it shows the password from the htpasswd authentication, not the password from typemill.

"Slim supports basic authentication and includes the password and username in the base-path" Then that is the problem, since Typemill seems to use that variable to figure out its own url. When typemill compares base-path with referer, base-path shows http://username:password@typemill.server/ and referer shows http://typemill.server/

trendschau commented 3 years ago

I will try to fix it this weekend, thank you for reporting again!

trendschau commented 3 years ago

I fixed it with version 1.3.7.2 and changed $request->getUri(); to $request->getUri()->withUserInfo(''); everywhere.

I also uncommented the referrer-check because it does not make too much sense and will be replaced in the next release with acl check.

Let me know if the fix works for your case.

bugsse commented 3 years ago

Seems to work fine in 1.3.7.2 :)

trendschau commented 3 years ago

Typemill 1.3.8 is out now. You can restrict the access to the whole website to registered users now. This might be an alternative to htpasswd, but you have to add all users as "member" to typemill then. With a lot of users this is of course not managable without a singel sign on system. Anyway, have a look...