Skip to content

InitialConfig#1465

Closed
darkgl0w wants to merge 12 commits intofastify:masterfrom
darkgl0w:initialConfig
Closed

InitialConfig#1465
darkgl0w wants to merge 12 commits intofastify:masterfrom
darkgl0w:initialConfig

Conversation

@darkgl0w
Copy link
Copy Markdown
Member

@darkgl0w darkgl0w commented Feb 21, 2019

Address #1444

Currently initialConfig exposes an object that can have those properties:

{
  http2, // show http2: true/false if explicitly passed.
  https, // show https: true or https: { allowHTTP1: true/false } if explicitly passed.
  ignoreTrailingSlash, // show ignoreTrailingSlash: true/false if explicitly passed.
  maxParamLength,
  bodyLimit,
  onProtoPoisoning,
  logger, // show logger: 'custom' if an instance is passed or logger: false/ { level }
  serverFactory, // show serverFactory: true if detected
  caseSensitive,
  requestIdHeader,
  genReqId, // show genReqId: 'custom' if a function is passed
  trustProxy, // show trustProxy: 'custom' if a function is passed
  pluginTimeout,
  querystringParser // show querystringParser: 'custom' if a function is passed
}

I have chosen to display a custom string when a custom function is explicitly passed to certain properties. And to avoid any security breach I filtered critical information (such as certificates, for example), i tried to avoid shallow freeze, so initialConfig is completely frozen and read-only.

Maybe some properties exposed here are not relevant and should to be removed, but for this first draft I tried to include all user customable options.

What do you think about this approach ? If you have suggestions I am completely open, and when we reach a consensus I will write the documentation and a fastify 1.x backport too ^^

Checklist

  • run npm run test and npm run benchmark
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message and code follows Code of conduct

@mcollina
Copy link
Copy Markdown
Member

We landed a flaky test. Would you mind to rebase?

Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work! Docs are missing and I've left a significant problem regarding deep freeze.
Let me know what you think.

Comment thread fastify.js

let initialConfig = filterInitialConfig(rawOptions)

return deepFreezeObject(initialConfig)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the filterInitialConfig logic is too brittle as it stands to safely do a deep freeze in all cases. It's definitely possible that a new feature that comes in forget to change this, and we end up with a frozen stream or process object which will be extremely hard to track.

I think we should:

  1. introduce a schema validation to Fastify options that removes additional properties (special care for the logger options, to the point that I will not really include them here).
  2. deep-freeze the resulting object.

I'm also ok in landing this PR with a simple, one level freeze and work on the validaiton in the next PR.

Copy link
Copy Markdown
Member Author

@darkgl0w darkgl0w Feb 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
I completely agree with you, I knew it would be troublesome to maintain the moment I started writing this piece of code 😄

I also wonder about the relevance to expose certain options (like the logger as you pointed out, and more generally some property that I decided to "exhibit" with a simple 'custom' return or that I have just deleted on this first draft), how can these exposed information can be used ? can they lead to malicious intents (key/certs for example) ?

What I suggest to do for now is to strip this first draft to the point where we have initialConfig return this:

{ ignoreTrailingSlash: true || false } // if explicitly passed by the user

For now we keep only this information as it addresses #1444 needs, so I think this particular option is relevant (we have a concrete legit use case here).

I think that the deepFreezeObject() function is good to be kept as is in prevision of the upcoming rework PR (currently the function can completely freeze "entities" that can be frozen and avoid those that can not - like typed arrays)

Are you okay if I strip the proposal to something like this :

   function getSecuredInitialConfig() {
  // We clone the initial configuration options object
  let rawOptions = Object.assign({}, options)
  let initialConfig = {}

  if (rawOptions.hasOwnProperty('ignoreTrailingSlash')) {
    initialConfig['ignoreTrailingSlash'] = rawOptions['ignoreTrailingSlash']
  }

  return deepFreezeObject(initialConfig)

  function deepFreezeObject(object) {
    let properties = Object.getOwnPropertyNames(object)

    for (const name of properties) {
      let value = object[name]
      if (typeof value !== 'object' || Buffer.isBuffer(value)) {
        continue
      }

      object[name] = value && typeof value === 'object' ? deepFreezeObject(value) : value
    }
    return Object.freeze(object)
  }
}

Doing so we put the first stone to this functionality without having "naive code" and without exposing information that we consider not relevant an that will be removed later, we address an issue that can help with a legit use case and in the meantime I can come with a better proposal (I really like the idea of a schema validation for the initialConfig object, it's a shame I didn't even think to use something like this to start with 😞 ) and in the issue topic we can discuss about the relevance of the information we are going to expose here.

What do you think ? Can I go with this, change the test file and the documentation ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of just releasing that config with only one property. We should literally aim to get all the relevant ones, and publish them.

IMHO the best way to do this is via a JSON Schema without additionalProperties set, followed by a deep-clone.

@cemremengu
Copy link
Copy Markdown
Contributor

There seems to be a problem with the rebase here

@darkgl0w
Copy link
Copy Markdown
Member Author

I will close this PR and open a new one to avoid commit pollution, as @cemremengu said I got some problems with my connection this afternoon and the rebase didn't go well 😞
sorry for the burden

@darkgl0w darkgl0w closed this Feb 22, 2019
mcollina pushed a commit that referenced this pull request Mar 10, 2019
* initialConfig - second draft

address #1444 with changes requested here #1465 (comment)

* fix typo

* Test fix and little code rework

* Code refactor

* Improve test coverage

* Fix code and add one more test

* Fix

* Add deep cloning through `rfdc`

* Fix test and expected behavior

* Fix test on Node.js 6

* Fix code and test

* Fix: from `let` to `const`

* Fix: Better `TypedArray` detection.

This will avoid any TypeError and cover all the cases.

*Previously it only covered `Uint8Array` because `Buffer` are instances of `Uint8Array` since Node.js 4*
ref.: https://nodejs.org/docs/latest-v4.x/api/buffer.html#buffer_buffer

* Add a test with Pino.js stream option.

* Fix: Improve Pino.js stream test.

* Fix: add a new internal error code.

* Fix: remove uneeded error statusCode.

* Fix: should expose default init options.

* Fix typo.

* Achieve 100 % code coverage and export utils.
@github-actions
Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Feb 10, 2022
@Eomm Eomm added the wontfix This will not be worked on, the behavior is intended label Apr 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

wontfix This will not be worked on, the behavior is intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants