-
Notifications
You must be signed in to change notification settings - Fork 83
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
Handle empty URL parameter values #1917
Conversation
end | ||
|
||
table.insert(queryParams, paramName .. "=" .. paramValue) | ||
if paramName and paramName ~= '' and paramValue then -- Check if paramName and paramValue exist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't paramName ~= ''
only match a blank paramName
, which is the opposite of what we want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if paramName and paramValue then -- this should be enough we dont need to check paramName to be empty is that okay @danielhoherd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like that would work. the regex specifies that the paramName must be at least one character.
@@ -48,14 +48,16 @@ data: | |||
|
|||
-- Split the query string into individual parameters | |||
for param in string.gmatch(queryString, "([^&]+)") do | |||
local paramName, paramValue = string.match(param, "(.+)=(.+)") | |||
local paramName, paramValue = string.match(param, "(.+)=(.*)") -- Allow empty paramValue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should tighten this regex up a bit. Here's at least one example:
local paramName, paramValue = string.match(param, "(.+)=(.*)") -- Allow empty paramValue | |
local paramName, paramValue = string.match(param, "([^=]+)=(.*)") -- Allow empty paramValue |
I wonder if there is a function we can use to do this, because the regex to reliably capture the parameters could be complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't causing any issue so we didn't optimize those
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like we can use ngx.req.get_uri_args()
to get a table of param k=v pairs https://github.com/openresty/lua-nginx-module#ngxreqget_uri_args
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should not use a regex to do this since there's the built-in function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me try to optimize the existing code and update the PR tomorrow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pgvishnuram i think this will do it:
# redact sensitive data in the URI
set_by_lua_block $request_uri_masked {
local requestUri = ngx.var.requestUri
if requestUri == nil or requestUri == '' then
return requestUri
end
local paramsToMask = {
token = true
}
local args = ngx.req.get_uri_args()
-- redact all paramsToMask, pass through anything else
for key, val in pairs(args) do
if paramsToMask[key] then
if val and val ~= '.' then -- match only values that have at least one character
val = "**REDACTED**"
end
args[key] = val
end
end
-- Find the position of the original query string
local qsStart = string.find(requestUri, "?")
-- Replace the original query string with a redacted version
local redactedQs = ngx.encode_args(args)
local masked_url = string.sub(requestUri, 1, qsStart) .. "?" .. redactedQs .. "#edited"
return masked_url
}
i can't add it as a suggestion though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to bang on this and try to figure it out. It's not quite working yet. The blank values are still causing a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been banging on this and I've run into a bunch of edge cases and can't solve them all. I've never done lua before, so that's part of my problem.
One case we should cover is &foo
([^?&]+)=([^&]*)
solves the &root=
case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After digging banging on the code and digging through the API reference https://github.com/openresty/lua-nginx-module#nginx-api-for-lua I don't see any good way to do the referer other than regex because there is no function to parse the arguments from URL string. All of the URL parsing functions do not take a URL, they imply the URL that is part of the current request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set_by_lua_block $request_uri_masked {
local args = ngx.req.get_uri_args()
local paramsToMask = {
token = true
}
local maskedArgs = {}
for paramName, paramValue in pairs(args) do
-- Check if the parameter should be masked
if paramsToMask[paramName] then
paramValue = "##REDACTED##" -- Replace the value with REDACTED
end
if paramName and paramValue then -- Check if paramName and paramValue exist
table.insert(maskedArgs, paramName .. "=" .. paramValue)
end
end
local maskedQueryString = table.concat(maskedArgs, "&")
local maskedUrl = ngx.var.uri
if maskedQueryString ~= "" then
maskedUrl = maskedUrl .. "?" .. maskedQueryString
end
return maskedUrl
}
Co-authored-by: Daniel Hoherd <daniel.hoherd@gmail.com>
Co-authored-by: Daniel Hoherd <daniel.hoherd@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. We've done a lot of back and forth and debugging on this and these changes are good for now. We have more things to tweak in the future if we choose to do so.
Description
Resolves an issue when a empty query param is passed or sent its being handled properly rather ending with 500 internal server error
Related Issues
https://github.com/astronomer/issues/issues/5683
Testing
Merging
cherry-pick to release-0.30, 0.32