Skip to content

Apparent buffer overrun affecting the Request object passed to the function #142

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

Closed
daniel-rocha opened this issue Nov 1, 2018 · 4 comments
Assignees

Comments

@daniel-rocha
Copy link

Suppose a function requires a query string parameter, like “productId”. Previously, if either the key wasn’t present in the query string, or if the value was null, the corresponding req. in node would be null, and we could do validation on it to decide how to proceed with the function.

Investigative information

Please provide the following:

Repro steps

Provide the steps required to reproduce the problem:

  1. Write a function in Node that requires a parameter from the query string, e.g. "productId"
  2. Call the function passing "productId=something". Verify it works.
  3. Call the function passing either "http://functionapp/api/FunctionName?productId" or "http://functionapp/api/FunctionName?productId="

Expected behavior

Provide a description of the expected behavior.

req.query.productId should be null or undefined.

Actual behavior

req.query.productId is full of garbage, including the entire header of the HTTP request:

`ser-agent�rMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36��

�upgrade-insecure-requests��1�>

�x-waws-unencoded-url�&/api/NodeRequestBugFunction?productId=�!

client-ip��100.72.212.131:51978��

�is-service-tunneled��0�4

x-arr-log-id�$37c75121-e24c-4afb-8eb2-8d0af7bc3fdb�6

�disguised-host�$noderequestbugtest.azurewebsites.net�*

�x-site-deployment-id��NodeRequestBugTest�<

�was-default-hostname�$noderequestbugtest.azurewebsites.net�8

�x-original-url�&/api/NodeRequestBugFunction?productId=�&

�x-forwarded-for��167.220.255.10:2412���

x-arr-ssl���2048|256|C=US, S=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT TLS CA 4|CN=*.azurewebsites.net��

�x-forwarded-proto��httpsz�`

Known workarounds

No known workarounds, which is important because prevents validation of query string parameters.

Related information

Provide any related information

  • Programming language used: Node
  • Links to source
  • Bindings used
module.exports = async function (context, req) {
  context.log('GetProductDescription function processed a request.');
  context.log('Requested product id is ' + req.query.productId);
 
  const productId = req.query.productId || "";
  
  if (productId || productId.length > 0) {
    context.res = {
      // status: 200, /* Defaults to 200 */
      headers: {
        "Content-Type": "text/plain"
      },
      body: `The product name for your product id ${productId} is Starfruit Explosion`
    };
  }
  else {
    context.res = {
      status: 400,
      body: "Please pass a productId on the query string or in the request body"
    };
  }
};
-->
@mhoeger
Copy link
Contributor

mhoeger commented Nov 1, 2018

Thanks @daniel-rocha, @dahatake has been investigating this issue recently too. It comes from a bug in code generated by protobuf.js. We're currently working on the fix, but in the meantime could you try checking context.bindingData.query.productId? This will work as expected for you.

Do you also know which version this was working for you? Is this a recent regression?

@mhoeger mhoeger self-assigned this Nov 1, 2018
@mhoeger mhoeger added this to the Triaged milestone Nov 1, 2018
@fabiocav
Copy link
Member

@mhoeger are we targeting Sprint 37 for this? If so, can we assign to the sprint?

@mhoeger
Copy link
Contributor

mhoeger commented Nov 17, 2018

The root cause of this issue is that we use a "map" in our protobuf file.

From the protocol buffers docs:

If you provide a key but no value for a map field, the behavior when the field is serialized is language-dependent. In C++, Java, and Python the default value for the type is serialized, while in other languages nothing is serialized.

In combination with protobuf.js, this results in generated code that overflows.

                    case 15:
                        reader.skip().pos++;
                        if (message.query === $util.emptyObject)
                            message.query = {};
                        key = reader.string();
                        reader.pos++;
                        message.query[key] = reader.string();
                        break;

@mhoeger
Copy link
Contributor

mhoeger commented Nov 30, 2018

This specific concern will be addressed in Azure/azure-functions-host#3789. A longer-term fix for valid empty values in a mapping will be addressed here: Azure/azure-functions-language-worker-protobuf#21

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

3 participants