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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

path parameters are overwritten by query parameters with the same name #3069

Closed
ljmsc opened this issue Dec 15, 2022 · 6 comments 路 Fixed by #3072 or #3946
Closed

path parameters are overwritten by query parameters with the same name #3069

ljmsc opened this issue Dec 15, 2022 · 6 comments 路 Fixed by #3072 or #3946

Comments

@ljmsc
Copy link
Contributor

ljmsc commented Dec 15, 2022

馃悰 Bug Report

if you have path parameter in your proto endpoint definition, you can overwrite the value by setting a query parameter with the same name. This is a security issue in my opinion since a gateway or routing rule maybe only checks the path but not the query parameters.

To Reproduce

The following service definition given:

service MyService {
  rpc GetResource(GetResourceRequest) returns (GetResourceResponse) {
    option (google.api.http) = {
      get: "/admin/{resource_id}"
    };
  }
}

One can call the API with GET <host>/admin/<some_resource_id> and gets the resource back. But it is also possible to call the endpoint like this: GET <host>/admin/<my_resource_id>?resourceId=<some_other_resource_id>

In the GRPC Handler the value of resource_id is set to <some_other_resource_id> instead of <my_resource_id>

Expected behavior

It should not be possible to overwrite path parameters with query parameters.

Actual Behavior

It is possible to overwrite path parameters with query parameters.

@ljmsc ljmsc changed the title URL parameters are overwritten by query parameters with the same name path parameters are overwritten by query parameters with the same name Dec 15, 2022
@johanbrandhorst
Copy link
Collaborator

Hi, thanks for your issue report. Could you share an example of this? I did some quick code spelunking and it seems to me that values that are specified in the path are added to the query parameter filter appropriately:

  1. See definition of Custom rpc here:
    rpc Custom(ABitOfEverything) returns (ABitOfEverything) {
    option (google.api.http) = {
    post: "/v1/example/a_bit_of_everything/{uuid}:custom"
    };
    }
    . It defines uuid to be part of the path.
  2. This is the generated code:
    filter_ABitOfEverythingService_Custom_0 = &utilities.DoubleArray{Encoding: map[string]int{"uuid": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
    . uuid is added to the filter.
  3. This filter is used in PopulateQueryParameters to skip parsing of this value:
    if filter.HasCommonPrefix(fieldPath) {
    .

If this bug report is accurate I'd suspect a problem with the filter. It also strikes me as possible that you could construct a query parameter using the json name instead of the proto name and bypass the filter. Could you confirm whether resourceId also works?

@ljmsc
Copy link
Contributor Author

ljmsc commented Dec 15, 2022

hey @johanbrandhorst you are actually right. You need to define resourceId as query param to overwrite the resource_id. That was wrong in my example above. That is also the reason why the HasCommonPrefix() function does not detect the field because the json name differs from the actual field name.

I fixed the example in my original post above.

@johanbrandhorst
Copy link
Collaborator

OK, then I both understand the issue and the cause. The query parameter parser is intentionally lenient in the parsing of query parameters, but clearly that is causing this problem. Removing the parsing of json name query parameters would be a breaking change, and although I'm happy to do that for what could arguably be considered a security issue, I think we should just make the filter look for both the protobuf and json name format. We can modify the gateway generator to output both the proto name and json name into the double array, which should fix the issue. Would you be willing to help contribute this fix?

@ljmsc
Copy link
Contributor Author

ljmsc commented Dec 15, 2022

hey @johanbrandhorst, I would like to help providing a fix for that. 馃憤 I鈥榣l give it a try.

@johanbrandhorst
Copy link
Collaborator

I think we need to add the jsonName to this line:

return fmt.Sprintf("&utilities.DoubleArray{Encoding: map[string]int{%s}, Base: %#v, Check: %#v}", e, f.Base, f.Check)
.

@ljmsc
Copy link
Contributor Author

ljmsc commented Dec 16, 2022

there we go #3072

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants