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
redact produces unquoted strings #599
Conversation
A strict=false redactor will return the unquoted value `s` when called with `redact(s)`. This leads to bad JSON. For strings, call `tools.asString` instead.
A strict=false redactor will return the unquoted value `s` when called with `redact(s)`. This leads to bad JSON. For strings, call `tools.asString` instead.
else o[k] = fastRedact({ paths: shape[k], censor, serialize, strict }) | ||
else { | ||
const fr = fastRedact({ paths: shape[k], censor, serialize, strict }) | ||
o[k] = value => (typeof value === 'string' ? asString(value) : fr(value)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be better fixed in fastRedact itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe I misunderstood and it is a fast-redact thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/davidmarkclements/fast-redact is a little odd because it returns JSON text when an object is passed in, primitives otherwise (with strict
set to false
). Perhaps it would be more consistent to always return JSON text. When primitives were passed in, JSON.stringify() would be called for the return.
It would be a simple matter of changing the last lines of lib/redactor.js
in fast-redact
function strictImpl (strict) {
return strict === true ? `throw Error('fast-redact: primitives cannot be redacted')` : `return JSON.stringify(o)` <--- used to be "return o"
}
but that breaks the existing unit test which checks that when a number is passed in, a number is returned. The return could be written as:
return typeof o === 'string' ? JSON.stringify(o) : o
(basically the same as what is in this PR). All tests would pass, but then the definition of strict=false
would be a little awkward. And the code doesn't use the cool optimized asString()
function which pino has.
I think if you fixed fast-redact
now, you'd be changing its documented behavior and so might break existing code in other packages which make use of it.
I suggest that a little caveat is added to the fast-readact markdown file warning of the strict=false
treatment of string primitives. And we work around this in the pino code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you fixed
fast-redact
now, you'd be changing its documented behavior and so might break existing code in other packages which make use of it.
I think we should release a new major version of fast-redact with the correct behavior, and then update pino. In this way other packages will not break unless they update to the new (fixed) version.
Would you mind sending a PR to fast-redact in this sense?
Sounds good to me. I've created davidmarkclements/fast-redact#15 So we can close this PR without merging. And update |
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. |
pino has a bug where it can produce invalid JSON. Here's an example:
The bug happens when pino is called with a string property that matches the root of one of the redact paths. In the example above, we have a redact path of "foo.bar", but pino is called with an object that has a string for "foo". pino outputs that string value without quotes.
"foo":abc
should be"foo":"abc"
.This bug is troublesome if the redact path starts with a wildcard, such as "*.password". It causes pino to output, without quotes, every string in the logged object.
With this bug, pino is susceptible to JSON injection. Change the call above to:
and the output is:
Fake messages can be injected with:
Why does this happen?
It happens because the non-strict fast-redact simply returns primitive objects. (https://github.com/davidmarkclements/fast-redact#strict-boolean---true) Strings are returned, without quotes and without escapes. So when the redactor gets called with a string, it simply echos the string value back.
What's the fix?
Add a test before the redactor is called. If it would be called with a string, make a call to
tools.asString
instead.Note: There was a test case that pino worked properly with primitives and paths. But the test was checking numbers and not strings, so this bug wasn't caught. I've added individual test cases for string, boolean and null.