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

Key authentication plugin is not protecting the APIs from Apache-HttpClient 4 #408

Closed
Hughiegao opened this issue Jul 16, 2015 · 11 comments
Closed

Comments

@Hughiegao
Copy link

I set up a kong server with keyauth following the http://getkong.org/plugins/key-authentication

then I use Jmeter to make a Apache-HttpClient 4.* HTTP request to call the Kong APIs with a wrong apikey or not apikey. And it pass the keyauth check like there is no protection.

Protected User-Agent:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36
Apache-HttpClient 3.*

Not Protected User-Agent:
Apache-HttpClient 4.*

@thibaultcha
Copy link
Member

Hi @Hughiegao,

This is what I just ran on my local Kong.

Adding an API:

$ http :8001/apis name=mockbin public_dns=mockbin.com target_url=http://mockbin.com
HTTP/1.1 201 Created
Date: Fri, 17 Jul 2015 22:12:52 GMT
Server: kong/0.4.0

{
    "created_at": 1437171172000,
    "id": "1905e78b-2e92-4160-c143-571915f0cac9",
    "name": "mockbin",
    "public_dns": "mockbin.com",
    "target_url": "http://mockbin.com/"
}

Adding a plugin on top of it (keyauth):

$ http :8001/apis/mockbin/plugins name=keyauth
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Date: Fri, 17 Jul 2015 22:13:13 GMT
Server: kong/0.4.0

{
    "api_id": "1905e78b-2e92-4160-c143-571915f0cac9",
    "created_at": 1437171193000,
    "enabled": true,
    "id": "26aff2ea-0c21-48a2-c8f3-52ca949b4b29",
    "name": "keyauth",
    "value": {
        "hide_credentials": false,
        "key_names": [
            "apikey"
        ]
    }
}

Making a request through Kong:

$ http :8000 Host:mockbin.com
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Date: Fri, 17 Jul 2015 22:13:42 GMT
Server: kong/0.4.0

{
    "message": "No API key found in headers or querystring"
}

And with a wrong credential:

http ':8000/?apikey=foo' Host:mockbin.com
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Date: Fri, 17 Jul 2015 22:17:15 GMT
Server: kong/0.4.0

{
    "message": "Invalid authentication credentials"
}

As you can see the request doesn't go through. Could you share your setup and/or compare it with the one I just posted so we can know what's happening, fix it or eventually clear the confusion if there was any?

Thanks

Note: if you run this on Kong 0.3.2, the request without credentials will respond 403 instead of 401.

@thibaultcha thibaultcha changed the title Key authentication plugin is not protect the APIs from Apache-HttpClient 4 require Key authentication plugin is not protecting the APIs from Apache-HttpClient 4 Jul 17, 2015
@Hughiegao
Copy link
Author

It is running at a CentOS 6 VM

Adding an API:

curl –X POST: http://localhost:8001/apis/ --data "name=mockbin" --data "path=/mockbin/" --data "strip_path=false" --data "target_url=http://mockbin.com"

curl: (6) Couldn't resolve host '–X'
curl: (6) Couldn't resolve host 'POST:'
{"path":"\/mockbin\/","target_url":"http:\/\/mockbin.com\/","id":"e1bd7009-6da7-4886-c8cf-ed7452f3bf66","created_at":1437486095000,"name":"mockbin","strip_path":false}

Adding a plugin on top of it (keyauth):

curl -X POST http://localhost:8001/apis/mockbin/plugins  --data "name=keyauth"  --data "value.key_names=apikey"

{"api_id":"e1bd7009-6da7-4886-c8cf-ed7452f3bf66","value":{"key_names":["apikey"],"hide_credentials":false},"id":"79f323a3-d9af-4468-c467-f524dabc51bb","enabled":true,"created_at":1437486116000,"name":"keyauth"}

Making a request through Kong:

curl localhost:8000/mockbin/123
{"message":"Invalid authentication credentials"}

Making a request through Kong with right key:
I believe "Cannot GET /mockbin/123 is the right message"

curl localhost:8000/mockbin/123 -H "apikey:123"
Cannot GET /mockbin/123

Making a request through Kong with header of "Expect:100-continue"
HERE IS THE ISSUES, I can reproduce with curl

curl localhost:8000/mockbin/123 -H "Expect:100-continue"
Cannot GET /mockbin/123

I believe the "Expect:100-continue" is the problem, what it did is allow a client to send a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. Maybe that is how it pass the Kong keyauth check?
more doc with http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
8.2.3 Use of the 100 (Continue) Status.

Thanks you to look it up for me.

@subnetmarco
Copy link
Member

I do confirm that this has been implemented as a feature (https://github.com/Mashape/kong/blob/master/kong/plugins/keyauth/access.lua#L14-L17) because it was breaking a specific use case, which it should be client-side HTML forms for file uploads.

Let me investigate.

@Hughiegao
Copy link
Author

skip_authentication? It looks like security breach for me. :)

Thank you for the investigation.

@subnetmarco
Copy link
Member

Okay, I remember now why this check has been implemented.

The Expect: 100-continue request is sent when the client is trying to validate the prerequisites of the request. This is primarily used when making POST requests with multipart/form-data bodies, to validate that the size of the payload can be accepted by the final API.

Because of the nature of 100-continue, the body is not being sent (otherwise it would defeat it's purpose). The Key Authentication plugin accepts the authentication key to be in the header, in the querystring or in the body. In the latter case when credentials are being sent in the body, because 100-continue doesn't send any body, the request will always fail because the authentication parameter will never be submitted.

So Kong skips the authentication for Expect: 100-continue requests, but it will properly enforce it on the subsequent request is the server doesn't deny the prerequisites.

@Hughiegao
Copy link
Author

The problem is with this "Expect: 100-continue", the KONG don't seem to deny the subsequent request. I can't show the target_url that I have. But, It doesn't need the apikey when you do "Expect: 100-continue" request. Maybe "POST requests with multipart/form-data" bodies is working, BUT post requests with application/json and Expect: 100-continue skipping authentication on both Expect: 100-continue requests and subsequent request! Can you run a test with it? Thanks

@Hughiegao
Copy link
Author

To prove what I mean, I create a mockbin for it.

http://mockbin.com/bin/14d814d0-ff59-4072-bbd3-c4f43720423a
All it did is return a message of "You pass the Key Authentication check!"

It is running at a CentOS 6 VM

Adding an API:

curl –X POST: http://localhost:8001/apis/ --data "name=mockbin" --data "path=/mockbin/" --data "strip_path=false" --data "target_url=http://mockbin.com/bin/14d814d0-ff59-4072-bbd3-c4f43720423a"


{"path":"\/mockbin\/","target_url":"http:\/\/mockbin.com\/","id":"e1bd7009-6da7-4886-c8cf-ed7452f3bf66","created_at":1437486095000,"name":"mockbin","strip_path":false}

Adding a plugin on top of it (keyauth):

curl -X POST http://localhost:8001/apis/mockbin/plugins  --data "name=keyauth"  --data "value.key_names=apikey"

{"api_id":"e1bd7009-6da7-4886-c8cf-ed7452f3bf66","value":{"key_names":["apikey"],"hide_credentials":false},"id":"79f323a3-d9af-4468-c467-f524dabc51bb","enabled":true,"created_at":1437486116000,"name":"keyauth"}

Adding a consumer

curl -X POST http://localhost:8001/consumers --data "username=hughiegao"

{"username":"hughiegao","created_at":1439845929000,"id":"bebe228d-f536-4251-c215-356cb7af522b"}

Adding a key=123 to this consumer

curl -X POST http://localhost:8001/consumers/bebe228d-f536-4251-c215-356cb7af522b/keyauth --data "key=123"

{"created_at":1439846176000,"consumer_id":"bebe228d-f536-4251-c215-356cb7af522b","key":"123","id":"c773224f-fc2d-4985-c929-7c21b7ce9c02"}

Making a request through Kong:

curl localhost:8000/mockbin/123
{"message":"No API key found in headers or querystring"}

Making a request through Kong with right key:

curl localhost:8000/mockbin/123 -H "apikey:123"
You pass the Key Authentication check!

Making a request through Kong with header of "Expect:100-continue"
HERE IS THE ISSUES, I can reproduce with curl

I DON'T NEED A API KEY FOR IT!

curl localhost:8000/mockbin/123 -H "Expect:100-continue"
You pass the Key Authentication check!

The problem is if I have a "Expect:100-continue" inside my header, it will always skip the key authentication.

@subnetmarco
Copy link
Member

@Hughiegao I decided to go ahead and remove that exception, so that the authentication parameter is always required. This will be effective starting from the next version.

@tyiss
Copy link

tyiss commented Aug 26, 2015

@thefosk
Isn't this should be applied for basicauth plugin aswell ? ( i can prepare a pr for it).

@Hughiegao
Copy link
Author

@thefosk
Thank you for the update.

@subnetmarco
Copy link
Member

This has been fixed on both key auth and basic auth.

hutchic added a commit that referenced this issue Jun 10, 2022
…nges. Drop jessie (#408)

* fix(ssl): adjust our base images to be more resiliant against ssl changes

* chore(jessie): drop jessie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants