Skip to content

Commit

Permalink
Respect disablePrototypePoisoningProtection option (#2380)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshMock authored Oct 16, 2024
1 parent 661caf8 commit 82acfc3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 3 deletions.
4 changes: 2 additions & 2 deletions docs/basic-config.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ const client = new Client({
----

|`disablePrototypePoisoningProtection`
|`boolean`, `'proto'`, `'constructor'` - By the default the client will protect you against prototype poisoning attacks. Read https://web.archive.org/web/20200319091159/https://hueniverse.com/square-brackets-are-the-enemy-ff5b9fd8a3e8?gi=184a27ee2a08[this article] to learn more. If needed you can disable prototype poisoning protection entirely or one of the two checks. Read the `secure-json-parse` https://github.com/fastify/secure-json-parse[documentation] to learn more. +
_Default:_ `false`
|`boolean`, `'proto'`, `'constructor'` - The client can protect you against prototype poisoning attacks. Read https://web.archive.org/web/20200319091159/https://hueniverse.com/square-brackets-are-the-enemy-ff5b9fd8a3e8?gi=184a27ee2a08[this article] to learn more about this security concern. If needed, you can enable prototype poisoning protection entirely (`false`) or one of the two checks (`'proto'` or `'constructor'`). For performance reasons, it is disabled by default. Read the `secure-json-parse` https://github.com/fastify/secure-json-parse[documentation] to learn more. +
_Default:_ `true`

|`caFingerprint`
|`string` - If configured, verify that the fingerprint of the CA certificate that has signed the certificate of the server matches the supplied fingerprint. Only accepts SHA256 digest fingerprints. +
Expand Down
20 changes: 20 additions & 0 deletions docs/changelog.asciidoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
[[changelog-client]]
== Release notes

[discrete]
=== 8.16.0

[discrete]
==== Features

[discrete]
===== Support for Elasticsearch `v8.16`

You can find all the API changes
https://www.elastic.co/guide/en/elasticsearch/reference/8.16/release-notes-8.16.0.html[here].

[discrete]
==== Fixes

[discrete]
===== Pass prototype poisoning options to serializer correctly

The client's `disablePrototypePoisoningProtection` option was set to `true` by default, but when it was set to any other value it was ignored, making it impossible to enable prototype poisoning protection without providing a custom serializer implementation.

[discrete]
=== 8.15.1

Expand Down
16 changes: 15 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,21 @@ export default class Client extends API {
this.diagnostic = opts[kChild].diagnostic
} else {
this.diagnostic = new Diagnostic()
this.serializer = new options.Serializer()

let serializerOptions
if (opts.disablePrototypePoisoningProtection != null) {
if (typeof opts.disablePrototypePoisoningProtection === 'boolean') {
serializerOptions = {
enablePrototypePoisoningProtection: !opts.disablePrototypePoisoningProtection
}
} else {
serializerOptions = {
enablePrototypePoisoningProtection: opts.disablePrototypePoisoningProtection
}
}
}
this.serializer = new options.Serializer(serializerOptions)

this.connectionPool = new options.ConnectionPool({
pingTimeout: options.pingTimeout,
resurrectStrategy: options.resurrectStrategy,
Expand Down
46 changes: 46 additions & 0 deletions test/unit/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,49 @@ test('Ensure new client does not time out at default (30s) when client sets requ
t.end()
}
})

test('Pass disablePrototypePoisoningProtection option to serializer', async t => {
let client = new Client({
node: 'http://localhost:9200',
disablePrototypePoisoningProtection: false
})
t.same(client.serializer[symbols.kJsonOptions], {
protoAction: 'error',
constructorAction: 'error'
})

client = new Client({
node: 'http://localhost:9200',
disablePrototypePoisoningProtection: true
})
t.same(client.serializer[symbols.kJsonOptions], {
protoAction: 'ignore',
constructorAction: 'ignore'
})

client = new Client({
node: 'http://localhost:9200',
disablePrototypePoisoningProtection: 'proto'
})
t.same(client.serializer[symbols.kJsonOptions], {
protoAction: 'error',
constructorAction: 'ignore'
})

client = new Client({
node: 'http://localhost:9200',
disablePrototypePoisoningProtection: 'constructor'
})
t.same(client.serializer[symbols.kJsonOptions], {
protoAction: 'ignore',
constructorAction: 'error'
})
})

test('disablePrototypePoisoningProtection is true by default', async t => {
const client = new Client({ node: 'http://localhost:9200' })
t.same(client.serializer[symbols.kJsonOptions], {
protoAction: 'ignore',
constructorAction: 'ignore'
})
})

0 comments on commit 82acfc3

Please sign in to comment.