Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.

Conversation

@mmattel
Copy link
Contributor

@mmattel mmattel commented Jun 3, 2016

These are small improvements for the nginx setup:

  • replace deny; by return 404; break; which equals .htaccess [R=404,L]
  • add a optional location statement to supress error logging of .ocdata

Referncing the discussion in owncloud/core#24968 (comment)

@josh4trunks Your feedback is more than welcomed 😄

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @carlaschroder to be a potential reviewer

@josh4trunks
Copy link
Contributor

Does deny all normally gives a 403? I guess this makes sense to match what apache does, though I've never seen it done this way. I think this is to do some sort of obfuscation for web scanners, can anyone confirm?

Are you sure adding your /data/.ocdata location doesn't allow browsing to that location now? Can you explain why owncloud is browsing here?
Also, it would be more efficient to use location = in this case.

@ghost
Copy link

ghost commented Jun 3, 2016

I say stay with deny all which throws the correct 403 = Forbidden instead of the wrong 404 = Not found.

The access to the .ocdata shouldn't be done by ownCloud via the Web so normally you shouldn't get a log message about that in your logs.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 3, 2016

To block the data directory with deny or return 404 does principly the same and works.

But there are two diffeences:

  1. deny returns a 403 which shows on the browser screen forbidden (yes it´s present but you do not have access to) while return 404 shows not found (maybe present or not, but no access anyways). Apache shows a 404 response, nginx should do the same.
  2. deny and return 404 break behave slightly different, see next

owncloud uses the access attempt via the browser to /data/.ocdata to check if the data directory is accessible or not. In case it is, it warns you on the admin page (your data directory is accessible from the internet...). This check is performed everytime you access or reload the admin page. The "bad" thing about that is, that everytime you get nginx error log entry because of the forbidden rule.
Here comes the second difference between deny and return 404 break.
Having deny for data, you can not use another location statement to supress error logging. I tried and it just does not work. But when you use return 404 break, it works and you can supress the access forbidden error logging. In case the file would not be present, it would at least log that it was not found which helps debugging.

Your statement regarding location = is correct, I tried it, it still works and will change that immediately.

@mmattel mmattel force-pushed the nginx_location_update branch from b200962 to a270242 Compare June 3, 2016 17:45
@ghost
Copy link

ghost commented Jun 3, 2016

If the return and break is needed then it should be 403 and not 404 from my PoV. There is no need to do obfuscating here.

For the test of the protected datadir the /data/htaccesstest.txt is used:

https://github.com/owncloud/core/blob/c0a19ecd2d4878684a135764e9cf4a175e5f591e/lib/private/legacy/util.php#L1150

where an hint at the docs already exists how to suppress that message.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 3, 2016

Then the Apache rule has to be changed. I just made that the webservers behave equal !
IMHO I prefer 404, because this makes guessing and attacking harder.

./ocdata, just give this a try and you see that you get the result as I described it. I have this message since the day when .ocdata has been introduced. But this is anyway not the point. I want to supress the access denied message because it is only filling up the log unnecessarily.

@josh4trunks
Copy link
Contributor

This is a policy decision; we should ask the OC security guy to weigh in, they might know why 404 is used here instead of 403.

I vaguely remember someone mentioning a scanner that thinks 404's are more secure. We should confirm if that still matters and...

  • if so go with 404, even though it doesn't seem right to me.
  • if not, go with the usual deny. we might be able to improve apache further by not even using rewrites
    http://stackoverflow.com/a/4352799

@LukasReschke
Copy link
Contributor

Can't quite remember why 403 or 404 is used here. Not an NGINX expert myself. Sorry :-)

@josh4trunks
Copy link
Contributor

Thanks Luke, guess we gotta figure out where to contribute now, lol

The decision isn't specific to nginx, we're just trying to figure out why it was done this way in apache, and make sure apache/nginx match.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 4, 2016

To consider:

  • 403 reports Forbidden what means that a user can think that the path entered is valid but he has no access rights.
  • 404 reports Not Found what means that a user does not know if the path entered is valid or not

Technically both are correct denying acces, but from a security POV, 404 is much better.

@LukasReschke independent where you contribute to, I would like to hear your expertise 😄

@ghost
Copy link

ghost commented Jun 4, 2016

./ocdata, just give this a try and you see that you get the result as I described it. I have this message since the day when .ocdata has been introduced. But this is anyway not the point. I want to supress the access denied message because it is only filling up the log unnecessarily.

There is no single call to the .ocdata via a GET request:

https://github.com/owncloud/core/search?l=php&q=ocdata&utf8=%E2%9C%93

If you're getting this message (i don't get it btw. even without those rules) there is something fishy in your environment.

Technically both are correct denying acces, but from a security POV, 404 is much better.

There is no security benefit from using 404. The structure of ownCloud are known and publicly available.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 6, 2016

@RealRancor
I run 9.0.2 and my environment has no bad setup nor something is fishy, setup was made following the documentation...
I tried with 3 different browsers just refreshing the admin page and logging the site´s access log.
You find in EVERY browser access a log entry with GET /data/.ocdata.
This request comes from the code and not from somewhere else, wherever it is created - it does not matter !! It is ok that this access happens, but it is not necessary to log it all the times in the error log because of the deny/404(403) rule as this is an oc internal thing and not a user entered string into the browser...

Security is not definded by code or structures beeing public available. There are dev teams like us, experienced folks and ordinary users. 404 is correct for the users (majority) and therefore it is correct in .htaccess - nginx should just do the same.

Opera 37:

"GET /settings/admin HTTP/2.0" 200 48401 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /core/js/oc.js?v=b3993661e6b9f78e1c9e9ed3539fc694 HTTP/2.0" 200 3270 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /apps/files_external/globalstorages HTTP/2.0" 200 913 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /ocs/v2.php/apps/notifications/api/v1/notifications?format=json HTTP/2.0" 200 638 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"PROPFIND /remote.php/webdav HTTP/2.0" 207 1708 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /cron.php HTTP/2.0" 200 555 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /data/.ocdata HTTP/2.0" 404 2788 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"POST /displaynames HTTP/2.0" 200 567 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /apps/files_external/globalstorages/2 HTTP/2.0" 200 926 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /heartbeat HTTP/2.0" 200 531 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"PUT /apps/files_external/globalstorages/2 HTTP/2.0" 200 926 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"
"GET /settings/ajax/checksetup HTTP/2.0" 200 1167 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 OPR/37.0.2178.54"

IE 11:

"GET /settings/admin HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /settings/admin HTTP/1.1" 200 48512 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /settings/admin HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /core/js/oc.js?v=b3993661e6b9f78e1c9e9ed3539fc694 HTTP/1.1" 200 2775 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /ocs/v2.php/apps/notifications/api/v1/notifications?format=json HTTP/1.1" 200 85 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /apps/files_external/globalstorages HTTP/1.1" 200 405 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"PROPFIND /remote.php/webdav HTTP/1.1" 207 1334 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /heartbeat HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /cron.php HTTP/1.1" 200 31 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /data/.ocdata HTTP/1.1" 404 2459 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /apps/files_external/globalstorages/2 HTTP/1.1" 200 418 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"POST /displaynames HTTP/1.1" 200 60 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"PUT /apps/files_external/globalstorages/2 HTTP/1.1" 200 418 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
"GET /settings/ajax/checksetup HTTP/1.1" 200 659 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"

Chrome 50:

"GET /settings/admin HTTP/2.0" 200 48930 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /core/js/oc.js?v=b3993661e6b9f78e1c9e9ed3539fc694 HTTP/2.0" 200 3270 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /apps/files_external/globalstorages HTTP/2.0" 200 913 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /ocs/v2.php/apps/notifications/api/v1/notifications?format=json HTTP/2.0" 200 638 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /cron.php HTTP/2.0" 200 555 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /heartbeat HTTP/2.0" 200 531 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"PROPFIND /remote.php/webdav HTTP/2.0" 207 1708 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /data/.ocdata HTTP/2.0" 404 2788 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"POST /displaynames HTTP/2.0" 200 567 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /apps/files_external/globalstorages/2 HTTP/2.0" 200 926 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"PUT /apps/files_external/globalstorages/2 HTTP/2.0" 200 926 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
"GET /settings/ajax/checksetup HTTP/2.0" 200 1167 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"

@ghost
Copy link

ghost commented Jun 6, 2016

@mmattel If there is such an access via GET then we need to create a new bugreport in core. This access doesn't make any sense as mostly every webserver setup out there is blocking an access to "dot" files.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 6, 2016

Sorry - pls stop. Everything is fine with the attempt from core accessing /data/.ocdata via the browser because this is the security check for the data directory and it is done when accessing the admin page. You can see this clearly on the logs above. (htaccesstest.txt is legacy code. see lib/private/legacy/util.php)

This PR is about aligning nginx to Apache and adds a documentation when an admin wants to suppress access denied .ocdata error log messages.

@ghost
Copy link

ghost commented Jun 6, 2016

Sorry, this is plainly wrong. The .ocdata is NOT used for the security check for the data directory als already mentioned above. It makes NO sense to access the .ocdata via the browser so this needs to be fixed in core if the access is done.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 6, 2016

If you are so sure, give it a try, allow access to the data directory, access the admin page and watch all the messages. Drill it down, allow access to /data but restrict to /data/.ocdata and watch again.

@ghost
Copy link

ghost commented Jun 6, 2016

If it is used then another bugreport is needed in core. Access to .ocdata for proofing if the datadir is protected is no proof if it is protected. If .ocdata is used this is a huge security issue.

@mmattel
Copy link
Contributor Author

mmattel commented Jun 6, 2016

Feel free to investigate and write a core issue ...

@ghost
Copy link

ghost commented Jun 6, 2016

Already done: owncloud/core#24987

@ghost
Copy link

ghost commented Jun 30, 2016

@mmattel The .ocdata part can be removed as oC 9.0.3+ is now correctly checking for htaccess.txt again: owncloud/core#25045

@mmattel mmattel force-pushed the nginx_location_update branch from a270242 to e5334f6 Compare July 13, 2016 16:18
@mmattel
Copy link
Contributor Author

mmattel commented Jul 13, 2016

@RealRancor done. I did a reset to master because of other already merged PR´s and added the changes accordingly so things are clean now. Thanks for your support, ready to merge (from my pov).

@ghost
Copy link

ghost commented Jul 14, 2016

@mmattel Just stumbled over another thing:

return code
Stops processing and returns the specified code to a client. The non-standard code 444 closes a connection without sending a response header.

http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return

So is the break; after the return needed at all?

@mmattel mmattel force-pushed the nginx_location_update branch from e5334f6 to 7d63c82 Compare July 14, 2016 17:15
@mmattel
Copy link
Contributor Author

mmattel commented Jul 14, 2016

@RealRancor When I was reading the docs I found the same, but I also found examples on google where folkes used break in addition. Originally I added this for beeing on the secure side. Now digging deeper and also did test with and without again, I removed the break statement and I can tell that everything is working as expected 😄

@ghost
Copy link

ghost commented Jul 14, 2016

👍 from my side (but personally i keep the deny all in my config 😀 )

@mmattel mmattel merged commit fb87565 into master Jul 14, 2016
@mmattel mmattel deleted the nginx_location_update branch July 14, 2016 17:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants