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

Handle empty URL parameter values #1917

Merged
merged 4 commits into from
Jun 22, 2023
Merged

Handle empty URL parameter values #1917

merged 4 commits into from
Jun 22, 2023

Conversation

pgvishnuram
Copy link
Contributor

@pgvishnuram pgvishnuram commented Jun 21, 2023

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

@pgvishnuram pgvishnuram marked this pull request as ready for review June 21, 2023 17:07
@pgvishnuram pgvishnuram requested a review from a team as a code owner June 21, 2023 17:07
end

table.insert(queryParams, paramName .. "=" .. paramValue)
if paramName and paramName ~= '' and paramValue then -- Check if paramName and paramValue exist
Copy link
Member

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?

Copy link
Contributor Author

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

Copy link
Member

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
Copy link
Member

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:

Suggested change
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.

Copy link
Contributor Author

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

Copy link
Member

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

Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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

Copy link
Member

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.

Copy link
Contributor Author

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
   
    }

pgvishnuram and others added 2 commits June 21, 2023 23:26
Co-authored-by: Daniel Hoherd <daniel.hoherd@gmail.com>
Co-authored-by: Daniel Hoherd <daniel.hoherd@gmail.com>
Copy link
Member

@danielhoherd danielhoherd left a 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.

@danielhoherd danielhoherd changed the title server template config update Handle empty URL parameter values Jun 22, 2023
@danielhoherd danielhoherd merged commit 5d3aa36 into master Jun 22, 2023
4 of 7 checks passed
@danielhoherd danielhoherd deleted the fix-airflow-root-url branch June 22, 2023 16:41
danielhoherd pushed a commit that referenced this pull request Jun 22, 2023
Simpcyclassy pushed a commit that referenced this pull request Aug 14, 2023
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

Successfully merging this pull request may close these issues.

None yet

2 participants