| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
When using https.createServer, passing boolean values for `key` and `cert` properties in the options object parameter doesn't throw an error an could lead to potential issues if they're accidentally passed. This PR aims to throw a reasonable error if a boolean was passed to either of those properties. Fixes: nodejs#12802
| throw new Error('"options.key" must not be a boolean'); | ||
|
|
||
| if (opts && typeof opts.cert === 'boolean') | ||
| throw new Error('"options.cert" must not be a boolean'); |
There was a problem hiding this comment.
By the way, we try to migrate to a new error system that allows for more flexibility in the future, it would be cool if you think you could take a look at using that.
Sorry, something went wrong.
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. |
There was a problem hiding this comment.
We don’t need the copyright header for new files.
Sorry, something went wrong.
|
Hello @yjimk and welcome. Thank you very much for you contribution 🥇.
|
Sorry, something went wrong.
| } | ||
| opts = util._extend({}, opts); | ||
|
|
||
| if (opts && typeof opts.key === 'boolean') |
There was a problem hiding this comment.
Line 41 guarantee that opts is an object so there is no need to check opts here or in line 46.
Sorry, something went wrong.
There was a problem hiding this comment.
I don't think checking against all invalid values is the way to go. I think it should confirm it is a valid value and reject everything else.
Sorry, something went wrong.
| https.createServer({ | ||
| key: true, | ||
| cert: fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`) | ||
| }), /"options\.key" must not be a boolean/); |
There was a problem hiding this comment.
These regular expressions would be better if they matched the entire message (that is, if they started with ^ and ended with $).
Sorry, something went wrong.
| opts = util._extend({}, opts); | ||
|
|
||
| if (opts && typeof opts.key === 'boolean') | ||
| throw new Error('"options.key" must not be a boolean'); |
There was a problem hiding this comment.
This and the other Error should be a TypeError.
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM with some cleanup.
Sorry, something went wrong.
| cert: fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`) | ||
| })); | ||
|
|
||
| assert.throws(() => |
There was a problem hiding this comment.
You can reduce code duplication a lot here. All of these assert.throws() calls are essentially the same, with only the value of key, cert, and the regular expression changing. You can do something like this instead:
const key = fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`);
const cert = fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`);
const invalidKeyRE = /^"options\.key" must not be a boolean$/;
const invalidCertRE = /^"options\.cert" must not be a boolean$/;
[
[true, cert, invalidKeyRE],
// Fill in other cases here
].forEach((params) => {
assert.throws(() => {
https.createServer({
key: params[0],
cert: params[1]
});
}, params[2]);
});
Sorry, something went wrong.
|
I agree with @Trott, better verify for validity instead of checking single invalid values like booleans (e.g. whitelist over blacklist approach). Also, I think the checks should also be done on tls.createServer and tls.createSecureContext, so I'd say the change should be done in the lowest level possible, which is tls.createSecureContext. |
Sorry, something went wrong.
|
Thank you all for the super helpful and detailed feedback! I'll make those changes and see if I can get closer. |
Sorry, something went wrong.
Taking on board the review from the initial PR, multiple changes have been made. - Type checking now a whitelist as opposed to only checking for a boolean - Type checking moved to the underlying `_tls_common` , `tls` and `https` modules now affected - Arrays are now iterated using `map` instead of `for` for affected sections -Testing added for the `tls` module Fixes: nodejs#12802
|
I believe I might have addressed all of the comments left with my latest commit. The new code is a bit of a departure from the old, so I hope it is OK and would appreciate any tips. Particularly worried about using that function validateKeyCert from a naming perspective and also whether it conforms to the right method for type checking. There are a few other things in that file that I noticed are a different style compared to other parts of the code, such as usage of for loops and var over let and const. Thanks again for your great feedback and comments, it's been a fantastic learning experience. |
Sorry, something went wrong.
| } | ||
|
|
||
| function validateKeyCert(value, type) { | ||
| if (typeof value !== 'string' && !(value instanceof Buffer)) |
There was a problem hiding this comment.
I think this is too strict, and instanceof Buffer is not a foolproof way to check for Buffers. Can you use ArrayBuffer.isView(value) instead and adjust the message accordingly (Buffers are just special Uint8Arrays, but all Uint8Arrays and other ArrayBufferViews should work, I think.).
Sorry, something went wrong.
There was a problem hiding this comment.
Ah, brilliant! Replacing the two check works perfectly. I'll change this over and add some additional tests.
Regarding the new error message, it is currently ['string', 'buffer'] and I'm thinking it should change to ['string', 'ArrayBuffer'] with perhaps string => String. Would you have an opinion on how that should look?
Sorry, something went wrong.
There was a problem hiding this comment.
I don’t think we can list ArrayBuffer, as those are not ArrayBufferViews themselves.
Maybe ['string', 'Buffer', 'TypedArray', 'DataView']? That would match the message here:
Line 231 in cde272a
Sorry, something went wrong.
There was a problem hiding this comment.
Perfect! Thank you, I'll create a commit for this change.
Sorry, something went wrong.
| const https = require('https'); | ||
| const fs = require('fs'); | ||
|
|
||
| const keyBuff = fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`); |
There was a problem hiding this comment.
There's been some recent work to simplify fixtures access...
example...
const fixtures = require('../common/fixtures');
const keyBuff = fixtures.readKey('agent1-key.pem');
Sorry, something went wrong.
There was a problem hiding this comment.
Ah OK, cool. Thanks, I'll change that over too. The original test file was copied over from another and amended, hence the previous inclusion of the license comments and usage of the fs.readFileSync method of including the pem files. Is there are issue/task that you're aware of to update the older tests to use the newer methods? Something like that I feel like would be a useful task for me to take up in future.
Sorry, something went wrong.
|
Since this PR relates to #12802 which is marked as "good first contribution", I'm going to ask a question (as I also intended on grabbing this). If this is inappropriate, delete my question and I'll take it to IRC or SO From e92e64a extended commit message:
What's the benefit of changing the loop type? I can't seem to find related review comment that (probably) requested the change. |
Sorry, something went wrong.
|
RE: @fl0w, mostly due to personal preference toward map and other functional programming methods rather than for or forEach loops. This tweet (although it mentions forEach instead of for) is the basis for my way of thinking. https://twitter.com/_ericelliott/status/710571765844615168 I'd love to hear the fors and againsts on it though ...sorry |
Sorry, something went wrong.
Additional changes in line with PR review - Loosen type checking for buffers using the ArrayBuffer method - Require pem files using updated fixture access method - Add tests for ArrayBuffer and DataView types Fixes: nodejs#12802
|
I've changed the type checking for buffer, but my knowledge of ArrayBuffers and DataViews is pretty limited. |
Sorry, something went wrong.
| options.ca.map((ca) => { | ||
| validateKeyCert(ca, 'ca'); | ||
| c.context.addCACert(ca); | ||
| }); |
There was a problem hiding this comment.
This map can be changed to a forEach because you're not using the return value.
Sorry, something went wrong.
| options.cert.map((cert) => { | ||
| validateKeyCert(cert, 'cert'); | ||
| c.context.setCert(cert); | ||
| }); |
There was a problem hiding this comment.
Same here.
Sorry, something went wrong.
| options.key.map((k) => { | ||
| validateKeyCert(k.pem || k, 'key'); | ||
| c.context.setKey(k.pem || k, k.passphrase || options.passphrase); | ||
| }); |
There was a problem hiding this comment.
And here.
Sorry, something went wrong.
There was a problem hiding this comment.
Few nits, overall LGTM.
Sorry, something went wrong.
Sorry, just saw your comment after review. I personally see no benefit of using map over forEach if you're not going to return something/use the return value. Node.js uses for a lot because as far as we know, it is still considerably faster than the prototype methods, thought that might have changed with TurboFan. |
Sorry, something went wrong.
|
No problem, I'll change it over to use the forEach method. :) |
Sorry, something went wrong.
- Change iteration method from map -> forEach Fixes: nodejs#12802
It does not appear to have changed by much. |
Sorry, something went wrong.
PR-URL: nodejs/node#14807 Fixes: nodejs/node#12802 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs/node#14807 Fixes: nodejs/node#12802 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
* **async_hooks**
* Older experimental `async_hooks` APIs have been removed
[[`d731369b1d`](d731369b1d)]
**(SEMVER-MAJOR)** [#14414](#14414)
* **Errors**
* Multiple built in modules have been migrated to use static error codes
* **Domains**
* The long deprecated `.dispose()` method has been removed
[[`602fd36d95`](602fd36d95)]
**(SEMVER-MAJOR)** [#15412](#15412)
* **File system**
* `fs.ReadStream` and `fs.WriteStream` now make use of `.destroy()`
[[`e5c290bed9`](e5c290bed9)]
**(SEMVER-MAJOR)** [#15407](#15407)
* `fs` callbacks are now invoked with an undefined `this` context
[[`2249234fee`](2249234fee)]
**(SEMVER-MAJOR)** [#14645](#14645)
* **HTTP**
* Socket timeout is set when the socket connects
[[`10be20a0e8`](10be20a0e8)]
**(SEMVER-MAJOR)** [#8895](#8895)
* A bug causing the request `error` event to fire twice has been fixed
[[`620ba41694`](620ba41694)]
**(SEMVER-MAJOR)** [#14659](#14659)
* The `pipe` method on `OutgoingMessage` has been disabled
[[`156549d8ff`](156549d8ff)]
**(SEMVER-MAJOR)** [#14358](#14358)
* **HTTP/2**
* The `--expose-http2` command-line argument is no longer required
[[`f55ee6e24a`](f55ee6e24a)]
**(SEMVER-MAJOR)** [#15535](#15535)
* **Internationalization**
* The `Intl.v8BreakIterator` class has been removed
[[`668ad44922`](668ad44922)]
**(SEMVER-MAJOR)** [#15238](#15238)
* **OS**
* `os.EOL` is now read-only
[[`f6caeb9526`](f6caeb9526)]
**(SEMVER-MAJOR)** [#14622](#14622)
* **Process**
* It is now possible to pass additional flags to `dlopen`
[[`5f22375922`](5f22375922)]
**(SEMVER-MAJOR)** [#12794](#12794)
* **Timers**
* Using a timeout duration larger than 32-bits will now emit a warning
[[`ce3586da31`](ce3586da31)]
**(SEMVER-MAJOR)** [#15627](#15627)
* **TLS**
* `parseCertString` has been deprecated
[[`468110b327`](468110b327)]
**(SEMVER-MAJOR)** [#14249](#14249)
* Type-checking for `key`, `cert`, and `ca` options has been added
[[`a7dccd040d`](a7dccd040d)]
**(SEMVER-MAJOR)** [#14807](#14807)
* **async_hooks**
* Older experimental `async_hooks` APIs have been removed
[[`d731369b1d`](d731369b1d)]
**(SEMVER-MAJOR)** [#14414](#14414)
* **Errors**
* Multiple built in modules have been migrated to use static error codes
* **Domains**
* The long deprecated `.dispose()` method has been removed
[[`602fd36d95`](602fd36d95)]
**(SEMVER-MAJOR)** [#15412](#15412)
* **File system**
* `fs.ReadStream` and `fs.WriteStream` now make use of `.destroy()`
[[`e5c290bed9`](e5c290bed9)]
**(SEMVER-MAJOR)** [#15407](#15407)
* `fs` callbacks are now invoked with an undefined `this` context
[[`2249234fee`](2249234fee)]
**(SEMVER-MAJOR)** [#14645](#14645)
* **HTTP**
* Socket timeout is set when the socket connects
[[`10be20a0e8`](10be20a0e8)]
**(SEMVER-MAJOR)** [#8895](#8895)
* A bug causing the request `error` event to fire twice has been fixed
[[`620ba41694`](620ba41694)]
**(SEMVER-MAJOR)** [#14659](#14659)
* The `pipe` method on `OutgoingMessage` has been disabled
[[`156549d8ff`](156549d8ff)]
**(SEMVER-MAJOR)** [#14358](#14358)
* **HTTP/2**
* The `--expose-http2` command-line argument is no longer required
[[`f55ee6e24a`](f55ee6e24a)]
**(SEMVER-MAJOR)** [#15535](#15535)
* **Internationalization**
* The `Intl.v8BreakIterator` class has been removed
[[`668ad44922`](668ad44922)]
**(SEMVER-MAJOR)** [#15238](#15238)
* **OS**
* `os.EOL` is now read-only
[[`f6caeb9526`](f6caeb9526)]
**(SEMVER-MAJOR)** [#14622](#14622)
* **Process**
* It is now possible to pass additional flags to `dlopen`
[[`5f22375922`](5f22375922)]
**(SEMVER-MAJOR)** [#12794](#12794)
* **Timers**
* Using a timeout duration larger than 32-bits will now emit a warning
[[`ce3586da31`](ce3586da31)]
**(SEMVER-MAJOR)** [#15627](#15627)
* **TLS**
* `parseCertString` has been deprecated
[[`468110b327`](468110b327)]
**(SEMVER-MAJOR)** [#14249](#14249)
* Type-checking for `key`, `cert`, and `ca` options has been added
[[`a7dccd040d`](a7dccd040d)]
**(SEMVER-MAJOR)** [#14807](#14807)
* **async_hooks**
* Older experimental `async_hooks` APIs have been removed
[[`d731369b1d`](d731369b1d)]
**(SEMVER-MAJOR)** [#14414](#14414)
* **Errors**
* Multiple built in modules have been migrated to use static error codes
* **Domains**
* The long deprecated `.dispose()` method has been removed
[[`602fd36d95`](602fd36d95)]
**(SEMVER-MAJOR)** [#15412](#15412)
* **File system**
* `fs.ReadStream` and `fs.WriteStream` now make use of `.destroy()`
[[`e5c290bed9`](e5c290bed9)]
**(SEMVER-MAJOR)** [#15407](#15407)
* `fs` callbacks are now invoked with an undefined `this` context
[[`2249234fee`](2249234fee)]
**(SEMVER-MAJOR)** [#14645](#14645)
* **HTTP**
* Socket timeout is set when the socket connects
[[`10be20a0e8`](10be20a0e8)]
**(SEMVER-MAJOR)** [#8895](#8895)
* A bug causing the request `error` event to fire twice has been fixed
[[`620ba41694`](620ba41694)]
**(SEMVER-MAJOR)** [#14659](#14659)
* The `pipe` method on `OutgoingMessage` has been disabled
[[`156549d8ff`](156549d8ff)]
**(SEMVER-MAJOR)** [#14358](#14358)
* **HTTP/2**
* The `--expose-http2` command-line argument is no longer required
[[`f55ee6e24a`](f55ee6e24a)]
**(SEMVER-MAJOR)** [#15535](#15535)
* **Internationalization**
* The `Intl.v8BreakIterator` class has been removed
[[`668ad44922`](668ad44922)]
**(SEMVER-MAJOR)** [#15238](#15238)
* **OS**
* `os.EOL` is now read-only
[[`f6caeb9526`](f6caeb9526)]
**(SEMVER-MAJOR)** [#14622](#14622)
* **Process**
* It is now possible to pass additional flags to `dlopen`
[[`5f22375922`](5f22375922)]
**(SEMVER-MAJOR)** [#12794](#12794)
* **Timers**
* Using a timeout duration larger than 32-bits will now emit a warning
[[`ce3586da31`](ce3586da31)]
**(SEMVER-MAJOR)** [#15627](#15627)
* **TLS**
* `parseCertString` has been deprecated
[[`468110b327`](468110b327)]
**(SEMVER-MAJOR)** [#14249](#14249)
* Type-checking for `key`, `cert`, and `ca` options has been added
[[`a7dccd040d`](a7dccd040d)]
**(SEMVER-MAJOR)** [#14807](#14807)
* **async_hooks**
* Older experimental `async_hooks` APIs have been removed
[[`d731369b1d`](d731369b1d)]
**(SEMVER-MAJOR)** [#14414](#14414)
* **Errors**
* Multiple built in modules have been migrated to use static error codes
* **Domains**
* The long deprecated `.dispose()` method has been removed
[[`602fd36d95`](602fd36d95)]
**(SEMVER-MAJOR)** [#15412](#15412)
* **File system**
* `fs.ReadStream` and `fs.WriteStream` now make use of `.destroy()`
[[`e5c290bed9`](e5c290bed9)]
**(SEMVER-MAJOR)** [#15407](#15407)
* `fs` callbacks are now invoked with an undefined `this` context
[[`2249234fee`](2249234fee)]
**(SEMVER-MAJOR)** [#14645](#14645)
* **HTTP**
* Socket timeout is set when the socket connects
[[`10be20a0e8`](10be20a0e8)]
**(SEMVER-MAJOR)** [#8895](#8895)
* A bug causing the request `error` event to fire twice has been fixed
[[`620ba41694`](620ba41694)]
**(SEMVER-MAJOR)** [#14659](#14659)
* The `pipe` method on `OutgoingMessage` has been disabled
[[`156549d8ff`](156549d8ff)]
**(SEMVER-MAJOR)** [#14358](#14358)
* **HTTP/2**
* The `--expose-http2` command-line argument is no longer required
[[`f55ee6e24a`](f55ee6e24a)]
**(SEMVER-MAJOR)** [#15535](#15535)
* **Internationalization**
* The `Intl.v8BreakIterator` class has been removed
[[`668ad44922`](668ad44922)]
**(SEMVER-MAJOR)** [#15238](#15238)
* **OS**
* `os.EOL` is now read-only
[[`f6caeb9526`](f6caeb9526)]
**(SEMVER-MAJOR)** [#14622](#14622)
* **Process**
* It is now possible to pass additional flags to `dlopen`
[[`5f22375922`](5f22375922)]
**(SEMVER-MAJOR)** [#12794](#12794)
* **Timers**
* Using a timeout duration larger than 32-bits will now emit a warning
[[`ce3586da31`](ce3586da31)]
**(SEMVER-MAJOR)** [#15627](#15627)
* **TLS**
* `parseCertString` has been deprecated
[[`468110b327`](468110b327)]
**(SEMVER-MAJOR)** [#14249](#14249)
* Type-checking for `key`, `cert`, and `ca` options has been added
[[`a7dccd040d`](a7dccd040d)]
**(SEMVER-MAJOR)** [#14807](#14807)
| Back | FazBrowse Home | New Git URL |
This is my first PR on the Node repository, your feedback is greatly appreciated.
When using https.createServer, passing boolean values for key and cert properties in the options object parameter doesn't throw an error an could lead to potential issues if they're accidentally passed.
This PR aims to throw a reasonable error if a boolean was passed to either of those properties.
Fixes: #12802
Checklist
Affected core subsystem(s)
https