owncloud / brute_force_protection

Brute-force protection app for ownCloud
GNU General Public License v2.0
6 stars 5 forks source link

500 status "Too many failed login attempts" #112

Closed phil-davis closed 4 years ago

phil-davis commented 4 years ago

1) Have brute_force_protection app enabled with the default 5 minute... settings. 2) Do some API access with an invalid password and OCS V2:

phil@JankariTech-OptiPlex-3050:~$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Host: 172.17.0.1:8080
< Date: Thu, 02 Apr 2020 06:52:22 GMT
< Connection: close
< X-Powered-By: PHP/7.3.16-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=eXxdDKjSEV%2FK1Lf5T1L0HIFEvw9iV3x0uOsTIia0lQEK6crDBC5iGsbf27qbAsETjCDdcTRyMOid7eyO3Djf0mBtQaBv%2FuS9QCHn6Ry2t4rGnRG6WpvaBowAGrv82aY6; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: oc98ayu6e5hn=15avs1vr98dnpisp7vbhilbi9b; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 213
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>997</statuscode>
  <message>Unauthorised</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0
phil@JankariTech-OptiPlex-3050:~$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< Host: 172.17.0.1:8080
< Date: Thu, 02 Apr 2020 06:52:32 GMT
< Connection: close
< X-Powered-By: PHP/7.3.16-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=RZNeYYxsi42MBRGjCvRqCa5nN%2BtPqUvDcCJv6PSgzT8P0CNGQp%2BVD0AVGCzHbjarx%2B27FGKNq%2BqO0Itpw9dM%2BkrPK0F3QVvZp7iuqu6PmZNUhS4Amblv63GcCukJYg7c; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: oc98ayu6e5hn=rs1qu8000ipbgr4u5k3ccou5iu; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 257
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>500</statuscode>
  <message>Too many failed login attempts. Try again in  5 minutes.</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0

The server has:

Server output:
[Thu Apr  2 12:37:22 2020] Login failed: 'admin' (Remote IP: '172.20.10.9')
[Thu Apr  2 12:37:22 2020] Login failed: 'admin' (Remote IP: '172.20.10.9')
[Thu Apr  2 12:37:22 2020] 172.20.10.9:36116 [401]: /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123
[Thu Apr  2 12:37:32 2020] Login failed: 'admin' (Remote IP: '172.20.10.9')
[Thu Apr  2 12:37:32 2020] 172.20.10.9:36122 [500]: /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123

When the failed login limit is reached the response is a HTTP 500 status and OCS 500 status.

That should never happen. Probably it should still be an HTTP 401 status and OCS 997 status.

It is also a bit surprising to me that a message is returned to a client that is providing invalid authentication, and that the message contains text that gives them a clue about how long to back-off for in their brute-force attempts.

phil-davis commented 4 years ago

I noticed this when running automated acceptance tests from core with the brute_force_protection app enabled. e.g. tests/acceptance/features/apiAuthOCS/ocsDELETEAuth.feature (and probably the other feature files in that test suite which check the responses to invalid auth on various OCS end-points)

phil-davis commented 4 years ago

Do some API access with an invalid password and OCS V1:

phil@JankariTech-OptiPlex-3050:~$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Host: 172.17.0.1:8080
< Date: Thu, 02 Apr 2020 07:03:08 GMT
< Connection: close
< X-Powered-By: PHP/7.3.16-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=ZGebOmxSMZywBX%2FCUnANXgeLq9wWRS0Io7WZ7QrzaX1rb5owSC8F0M%2BuMEEOKuoCi7om8diy%2FUrV0FRZRcmJvrlfy6DH1GUGQ4sBT81ad1RLqqRgko0%2Bs8yP3aI5NWBF; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: oc98ayu6e5hn=gsrsj4jvmr22cegkmccpn5n5n6; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 213
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>997</statuscode>
  <message>Unauthorised</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0
phil@JankariTech-OptiPlex-3050:~$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Host: 172.17.0.1:8080
< Date: Thu, 02 Apr 2020 07:03:12 GMT
< Connection: close
< X-Powered-By: PHP/7.3.16-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=CySC%2FnCTRVEVehngAo8jNTJ5qP0%2BGeSUa1PVTwW6OhXUnoUJSBB0VtCjpIAfcfWGCoQpNLJw44DWMqaJAmoRh48eqFrJFt95lVfhyNNz8bB7RBlRHjZN2k2A4RlatRh3; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: oc98ayu6e5hn=qq8r4ha8tmfvh3qdaq2b6a8bhv; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 257
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>996</statuscode>
  <message>Too many failed login attempts. Try again in  5 minutes.</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0

The ordinary response is HTTP 401 and OCS 997 Unauthorized - good. This is the same as OCS V2, which is nice.

When Brute Force Protection kicks in, the HTTP status becomes 200 and OCS 996. That is surprising.

IMO the HTTP status should stay 401.

Then there is the same issue as for OCS V2 - a client is providing invalid auth and a message comes back giving them a clue about how long to back-off for in their brute-force attempts.

DeepDiver1975 commented 4 years ago

I cannot reproduce http status code 500 .... :confused:

phil-davis commented 4 years ago

It happens for me just once, after a few API calls with wrong password I get a response with 500 and "Too many failed login attempts...". Then when I keep repeating the API call I get the usual 401 "Unauthorized".

I think that after about 5 minutes, when the timer runs out, I can then do a few API calls again and get a 500 once.

So I think it happens only on the initial time that brute force protection kicks in.

DeepDiver1975 commented 4 years ago

Do you have anything of interest in the server log when this 500 happens? 500 should always result in some error log entry ...... :man_shrugging:

phil-davis commented 4 years ago

@DeepDiver1975 I just did exactly this:

phil@phil-OptiPlex-3050:~/git/owncloud/core$ php occ a:l -e
Enabled:
  - comments: 0.3.0
  - configreport: 0.2.0
  - dav: 0.5.0
  - enterprise_key: 0.2.0
  - federatedfilesharing: 0.5.0
  - federation: 0.1.0
  - files: 1.5.2
  - files_external: 0.7.1
  - files_sharing: 0.12.0
  - files_texteditor: 2.3.0
  - files_trashbin: 0.9.1
  - files_versions: 1.3.0
  - notifications: 0.5.0
  - provisioning_api: 0.5.0
  - systemtags: 0.3.0
  - testing: 0.1.0
  - updatenotification: 0.2.1
phil@phil-OptiPlex-3050:~/git/owncloud/core$ php occ a:e brute_force_protection
brute_force_protection enabled
phil@phil-OptiPlex-3050:~/git/owncloud/core$ rm data/owncloud.log 
phil@phil-OptiPlex-3050:~/git/owncloud/core$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Host: 172.17.0.1:8080
< Date: Tue, 21 Apr 2020 08:59:30 GMT
< Connection: close
< X-Powered-By: PHP/7.2.30-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=5dUsdgHCehZ3Ye5jpzyISM90sn3TxLNmefYDyaxZSaPb0UCFaftw%2BK8sQZgmOsZFWPEp6tDlYAiN8cxZbpMLjQE9JEJSe0%2BvYPYyyNaavABL0NYeHeq7%2Fv1uMbKxyqvh; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: ocr9ioians8b=t4h8sbjkgof7kiq4eaaoobjk11; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 213
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>997</statuscode>
  <message>Unauthorised</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0
phil@phil-OptiPlex-3050:~/git/owncloud/core$ cat data/owncloud.log 
{"reqId":"37nUpw8INCq5Qaw6RXg4","level":2,"time":"2020-04-21T08:59:30+00:00","remoteAddr":"10.49.210.9","user":"--","app":"core","method":"DELETE","url":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/remote_shares\/pending\/123","message":"Login failed: 'admin' (Remote IP: '10.49.210.9')"}
{"reqId":"37nUpw8INCq5Qaw6RXg4","level":2,"time":"2020-04-21T08:59:30+00:00","remoteAddr":"10.49.210.9","user":"--","app":"core","method":"DELETE","url":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/remote_shares\/pending\/123","message":"Login failed: 'admin' (Remote IP: '10.49.210.9')"}
phil@phil-OptiPlex-3050:~/git/owncloud/core$ 

wait 15 seconds and:

phil@phil-OptiPlex-3050:~/git/owncloud/core$ curl -v -u admin:wrong -X DELETE http://172.17.0.1:8080/ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123
*   Trying 172.17.0.1...
* TCP_NODELAY set
* Connected to 172.17.0.1 (172.17.0.1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> DELETE /ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/123 HTTP/1.1
> Host: 172.17.0.1:8080
> Authorization: Basic YWRtaW46d3Jvbmc=
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< Host: 172.17.0.1:8080
< Date: Tue, 21 Apr 2020 08:59:45 GMT
< Connection: close
< X-Powered-By: PHP/7.2.30-1+ubuntu18.04.1+deb.sury.org+1
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=WSG%2FnzLZoFT4eWzkaVpYk5JcHxXIO3fsoCeJB0rgVVeDCZ%2Bmi4HyQZ%2F7kriOLqbHHYLXhzNZa%2B9Rw7x%2FkEEzfTncvokgtmMGS1YZY2hsczGTf2jTo7tzjhcMrFIKTrv7; path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Robots-Tag: none
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Set-Cookie: ocr9ioians8b=b6utkq9r4bn0msge2389celnme; path=/; HttpOnly
< Cache-Control: no-cache, no-store, must-revalidate
< Content-Type: application/xml; charset=utf-8
< Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
< Content-Length: 257
< 
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>500</statuscode>
  <message>Too many failed login attempts. Try again in  5 minutes.</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
* Closing connection 0
phil@phil-OptiPlex-3050:~/git/owncloud/core$ cat data/owncloud.log 
{"reqId":"37nUpw8INCq5Qaw6RXg4","level":2,"time":"2020-04-21T08:59:30+00:00","remoteAddr":"10.49.210.9","user":"--","app":"core","method":"DELETE","url":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/remote_shares\/pending\/123","message":"Login failed: 'admin' (Remote IP: '10.49.210.9')"}
{"reqId":"37nUpw8INCq5Qaw6RXg4","level":2,"time":"2020-04-21T08:59:30+00:00","remoteAddr":"10.49.210.9","user":"--","app":"core","method":"DELETE","url":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/remote_shares\/pending\/123","message":"Login failed: 'admin' (Remote IP: '10.49.210.9')"}
{"reqId":"iMDKP4YbBwbHGKoIH7y2","level":2,"time":"2020-04-21T08:59:45+00:00","remoteAddr":"10.49.210.9","user":"--","app":"core","method":"DELETE","url":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/remote_shares\/pending\/123","message":"Login failed: 'admin' (Remote IP: '10.49.210.9')"}
phil@phil-OptiPlex-3050:~/git/owncloud/core$ 

The first request ends up with 2 entries in owncloud.log but the second request only adds 1 entry to owncloud.log - maybe there is a clue there? I guess the ffirst request should have only loggged the login fail once?

micbar commented 4 years ago

Fixed, Closing

karakayasemi commented 4 years ago

@issue-112 annotation still exists in some acceptance test scenarios. This issue will be resolved with https://github.com/owncloud/core/pull/37948