pi-hole / web

Pi-hole Dashboard for stats and more
https://pi-hole.net
Other
2.04k stars 558 forks source link

Possible Future Security Breach Warning #39

Closed Fedora-Core closed 8 years ago

Fedora-Core commented 8 years ago

The future maintenance functions of the /admin/ website can be reached from the outside !

[PANIC SWITCH] ---------- [ON]

The IT-gurus, employed by the multi-million-dollar advertising industry (that we sabotage), can - in the future - 'whitelist' their domains with something like the following : <img src="http://adserver.com/admin/php/add.php?list=white&domain=adserver.com">

Pi-Hole is Open-Source, and the GitHib development branch is visible by everyone, including by these IT-gurus of the advertising industry.

---------- Request => Please 'harden' the Pi-Hole admin webserver.

2 Possible solutions => One for Short-Term, and One for Long-Term.

Solution 1° - Short-Term { Add username / password Authetication. }

From the github / pi-hole / wiki = https://github.com/pi-hole/pi-hole/wiki/Nginx-configuration-instead-of-the-default-lighttpd-and-php-cgi-option

From the jacob salmela blog = http://jacobsalmela.com/password-protect-a-lighttpd-web-server-on-a-raspberry-pi-using-mod-auth/

Solution 2° - Long-Term { Run each of the Pi-Hole-appliance's services on individual Static IP-addresses. }

A) Give the RaspberryPi's 'main' interface a Static IP-address for SSH and other softwares. Bonus: this main Static IP-address remains free for other appliances (cloud, web, streaming,...) Note : we have seen this requirement on several fora by people who want to run other stuff too.

B) Give the Pi-Hole-appliance's DNS server another Static IP-address for the DNS resolution. Bonus: this is the only Static IP address that the user's router must know.

C) Give the Pi-Hole-appliance's 'adblock' Webserver - and future miniDLNAserver - yet another Static IP-address, and adapt the gravity script accordingly. (No more dynamic-searching for the IP). Bonus: the user of the Pi-Hole-appliance can run other webservers on the main interface Static IP-address - see A). Optional Bonus: a full-fledged webserver, crippled with Rewrite-Rules, is no longer required. A simple webserver in Perl, or in Python2, or in Python3, or even in command-line PHP, can simply reply with the HTTP header '204 No Content'. ° This new Static IP-address must not be known by anybody but: the gravity script that feeds the DNS server's configuration file.

D) Give the Pi-Hole-appliance's 'admin' webserver yet another Static IP-address. Bonus: Cutting-off the outside world. Problem solved. Bonus: No need for /admin/ in the URL. It can be the document-root for this webserver. Bonus: No need for yet another username / password to remember. (But may be optional.) ° This new Static IP-address must be known only by the 'administrator' of the Pi-Hole-appliance.

Optional => E) Disable (not un-install) the dhcp-client-daemon(s), the assumption being that we run a 'server'. F) Use the '/etc/network/interfaces' again to declare the multiple Static IP-addresses, this time by using the 'ip' utility from the 'route2' package. Raspbian Jessie already includes the statement 'source-directory /etc/network/interfaces.d'

Conclusion: Yes, We Can.

[PANIC SWITCH] ---------- [OFF]

Note: why I used the term 'Pi-Hole-appliance' => Quote from the githib / AdminLTE / New admin features (idea) #24

jacobsalmela commented 3 days ago If we ever want to commercialize anything, ....

Greetings, F.C.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/31023975-possible-future-security-breach-warning?utm_campaign=plugin&utm_content=tracker%2F20311099&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F20311099&utm_medium=issues&utm_source=github).
PromoFaux commented 8 years ago

Hey, thanks for the post.. I've only skimmed this so far, but promise I'll do the justice of giving it a full read when I get home from work!

Just a note.. it can only be accessed by malicious third parties if it's set up to be visible from the outside world... (which we do not do, by default.. it would have to be done in the port-forwarding settings of the users router...)

Other than wanting to see the stats, why would you forward port 80 to the pi-hole?

But I totally understand the sentiment of your post, and I will give it some thought.

I will read it properly.

PromoFaux commented 8 years ago

Yeah, ok wow. I really didn't read that properly. You make a lot of valid points, which will be discussed.

@Mcat12 Before you push devel to master, could you completely strip the whitelist/blacklist php pages from the repo, rather than just hide the links. I know they don't fully function yet, but just to be on the safe side we should probably get that locked down before we push them out to users.

AzureMarker commented 8 years ago

This will not be a problem in the next release, but we will certainly figure out a way to fix this!

AzureMarker commented 8 years ago

Does #49 fix this?

Fedora-Core commented 8 years ago

At first sight it should work. However.... At first sight. It is a work-around. Like back in the mid-1990s.

The well-paid IT-gurus from the multi-million-dollar advertising industry are already busy with the modification of their Pi-Hole-"whitelist" hack. With something like the following => <img src="http://adserver.com/admin/php/add.php?list=white&pass=0.0&domain=adserver.com">

---------------------------- Please 'harden' the Pi-Hole admin webserver.

Security should not be accomplished with a work-around. It should be done fundamentally.

Security should not be accomplished with GUI code. It should be done with the underlying server systems.

----------------------------

Final General Observation => This proposed fix ( even when fixed again ) would be valid only for this particular piece of the Pi-Hole adminLTE functionality. Who knows ( now ) what other functionalities are imaginable in the future ? Do these new functionalities also need to fix their access problems with a GUI work-around ?

----------------------------

Greetings, F.C.

PromoFaux commented 8 years ago

:+1:

PromoFaux commented 8 years ago

I've had some thoughts on this myself, which we are currently discussing internally, I'll be sure to run in by you for final analysis before we realise we have missed something important :)

DonLexos commented 8 years ago

Well one thing to take in consideration is that when you require a password no matter how you save it it needs to expire. It's not a real fix if you require it and cookie the user for 30 minutes who then goes out and browses the internets only to visit a addomain.com/admin/trick-url with his credentials saved.

Not entirely sure about lighttpd but what could help is that a ?sessionid=X is required in the url and otherwise it requests the login details. The adserver can't ever guess it, and as long as it is not saved in a cookie (but in a session) it should not be able to find it.

dschaper commented 8 years ago

Persistent cookies? (And with the password comes maintenance, and users forgetting passwords, locking themselves out and all the other fun of securing the things...)

AzureMarker commented 8 years ago

The password is only saved in the js, not a cookie, so it is never kept for longer than the user has the page open.

dschaper commented 8 years ago

Here's a wild one, Google Authenticator,,, 2 Factor it...

dschaper commented 8 years ago

But a password and a cookie, make the process so there isn't a single point of failure (or single point of override in this case...)

DonLexos commented 8 years ago

No cookies at all, if the /admin/php/whitelist.php checks for a valid cookie it does not really matter if there is a password or not if the user logged in prior.

You could simply have the password stored in a file somewhere and have the user log in, then create a session and use that in the URLs.

2factor might bring many new challenges. I would love it (since I already use 2FA) however I can imagine that for some users that might complicate things.

DonLexos commented 8 years ago

And @dschaper and in a normal situation a cookie would be set by the code that handles the successful browser login. Even if you let it expire in 5 minutes the window of opportunity for a rogue <img src="http://adserver.com/admin/php/add.php?list=white&domain=adserver.com"> is small but still there.

dschaper commented 8 years ago

We do have a method to tell if the request came from the /admin.php page though... @DonLexos take a look at your /admin.php page and look at the X-Headers...

PromoFaux commented 8 years ago

Surely we can't use that as an auth method...? Wouldn't that be quite easy to spoof?

DonLexos commented 8 years ago

@dschaper trying to find them in Chrome Dev console but fail to locate them.

dschaper commented 8 years ago

Not as a single authentication method, but as a part of a layered approach. And to spoof that then the ad companies would have to send out that x-header, and I seriously doubt they would go that route... (It'd be nice to get some legal protection on the phrase used in the X-header and then nail them for trademark infringement if they used it...) I'm just throwing out multiple methods that we can use in a layer approach...

dschaper commented 8 years ago

@DonLexos Can you install HTTP Headers from the Chrome store?

dschaper commented 8 years ago

capture

DonLexos commented 8 years ago

Got it, you would use the referer?

dschaper commented 8 years ago

The X-Pi-Hole header, and I think with some magic you could randomize the payload for the header and verify that, or at least change up the payload so that it's not predictable? Totally throwing off the wall here just to see if anything clicks...

DonLexos commented 8 years ago

But how would the page get that token?

I mean if it is in a cookie the rogue addomain.com/admin/etc would simply still work since it is locally, problem is we redirect addomain.com to pi-hole-ip and that has access to exactly that info, no?

Verpz commented 8 years ago

Php for the password? And not everyone has cookies enabled. 2 step would be great but wouldn't the pi need Internet access?

dschaper commented 8 years ago

If you look at the lighttpd.conf you see that anything that is served via the admin directory has that X-Header added to it, so that could be just another piece of authenticating information, maybe along with a session cookie or something. If a company want's to endrun us, they will, there's no stopping them honestly, we just need to make it more uncomfortable than comfortable for them to do anything. And we'll probably need to change tactics, just like we needed to change when IPv6 became the way to send ads down the pipe....

Of course I could be completely wrong, but it's an idea?

dschaper commented 8 years ago

And the blank replacement page has it's own X-Header added...

dschaper commented 8 years ago

@verpz, Nope, with 2 factor you only need to sync up once, then everything is generated via a shared algorithm. no internet access is needed. (Although a Pi-hole without net access wouldn't do too well, since it needs upstream DNS servers to resolve good addresses, and the install script picks it's IP address by checking to see which interface has a route to 8.8.8.8)

dschaper commented 8 years ago

Gotta run to a site survey, the team knows how to ping me if they have any questions...

dschaper commented 8 years ago

Oh, and I have cookies and JS disable in Chrome, but I allow the sites I want through, and I think that's a fair thing to ask our users... I'm kind of laying hard on the enterprise aspect of things, I think that would be a great place to get into...

jacobsalmela commented 8 years ago

Ad Block Plus uses X-headers with unique IDs to make sure they get whitelisted. I wrote an article on it a while back, so I'm sure something like that would be possible.

DonLexos commented 8 years ago

If you look at the lighttpd.conf you see that anything that is served via the admin directory has that X-Header added to it, so that could be just another piece of authenticating information, maybe along with a session cookie or something. But that does not prevent the issue raised then would it. The addomain.com/admin/whatever would also contain that specific X-Header since it is served from the same directory. A cookie could work only if that would not be accepted if the url is not http://192.168.1.x/admin/ but http://addomain-trick.com/admin

PromoFaux commented 8 years ago

I've been thinking along the lines of a seperate web server entirely for the admin pages. Behind a non-standard port which the user chooses themselves. In that case, we have no way of knowing what the port used is, and neither would ad companies.

PromoFaux commented 8 years ago

Hell, it could even be done in lighttpd

DonLexos commented 8 years ago

Well the port part sounds like a plan! Not sure if you should enable 2 webservers, some people are really keen on keeping things light. I would be happy to install MySQL for example since my pi only does the pi-hole blocking, but others disagree.

Verpz commented 8 years ago

What if the api is moved to a separate folder like /api, that is separately password protected. Or to trigger the whitelist / blacklist function it requires a password in the url like this:

/admin/php/add.php?list=white&domain=ad.com?password=whatever

Would the url be really un secure? Two step auth sounds great but it may be confusing to some users.

dschaper commented 8 years ago

I see a possible split in the code base, home use and enterprise use. Home use is getting more and more complex. Passwords are just a difficult thing to do operationally, but I like the ideas, keep them coming and lets see what we can cherrypick out and put together... Thanks for everyone's input on all of this...

Verpz commented 8 years ago

What if there are two install options, like for basic home setup with no extra features (set and forget) or an advanced install where perhaps a flag is added to the install command such as:

-a or -advanced

Which gives more options and customisation which could be used for "enterprise" installations or for people who want extra features and such. This way there wouldn't be two separate projects or a split in the code. Am I right in saying that the api / add.php is the main security issue here? In that case a random api key generated on install and a user defined password on install should fix that issue, unless /admin needs to be protected in general.

DonLexos commented 8 years ago

What if, the admin folder is not default at /admin/ but at /whatever/. Maybe even by user choice, or just random /admin3312/. Even adding 4 digits would resolve the rogue adserver thing since I doubt they will add 10000 lines of image code (and when they do you can always add a digit more).

As long as the script mentions the admin page at the end :: You can find the stats in the admin panel at http://192.168.1.x/admin3312/

Only thing you need to do is save it. Or would that wreck the git intergration?

AzureMarker commented 8 years ago

That might work, but users either won't like or will choose a generic one like pihole or admin.

DonLexos commented 8 years ago

Well in that case why let them chose? I would not care a bit as long as I know where it is, and it does not change after an upgrade since I simply bookmark the /admin3312/ page.

AzureMarker commented 8 years ago

How about staying with passwords (until we move to different ports or something) and check the hash of the password and input. That should fix the problem of inputting something like 0.0 for the password.

AzureMarker commented 8 years ago

Also, store the password after install as a hash instead of plain text. This function could be useful.

DonLexos commented 8 years ago

Passwords is also a good solution! Would also prevent users in same network to access (and white/blacklist things) in a more commercial installation environment.

AzureMarker commented 8 years ago

Currently, that's what's up in devel.

PromoFaux commented 8 years ago

Wait was password=0.0 a specific exploit? How would that even work? I really think we should get a solid thought through bulletproof option together, rather than a half-baked stopgap. We're not desperate to include the extra functionality to the website, as nice as it would be.

DonLexos commented 8 years ago

I will need to dive into git(hib) better so I can fetch the devel branche, test/play with it myself and help out there (if/when needed).

PromoFaux commented 8 years ago

Wait was password=0.0 a specific exploit? How would that even work? I really think we should get a solid thought through bulletproof option together, rather than a half-baked stopgap. We're not desperate to include the extra functionality to the website, as nice as it would be.

PromoFaux commented 8 years ago

Argh. Apologies, commenting from mobile. Messing things up!

AzureMarker commented 8 years ago

I haven't tested it yet, but hashing and checking hashes should prevent any exploits such as that.

AzureMarker commented 8 years ago

Just tested, 0.0 doesn't work