Comments (78)
I gave up on being hip as soon as I turned 30. XD
from adminlte.
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.
from adminlte.
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.
from adminlte.
This will not be a problem in the next release, but we will certainly figure out a way to fix this!
from adminlte.
Does #49 fix this?
from adminlte.
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.
from adminlte.
👍
from adminlte.
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 :)
from adminlte.
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.
from adminlte.
Persistent cookies? (And with the password comes maintenance, and users forgetting passwords, locking themselves out and all the other fun of securing the things...)
from adminlte.
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.
from adminlte.
Here's a wild one, Google Authenticator,,, 2 Factor it...
from adminlte.
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...)
from adminlte.
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.
from adminlte.
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.
from adminlte.
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...
from adminlte.
Surely we can't use that as an auth method...? Wouldn't that be quite easy to spoof?
from adminlte.
@dschaper trying to find them in Chrome Dev console but fail to locate them.
from adminlte.
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...
from adminlte.
@DonLexos Can you install HTTP Headers from the Chrome store?
from adminlte.
from adminlte.
Got it, you would use the referer?
from adminlte.
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...
from adminlte.
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?
from adminlte.
Php for the password? And not everyone has cookies enabled. 2 step would be great but wouldn't the pi need Internet access?
from adminlte.
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?
from adminlte.
And the blank replacement page has it's own X-Header added...
from adminlte.
@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)
from adminlte.
Gotta run to a site survey, the team knows how to ping me if they have any questions...
from adminlte.
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...
from adminlte.
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.
from adminlte.
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
from adminlte.
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.
from adminlte.
Hell, it could even be done in lighttpd
from adminlte.
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.
from adminlte.
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.
from adminlte.
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...
from adminlte.
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.
from adminlte.
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?
from adminlte.
That might work, but users either won't like or will choose a generic one like pihole or admin.
from adminlte.
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.
from adminlte.
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.
from adminlte.
Also, store the password after install as a hash instead of plain text. This function could be useful.
from adminlte.
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.
from adminlte.
Currently, that's what's up in devel.
from adminlte.
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.
from adminlte.
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).
from adminlte.
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.
from adminlte.
Argh. Apologies, commenting from mobile. Messing things up!
from adminlte.
I haven't tested it yet, but hashing and checking hashes should prevent any exploits such as that.
from adminlte.
Just tested, 0.0 doesn't work
from adminlte.
I'm pretty sure it was just given as an example. What he's saying is that if the password is intercepted, somehow, the function can be run.
from adminlte.
That's going to be the same problem with any of his solutions. Without encryption, it's going to stay like that...
from adminlte.
I don't think that there's enough features to split between home and enterprise. With #53 this issue may be solved until we move to redirecting ads to an empty server or port or something.
from adminlte.
I've just been reading through this issue, pi-hole/pi-hole#354, and #49
In those pull requests, it looks like we're rolling our own password protection, which usually means spending a lot of effort on writing and maintaining that's likely to have some flaw compared to something prebuilt we can use that's been written by a netsec team whose code has been well looked over by the FLOSS community.
pi-hole/pi-hole#360 and #53 also - my first thought was "Wait, why not bcrypt?" then "Wait, why not salt it?", followed by "Wait, I'm not even remotely netsec, surely there's even more missing than the basics I've read repeatedly on Ars Technica?"
Forgive me but I must be missing something - is there a reason we're not using lighttpd's mod_auth? I can see @Fedora-Core already mentioned lighttp's mod_auth in passing. (Ironically Googling "lighttpd mod_auth" brings up Jacob's article as the second result.) We know it will be relatively reliable, and there are quite a few options on how we encrypt the password, plus digest auth.
On another note:
- @Fedora-Core mentioned running the admin web server on a different IP address.
- @PromoFaux mentioned running it on a different port.
- @DonLexos mentioned running it on a different subdirectory.
Another option: we run it on a different virtual host. I don't know lighttpd as well as apache, but I understand it can support virtual hosts just fine. The result would be, for example http://mypiholeadmin/admin, takes you to the admin interface, whereas going to http://myadserver/admin takes you to the blocking vhost. Since we control DNS this is easy to add to the hosts file or 01-pihole.conf.
First of all the ad provider would need to use a domain that isn't their own to try to trick the pi-hole, e.g.
<img src="http://piholeadmin/admin/php/add.php?list=white&domain=adserver.com">
, which is bad form for them (not sure how non-pi-hole users' browsers will react to that) and I'm sure some ad networks wouldn't even allow. EDIT: Heh, we could even make it a globally routable domain (e.g. http://piholeblocking.cheaptld), register it ourselves and put some code - non-malicious but messes up the page for non-pihole users? Big ad wouldn't want to link to it then!
If we want, similar to the subdir idea we could ask the user for a domain to obfuscate it a bit - e.g. http://mypiholeadmin9725. EDIT: Or we could use the actual pi's hostname for this? Different for every user but they should know what it is.
Also, I believe would allow us to specify lighttpd options specific to the admin interface more easily than with a subdirectory, in particular mod_auth. It would also simplify the blocking vhost (regex wouldn't have to accommodate /admin).
from adminlte.
Also, I'm just thinking of a few things we can do to stop embedding. I doubt we can fully harden it this way and in any case I'm still strongly in favour of passwording the interface, but just food for thought:
- This logic to stop hotlinking would stop the admin interface from being loaded in an img tag?
- A few ways to stop iframes? Some Javascript, Content-Security-Policy.
from adminlte.
it looks like we're rolling our own password protection
It's there, but I personally am not happy with it. It's a workaround/hack to put off an issue, but it's there.
At the moment the whitelisting from the website is being put on hold whilst we work on the refactor, so there is plenty of oppurtunity to get this aspect of things nailed down. I still think the separate port idea is the simplest solution.
from adminlte.
It's there, but I personally am not happy with it. It's a workaround/hack to put off an issue, but it's there.
I know password protection wasn't considered until this issue was raised. But, done right, is it not a good idea as a permanent feature? IMO it's something we ought to have as standard anyway.
Password aside, in terms of separating the admin interface, your separate port idea is my second choice and I agree that it's by far the simplest to implement and maintain.
from adminlte.
I like the own hostname idea, or running it on a (non existent) domain. What if the domain would be the non existent adminconsoleformypihole.pi
. We can resolve this ourselves and in combination with what @ryt51V mentioned it could resolve to somewhere in /var/www/html/whatever
that is not accessible through blockeddomain.com/admin/
(or http://192.168.1.xx/admin
).
from adminlte.
Sorry, @ryt51V I meant in terms of rolling our own. Self-rolled authentication/security/encryption of any sort is generally a bad idea!
I really like @Fedora-Core's suggestion of multiple IPs, but it's a bit beyond my understanding of how things work! Which is why I ended up thinking about separate ports instead. :)
from adminlte.
@PromoFaux Ah, right, thanks for clarifying. This is why I'm a bit confused in the first place - AFAIK using lighttpd's mod_auth in the first place would not only have been better but also quicker and easier. i.e. A quicker ugly hack, except not ugly and not really a hack.
I think multiple IPs for each service are ideal, but are not appropriate for an auto install script, both now and after this project has matured. Ports, vhosts and subdirs are far more suitable.
from adminlte.
I noticed pi-hole had no authentication for the web panel when installing today, and im also not really a fan of lighttpd. So, I moved it over to nginx and setup a simple basic_auth user:pass setup, nothing fancy but it works. Definitely agree on the separate static ip solution for long-term security, though.
For even better security for the web service (although probably overkill) you could setup HTTPS Client Authentication so that only the administrator of the pi-hole with the certificate can interact with the web service.
from adminlte.
I haven't read all of the comments here, but is this not just XSRF ("Cross Site Request Forgery")?
XSRF is a common issue - eg. if I'm logged into my bank and then I visit a malicious site, what's to stop them outputting a form with hidden fields and auto-posting to my banks transfer form to steal my money?
There's some info in this here:
https://en.wikipedia.org/wiki/Cross-site_request_forgery
One fix is basically to make sure all whitelists requests get a random value (token) entered into the form when the HTML is rendered and when submitted to the server, validate that that token is correct. Here's what it looks like in aspnet mvc (I know you don't use that, just the one I'm most familiar with).
from adminlte.
May also be worth reviewing CSP and locking down anything else that shouldn't be allowed. And X-Frame-Options to ensure the control panel can't be loaded inside a frame on a site (eg. to be click-jacked).
Edit: Oh, I see a lot of this is already being discussed in #444! :)
Edit (Mcat12): Corrected link (It was going to an issue on almasaeed2010's AdminLTE)
from adminlte.
Yep, actually just implemented the token on the whitelist
branch and X-Frame-Options on the other repo (that's where the server configs are).
from adminlte.
@Fedora-Core Have you checked out the latest dev versions of Pi-hole and the web interface?
from adminlte.
Open Source is great !
If one dares to open the source...
Yes, I have followed the development branch.
And now you have introduced a "source" for far more serious issues => concurrency !
What if father Abe is blacklisting a bunch of porn domains for his little daughter,
and his son Ben is busy whitelisting a newschannel,
and his son Carl is busy whitelisting a gamesportal,
all at the same 2 second interval ?
Since that's the time-frame that the script typically needs to finish on a bare Raspberry-pi.
And a pihole running in a college dorm has probably several adminweb-users...
Problem = concurrency !
Don't tell me that you will instruct the pihole adminweb-users not to do this...
Don't tell me that you will instruct the pihole installers not to give the adminweb away...
Once your software is in the wild, you have strictly no control over it's use.
Your development needs to be 100% foolproof.
This is about delegation of duty, and also - I'm not going into it - elevation of privileges.
Proposal:
The PHP must accept the request from the adminwebuser, and pass it on to another process.
That other process should - independently - execute all the accumulated request that have been queued in a very well defined - and publicized - time-slice.
Don't look at the PHP semaphores, they are in fact a form of mutex.
Don't look at the PHP queues, they use shared-memory (don't know how Docker likes that)
Don't try to install another package for queueing, most require too much effort.
There is a very simple solution to tackle this.
° A cron job (a one minute interval would do just fine)
° A subdirectory "arriving" with write access for www-data
° A subdirectory "arrived" with write access for www-data and the cron job
° A subdirectory "accepted" with write access for the cron job
° A subdirectory "iamalreadyandstillbusy" with write access for the cron job
° Elevated privileges for the cron job only (SignalHangUp towards DNSMasq)
° etc
Get inspired ;-)
Yes we can!
note:
The English language has this expression:
Eating_your_own_dog_food
About Feb 19, 2016 =>
I have immediately (19) implemented my own proposed short term solution.
I'm safe.
I have during the following week-end (20-21) implemented my own proposed long term solution.
I'm very safe.
from adminlte.
Re: Docker, Is it the Docker way to have a container that includes both a DNS Resolver and a web server? Wouldn't the concept of microservices dictate that two separate containers be used and Compose them together? Or if using a recent Docker version, advertise the services?
from adminlte.
@Fedora-Core What about using a database for the queue? We are currently experimenting with sqlite with the Python rewrite and it's going well. PHP could add to a queue and then call a pihole script that would run through it. Just thinking out loud here. :)
from adminlte.
Would that just put the race in a different queue though? Not really solving the concurrency unless you lock the database for access and then it's just pushing the the issue to another thread.
Speaking of which, would you folks be okay with a new issue for concurrency discussions. Don't want to have this single issue addressing two separate themes... Yeah, I'm a little AR about that kind of thing, 😃
from adminlte.
A new issue would be good. But about the database, it could have an auto incrementing id, and the program would go from lowest to highest id. Therefore when a new action gets into the queue, it'll be handled by the program after all the other actions get handled. I'm pretty sure sqlite would be able to handle concurrency, as this mentions that it locks the database during writes.
from adminlte.
Okay, I was thinking Race versus Concurrency. User A blacks a domain while User B whites the same domain in the same update cycle. I'm still fighting with even needing an external database with Python, just using all internal data structures and exposing via API or interfaces. But that's yet another Issue :)
from adminlte.
I'm a little late to this conversation, but would a simple sqlite db with session variables work? Seems like that would be a pretty easy fix to add user authentication to pages that need it without needing to overhaul too much.
- login page (process logins and set session)
- on add.php add to top
if (!isset($_Session['login'])){ header ( 'location: admin/login.php')}
- create a user cp that lets admin change password as needed.
If user forget password they can open up the sqlite db and add a new one in manually.
from adminlte.
Thanks for your concern @viemmsakh. 😄 In the latest version we've implemented session variables in the security-focused php (whitelisting and blacklisting) that verifies that only the web interface is able to activate those actions. We've also made sure that the web interface can't be used in an IFrame (tricking users to whitelist the ad one way or another). We're still not sure whether or not we should add a login page for the web interface (or parts of it), but we'll keep your idea in mind. 👍
from adminlte.
Did you implement XSRF protection?
from adminlte.
I'm a bit behind on websec terminology.. but if CSRF is the same thing, then yes!
from adminlte.
@PromoFaux Sorry yes, it is :) Sometimes people write "X" for "Cross" in an attempt to be hip ;)
from adminlte.
These issues should be fixed for now.
from adminlte.
Related Issues (20)
- Local DNS records and CNAME don't show pagination buttons HOT 11
- After clicking on the +/- icon they keep the "active" state making them nearly invisible with dark theme HOT 1
- After datatables update, tables are no longer striped HOT 1
- Save button on boxed layout outside of content area HOT 1
- SQL-Error on fresh installation on Raspberry HOT 3
- Web GUI add domain to whitelist / blacklist is added only in default group HOT 1
- No log in for a week HOT 7
- admin/scripts/pi-hole/php/customdns.php and admin/dns_records.php: CORS is something the browser handles, not the server HOT 3
- CNAME records not imported to v6 from v5 Teleport file HOT 11
- /admin/scripts/pi-hole/php/customdns.php persistently fails even with password disabled HOT 2
- Update Gravity page is redirect depending on the settings level HOT 1
- An entry in the blacklist is not being blocked HOT 10
- Mapping 2 MAC addresses to the same IP address not displayed correctly on web HOT 2
- "Total queries over last 24 hours" empty HOT 4
- NAN on Admin Stats with Multiple Containerized Pihole Admin Consoles HOT 15
- Glow effect in "Total Queries" box result in blurry text. HOT 5
- Universal Time Displayed in Firefox Instead of Local Time HOT 3
- Teleporter import adds "default" to all domainlist_by_group.json entries. HOT 1
- Disabled Blocking doesn't get resumed after timer expiry. HOT 4
- Custom DNS does not handle multiple whitespace in custom.list HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from adminlte.