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

hmac GH issues# 600 fix #602

Merged
merged 1 commit into from
Oct 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions kong/plugins/hmac-auth/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local ngx_parse_time = ngx.parse_http_time
local ngx_sha1 = ngx.hmac_sha1
local ngx_set_header = ngx.req.set_header
local ngx_set_headers = ngx.req.get_headers
local ngx_log = ngx.log

local split = stringy.split

Expand All @@ -28,13 +29,13 @@ local function retrieve_hmac_fields(request, headers, header_name, conf)
if authorization_header then
local iterator, iter_err = ngx_gmatch(authorization_header, "\\s*[Hh]mac\\s*username=\"(.+)\",\\s*algorithm=\"(.+)\",\\s*headers=\"(.+)\",\\s*signature=\"(.+)\"")
if not iterator then
ngx.log(ngx.ERR, iter_err)
ngx_log(ngx.ERR, iter_err)
return
end

local m, err = iterator()
if err then
ngx.log(ngx.ERR, err)
ngx_log(ngx.ERR, err)
return
end

Expand Down Expand Up @@ -151,6 +152,9 @@ function _M.execute(conf)

-- validate signature
local secret = load_secret(hmac_params.username)
if not secret then
responses.send_HTTP_FORBIDDEN(SIGNATURE_NOT_VALID)
end
hmac_params.secret = secret.secret
if not validate_signature(ngx.req, hmac_params, headers) then
ngx.ctx.stop_phases = true -- interrupt other phases of this request
Expand Down
92 changes: 91 additions & 1 deletion spec/plugins/hmac-auth/access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,97 @@ describe("Authentication Plugin", function()
it("should pass with GET with request-line", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1", headers="date content-md5 request-line",signature="]]..encodedSignature..[["]]
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1", headers="date content-md5 request-line", signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
assert.equal(200, status)
local parsed_response = cjson.decode(response)
assert.equal("hello", parsed_response.headers["authorization"])
end)

it("should not pass with GET with wrong username", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bobb", algorithm="hmac-sha1", headers="date content-md5 request-line", signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with username blank", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="", algorithm="hmac-sha1", headers="date content-md5 request-line", signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with username missing", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac algorithm="hmac-sha1", headers="date content-md5 request-line", signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with wrong hmac headers field name", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1", header="date content-md5 request-line", signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with wrong hmac signature field name", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1", headers="date content-md5 request-line", signatures="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with malformed hmac signature field", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1" headers="date content-md5 request-line",signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should not pass with GET with malformed hmac headers field", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob", algorithm="hmac-sha1" headers=" date content-md5 request-line",signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
local body = cjson.decode(response)
assert.equal(403, status)
assert.equal(SIGNATURE_NOT_VALID, body.message)
end)

it("should pass with GET with no space or space between hmac signatures fields", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob",algorithm="hmac-sha1", headers="date content-md5 request-line",signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
assert.equal(200, status)
local parsed_response = cjson.decode(response)
assert.equal("hello", parsed_response.headers["authorization"])
end)

it("should pass with GET with wrong algorithm", function()
local date = os.date("!%a, %d %b %Y %H:%M:%S GMT")
local encodedSignature = base64.encode(hmac_sha1_binary("secret", "date: "..date.."\n".."content-md5: md5".."\nGET /request? HTTP/1.1"))
local hmacAuth = [["hmac username="bob",algorithm="hmac-sha256", headers="date content-md5 request-line",signature="]]..encodedSignature..[["]]
local response, status = http_client.get(STUB_GET_URL, {}, {host = "hmacauth.com", date = date, ["proxy-authorization"] = hmacAuth, authorization = "hello", ["content-md5"] = "md5"})
assert.equal(200, status)
local parsed_response = cjson.decode(response)
Expand Down