Skip to content
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

Add server-side password protection for the web interface #197

Merged
merged 43 commits into from
Nov 23, 2016
Merged

Add server-side password protection for the web interface #197

merged 43 commits into from
Nov 23, 2016

Conversation

DL6ER
Copy link
Member

@DL6ER DL6ER commented Nov 16, 2016

Fixes #128.

Changes proposed in this pull request:

  • Add an effective password protection to the web interface as I always felt that the current way of doing it is to inconvenient for most of the users.

Behavior:

  1. No password is set: No surprises, everything is always shown to everyone.

  2. The user sets a password in setupVars.conf: Now, the user will be shown a "login" page:
    screenshot at 2016-11-16 11-51-48
    Also, clicking on the links "Enable/Disable" doesn't do anything completely locking out any non-authorized user.
    Once logged in, the hashed password is always carried around in all links to be sure that we only have to log in once.
    screenshot at 2016-11-16 12-11-02
    The hashing of the password guarantees that the password is never visible in plain-text to someone who might look over your shoulder.

Once we agree on how we like to have it, we should definitely add an (clearly documented) option for the pihole command to make it easy to set the password. We might even ask for it during the installation.

Syntax for setupVars.conf: webpassword="ABC"

@pi-hole/dashboard

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

Added Logout button
screenshot at 2016-11-16 12-27-39

@PromoFaux
Copy link
Member

Thanks for this @DL6ER , I think before we accept, we're going to need to make some changes to how setupVars.conf is handled in the base pi-hole repo.

At the moment, if a user was to choose to re-install (i.e pihole -r followed by reconfigure) then any values in setupVars.conf are wiped out in order to start fresh.

Obviously, there shouldn't really be any reason for the user to have to run that, but it's a possibility, and would end with them having to re-add the password field, (and temperature flag).


Question more related to this PR (I haven't fully gone through the code yet, or tested it...) will the password stored in setupVars.conf always be in plain text, or is it hashed after the first use? Obviously if it's in plain-text then we have a security risk...

@PromoFaux
Copy link
Member

PromoFaux commented Nov 16, 2016

Just tried it out, and in answer to my question, yes.. the password is stored in plain text... not really too happy with that!

Could you also hide these buttons when the user is not logged in?

image

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

I think it makes sense to hide the whole navigation bar if the user is not logged in.
screenshot at 2016-11-16 20-28-36


Concerning password and hashing: I think it is not wise to save a hashed password using PHP. Instead, the password should be stored as a hash in the setupVars.conf file from the beginning, i.e. the pihole command should do this.

I didn't do this here intentionally, so testing would be easier. Should I open a PR to integrate the password setting feature into the pihole command? I'd obviously save only the hash there.


Concerning the possible wipe out of the password and temperature flag: Well, both of these settings are not critical by any mean, so if they get wiped out, then we'll just fall back to the defaults (no password + Celcius).

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

This is how it looks on mobile devices, not unpleasant surprises here.
screenshot_20161116-192912

@PromoFaux
Copy link
Member

Should I open a PR to integrate the password setting feature into the pihole command? I'd obviously save only the hash there.

Yes please! If you can, try and make it so that it's a seperate script that is called by pihole, as with list.sh, update.sh etc.

Concerning the possible wipe out of the password and temperature flag: Well, both of these settings are not critical by any mean, so if they get wiped out, then we'll just fall back to the defaults (no password + Celcius).

Agreed.

@DL6ER DL6ER mentioned this pull request Nov 16, 2016
15 tasks
@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

I opened the PR there. Also, I changed the behavior of the script such that the saved password has to be the corresponding hash.

@PromoFaux
Copy link
Member

Oh, minor niggle, can you CAPSLOCK the variable names?

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

@PromoFaux Not sure what you mean. You mean like $pwstring -> $PWSTRING?

@PromoFaux
Copy link
Member

PromoFaux commented Nov 16, 2016

in setupVars, and then everywhere they are referenced. See the top 6 as an example :)

pi@raspberrypi:/etc/.pihole $ cat /etc/pihole/setupVars.conf
PIHOLE_INTERFACE=eth0
IPV4_ADDRESS=192.168.1.4/24
IPV6_ADDRESS=fe80::49d7:ea2e:28fd:c0b9
PIHOLE_DNS_1=8.8.8.8
PIHOLE_DNS_2=8.8.4.4
QUERY_LOGGING=true
temperatureunit=C
webpassword=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

i.e do TEMPERATURE_UNIT and WEB_PASSWORD

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

Okay, I got confused, since this is the web interface pull request. Also, in my setupVars.conf everything is in lower case, but might be that this has changed recently:

pi@raspberrypi:~ $ cat /etc/pihole/setupVars.conf
piholeInterface=eth0
IPv4_address=192.168.2.10/24
IPv6_address=
piholeDNS1=8.8.8.8
piholeDNS2=8.8.4.4
temperatureunit=C
webpassword=183c1b634da0078fcf5b0af84bdcbb3e817708c3f22b329be84165f4bad1ae48

@PromoFaux
Copy link
Member

AH, yes sorry... they're capped in the development branch ready for next release.

Changed them as per google style guide

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

Well, this is a problem, I think. The function used in the web interface to read from the setupVars.conf file is case sensitive!
Currently, there is e.g. in data.php
$divide = parse_ini_file("/etc/pihole/setupVars.conf")['IPv6_address'] != "" && parse_ini_file("/etc/pihole/setupVars.conf")['IPv4_address'] != "";

This will fail if the capitalization of the variable names changes.

@PromoFaux
Copy link
Member

Have you based off of devel on the web side of things? I thought I'd updated that...

@DL6ER
Copy link
Member Author

DL6ER commented Nov 16, 2016

Sure. It is now updated, see e.g. here: https://github.com/pi-hole/AdminLTE/blob/devel/data.php#L3

@PromoFaux
Copy link
Member

Yeah, turns out I completely imagined that I'd updated that... Good catch!

@PromoFaux PromoFaux mentioned this pull request Nov 16, 2016
Copy link
Contributor

@AzureMarker AzureMarker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we possibly show the user on the main screen when logged in that their session won't expire on that screen? Or would that be unnecessary?

updateTopClientsChart();

updateForwardDestinations();

updateTopLists();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updateTopClientsChart() and updateTopLists() are being called even if not authorized, which will cause more strain on the Pi-hole for no gain since those charts are not available when not logged in.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API will reject the queries anyway, so there isn't much work to be done here. Anyhow, I'll check if the items exist at all before trying to get the data.

@@ -255,6 +263,27 @@
<i class="fa fa-paypal"></i> <span>Donate</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still show the donate button when not logged in.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True.

else
document.getElementById("sessiontimercounter").textContent = "-- : --";

$('.timer').text(currentTimeString);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currentTimeString is not defined

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that shouldn't be there, actually...

@PromoFaux
Copy link
Member

PromoFaux commented Nov 20, 2016

image

Edit: Fixed by clearing browser cache as per @Mcat12's suggestion

@AzureMarker
Copy link
Contributor

I think that is from your browser not updating cached files.

@DL6ER
Copy link
Member Author

DL6ER commented Nov 21, 2016

@Mcat12

Can we possibly show the user on the main screen when logged in that their session won't expire on that screen? Or would that be unnecessary?

I think that is not necessary. Most people won't even know that there is some countdown in the background that might log them out at some time. If you like, we could put the timer display at some other (less hidden) place. Then everything should be more or less self-explanatory (they see that the timer is continuously reset on the main page).

I see that codacy comolained about valid code since it wants to enforce a certain code style. I'm fine with that and will change the corresponding parts.

@dschaper
Copy link
Member

So the session is based on time, not on the session? If a user leaves they can still come back within the hour and the session will still be active?

@DL6ER
Copy link
Member Author

DL6ER commented Nov 21, 2016

@dschaper The session functionality of PHP has an internal timeout feature, i.e. it will invalidate a valid session on its own after a certain amount of time (defaulting to 24 minutes).

Say you visit a site and close your browser completely. If you reopen it within the said 24 minutes, then your session will be refreshed and you have another 24 minutes. If, however, you open up your browser more than 24 minutes later, then you have to login again.

If different users log in, each of them will have his own (independent) timeout.

@dschaper
Copy link
Member

Okay, and then the logout button will immediately invalidate the session...

@dschaper
Copy link
Member

As for Codacy, we have control of the applied rulesets, so if there are hits being registered that are no applicable, we can just disable those particular checks for these files.

@DL6ER
Copy link
Member Author

DL6ER commented Nov 21, 2016

Currently, the session countdown timer is slightly hidden because I don't know if people would want to see it. Should I put it to some more prominent place clearly visible to the logged in user?

@AzureMarker
Copy link
Contributor

It's fine where it is.

&& !!document.getElementById("ad-frequency"))
{
updateTopClientsChart();
}

updateTopLists();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one should only be called if authorized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this should be moved to and replace line 155, because that one is called twice when authorized and never when not authorized.

@AzureMarker
Copy link
Contributor

AzureMarker commented Nov 23, 2016

Approved, pending merge resolution

Approved with PullApprove

@DL6ER
Copy link
Member Author

DL6ER commented Nov 23, 2016

@Mcat12 Conflict resolved.

@AzureMarker
Copy link
Contributor

AzureMarker commented Nov 23, 2016

Approved

Approved with PullApprove

@AzureMarker AzureMarker merged commit 4e9f6b6 into pi-hole:devel Nov 23, 2016
@DL6ER DL6ER deleted the auth branch November 23, 2016 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants