Update dependency @larvit/log to v2.5.0 #238
Reference in New Issue
Block a user
Delete Branch "renovate/larvit-log-2.x"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR contains the following updates:
2.4.0→2.5.0Release Notes
larvit/log (@larvit/log)
v2.5.0Compare Source
Rotate the credentials that several Security entries name: earlier versions exported them. One
exposure stays open: keep credentials out of a url you base64-encode into a request path.
Fewer ways for a credential to reach a span: a url nested in the request path, a header Elastic
APM's rule names, a query key Datadog's rule names, userinfo in more spellings, and the url in a
span's status message all record
REDACTED. A batch survives a failed send, a full queue and athrowing
storage, and no longer holds the process open. The text format writes the time to themillisecond, and
resolveFormatteris new. README → Audience now promises only that a credentialrecords
REDACTEDin the shapes README → Credentials in a captured value lists.Security
url.fullexports it aswritten. An image proxy such as imgproxy takes its source url this way.
log.fetchstillexports any credential in that url, on every such call, as it has since v2.3.0. Send such a
request with the global
fetch, which records no span, or keep the credential out of the url.Search
url.fullin spans from any version foraHR0c, which finds such a url where the encodedtext starts with
http, and rotate any credential a hit holds.url.fullrecordsREDACTEDfor a url nested in the request path, raw or percent-encoded.Since v2.3.0,
log.fetch("https://proxy.test/fetch/https://user:pass@cb.test/x")— the shape afetch-through, CORS or image proxy takes — exported the password in
url.fullwith no captureoption involved, and a signed url percent-encoded into the path exported its signature. Now the
path records
REDACTEDfrom the first segment starting with a scheme and opening a url that holds acredential, at any depth of percent-encoding:
https://proxy.test/fetch/REDACTED. It also recordsREDACTEDfrom the first segment holding a query key that names a credential, wherever thenested url sits:
/fetch/s3.test/k%3Fsig%3D…records/fetch/s3.test/REDACTED, and/a/x=https:%2F%2Fcb.test%2Fx%3Fpassword%3D…records/a/REDACTED; so does a matrixparameter such as
/m/img;sig=…/x.png, which records/m/REDACTED. A path showing userinfoafter
//,\\,/\or\/, raw or percent-encoded, such as/users//bob@x.test, records/REDACTEDwhole, and so does one percent-encoded more than eight times. A dashboard grouping onurl.fullsees such a path change, and some paths holding no credential too: a nested url's?key=lookup cuts the path, and so does a ninth nested url. Rotate what such a path carried inspans an earlier version exported, as v2.4.0 says.
otlpAdditionalHeadersname is reported by its position, never by the name. Sincev2.4.0, a whole header line pasted as a name, such as
{ "Authorization: Bearer …": "" }, wrotethe token in the queue's
OTLP export headers invalid, batch droppedreport, tostderror yourreport. Now a name that isn't a valid header name reports asotlpAdditionalHeaders carries an invalid header name at position 1 (counting from 1). Search those reports forcarries an invalidand rotate any credential the name shows.REDACTEDby Elastic APM's defaultsanitize_field_namesrule.Since v2.3.0 only
authorization,cookie,proxy-authorizationandset-cookiedid, so alisted
x-api-key,x-auth-tokenorx-amz-security-tokenexported its value. Now a name that,in any casing, is
passwd,password,pwdorsecret, ends inkey, or holdsauth,card,credit,principal,sessionortokenrecordsREDACTEDtoo, so a dashboard grouping onsuch a header sees it change, a non-secret
www-authenticateorx-idempotency-keyincluded.Check
captureRequestHeadersandcaptureResponseHeadersfor such a name, and rotate what itcarried.
log.fetchredacts the url it fetched in its span's status message asurl.full's query iswith
captureQueryon, whatevercaptureQuerysays. Since v2.4.0,log.fetch("https://u:p@h.test/x?access_token=…")on Node or in a browser exported the token inthe rejection the runtime quotes the url into; only the userinfo was redacted. Now the url in it
records
https://REDACTED@h.test/x?access_token=REDACTED. Anend({ error })message that is aurl is redacted the same way, so a
?key=lookup or a?token=cursor in one recordsREDACTEDand a dashboard grouping on status messages sees it change. Search status messages with the regex
(?i)([?&#;]|%(25)*(3f|26|23|3b))[-_]*([^&=%\s]*(auth|authentication|authorization|consumer[-_]?id|credential|key|key[-_]?id|pass|pass[-_]?phrase|p(ass)?w(or)?d[12]?|secret|sig|sign|signature|signed|token)|code|googleaccessid|id[-_]?token[-_]?hint)[-_]*(=|%(25)*3d)for a match followed by anything but
REDACTED, and rotate what it finds.\\and mixed-slash spellings among other text, in a slashless url, andpercent-encoded. Since v2.3.0, a captured
locationofhttps:\\u:pw@horhttp:u:pw@hexported
pw. So didhttps:\\u:pw@horhttps:/\u:pw@hamong other text in a header value, akept query value such as
?next=https://my+user:pw@cb.test/x, and a url percent-encoded twice ormore into a header value or three times or more into a query value. Since v2.4.0, either spelling
among other text in a status message did too. Search captured header values, status messages and
url.fullwith(?i)(https?:|([\\/]|%(25)*(2F|5C)){2})\S*(@|%(25)*40)and rotate any password amatch holds; a match reading
REDACTEDbefore its@holds none.or value or a status message, where the rules for a parsed url left it. Since v2.3.0,
location: /cb?token=…, alink: </next?access_token=…>header and a kept query value holding ascheme-less or protocol-relative url, such as
?src=%2F%2Fcdn.test%2Fk%3Fsig%3D…, exported thecredential, and so did a key opening a fragment, such as an OAuth implicit-flow redirect's
location: https://app.test/cb#access_token=…; since v2.4.0, so did anend({ error })messagesuch as node-fetch's
request to …?token=… failed. Now a header value or query value holding sucha key after a
?,&,#or;recordsREDACTEDwhole, and a query key records it with its value. A status message recordsREDACTEDin place of the value, which ends at&,#or a plain space:request to https://h/x?token=REDACTED failed. Text percent-encoded is read decoded up to eighttimes, and a status message holding a key only decoded, or encoded deeper, records
REDACTEDwhole. A dashboard grouping on such a header, message or
url.fullsees it change, a?key=lookup included. Search captured header values, status messages and
url.fullwith the regex inthe status-message entry above for a match followed by anything but
REDACTED, and rotate what itfinds.
captureQueryredacts a url a query key or value holds once decoded, at every level. Itsuserinfo records
REDACTEDin place of the whole key or value, and a matched key's valueREDACTEDin place: since v2.3.0,?next=https%3A%2F%2Ft.test%2Fx%3Ftoken%3D…withcaptureQueryon exported the token inurl.full, and now recordsnext=https%3A%2F%2Ft.test%2Fx%3Ftoken%3DREDACTED. A url in a key is read with its value too, asa proxy taking
?<url>reads it, and where that finds a credential both recordREDACTED:?https://t.test/x?token=…and?https://a@b=pw@evil.test, whose userinfo runs across the=.?//u:pw&w@evil.test, whose userinfo runs across the&, recordsREDACTED=REDACTED&REDACTED=REDACTED; README → Credentials in a captured value says which pairssuch userinfo takes.
Search
url.fullwith(?i)%(25)*(3f|26|23|3b)[-_]*([^&=%]*(auth|authentication|authorization|consumer[-_]?id|credential|key|key[-_]?id|pass|pass[-_]?phrase|p(ass)?w(or)?d[12]?|secret|sig|sign|signature|signed|token)|code|googleaccessid|id[-_]?token[-_]?hint)[-_]*(=|%(25)*3d),and with
(?i)(^|[?&])[^&=]*%(25)*2F%(25)*2F\S*%(25)*40for a match followed by anythingbut
REDACTED, and rotate what it finds; a presigned SigV4 url only while unexpired, as v2.4.0says.
captureQueryredacts userinfo holding a+,%2F,%3For%23in a kept query. Since v2.3.0,?//u:pw+x@host,?//u:p&a%2Fb&w@hostand?next=//my+user:pw@cb.test/x, withcaptureQueryon, exported the password in
url.full: the query was read form-decoded only, where those turninto a space and delimiters that end userinfo. It is now read as typed too, and userinfo either
reading finds records
REDACTED. Text holding a url and later an@, with only+or%20between, records
REDACTEDtoo, as in?text=Visit+https://app.test+or+mail+help@app.test, so adashboard grouping on such a
url.fullsees it change. Searchurl.fullwith(?i)(//|%(25)*2F%(25)*2F)\S*(@|%(25)*40)and rotate any password a match holds.captureQueryredacts the value of a query key that names a credential, by the key terms ofDatadog's default rule. A key's value records
REDACTEDwhen the key, in any casing and with-and_ignored, ends in a term such astoken,key,secret,passwordorauth, or iscode,googleaccessidoridtokenhint; README → Credentials in a captured value lists them.Since v2.3.0,
log.fetch("https://api.test/me?access_token=…")withcaptureQueryon exportedthe token in
url.full; searchurl.fullwith(?i)[?&][-_]*([^&=]*(auth|authentication|authorization|consumer[-_]?id|credential|key|key[-_]?id|pass|pass[-_]?phrase|p(ass)?w(or)?d[12]?|secret|sig|sign|signature|signed|token)|code|googleaccessid|id[-_]?token[-_]?hint)[-_]*=for a match followed by anything but
REDACTED, and rotate what it finds. Search a spelling witha
-or_inside a term, such aspass_word, for itself. A value that is no secret, such as akeylookup, atokenpagination cursor or anoauthflag, recordsREDACTEDtoo, so adashboard grouping on such a
url.fullsees it change.otlpAdditionalHeaders. Since v1.4.0 for a child and v2.2.0 for a clone,new Log({ parentLog, otlpHttpBaseURI: other })sent the parent's headers, a bearer tokenincluded, to
other; rotate any token that may have reached such a host. Set the headers on thechild where that host should get them.
Queue'sstorageno longer reaches a stringifiedlog.conforqueue.conf.storageisnon-enumerable on
queue.conf, so alocalStoragegiven as one stays out ofJSON.stringifyandof a spread; the v2.4.0 entry says what to rotate. A
Queuebuilt from{ ...queue.conf }has nostorage; passstorageto it by name.http:to a host other thanlocalhost,127.0.0.0/8or::1writes one@larvit/log:warning naming the host and the header, unless theQueuesetsthe new
acceptPlainHttpCredentials: true. A credential header is any whose namelog.fetchredacts, such as
Authorizationorapi-key, set byuser:pass@inotlpHttpBaseURIor inotlpAdditionalHeadersat any time. Each line is written once per host, header and credentialsource: to each
reportfunction, or atwarnto eachstderrfor a queue aLogbuilt. Therequest still goes. Rotate a credential that has crossed a network you do not trust. On one you
do, a
LogusingotlpHttpBaseURImoves itsotlp*options tootlpQueue: new Queue({ acceptPlainHttpCredentials: true, otlpHttpBaseURI }), whose report linesthen go to that queue's
report,console.errorunless you pass one.url. A url parser drops a tab, newline or carriage return, so
https://admin:hun<TAB>ter2@db.test/xhas the password
hunter2, and keeps any other whitespace character percent-encoded, sohttps://admin:hun<NBSP>ter2@db.test/xhas the passwordhun%C2%A0ter2. Since v2.3.0 a capturedheader value that isn't a whole url, and since v2.4.0 a status message from
end({ error })or afailed
log.fetch, exported such userinfo unchanged; so didurl.fullwithcaptureQuery, when atab sat in a query key and the
@was percent-encoded, or another such character sat in a querykey or value. Now no whitespace character but a space ends userinfo after
//,\\,/\or\/: a status message recordsREDACTEDin place of the userinfo, as inretry https://REDACTED@db.test/x, and a header value recordsREDACTEDwhole. Text with nocredential in it is redacted too when such a character sits between its
//and an@://note,a line break and
@mention. Search captured header values, status messages andurl.fullwith(?i)(https?:|([\\/]|%(25)*(2F|5C)){2})[^ ]*(@|%(25)*40)and rotate any password a match holds; amatch reading
REDACTEDbefore its@holds none.Everything else
2022-09-24T23:40:39.123Z [inf] ….It cut the time to whole seconds, so entries written within one second lost their order in a
backend reading
stdout. A parser of the text line sees it change; parseformat: "json"instead, as README → Audience says.
REDACTEDin each shape README →Credentials in a captured value lists. A minor may add a shape. A value holding no credential
may record
REDACTED, as one percent-encoded more than eight times or holding a ninth nested urldoes. A minor may change such a redaction and those limits, so the value may show again. A
credential in any other shape exports as written, text you log and a url you base64-encode into a
request path included.
URLpolyfill. React Native's ownURLand
URLSearchParamsthrow "not implemented" from members thatnew Log({ otlpHttpBaseURI }),new Queueandlog.fetchread, so those calls throw in an app with no polyfill. Nothing in thepackage changed; install one such as
react-native-url-polyfillbefore the app's code uses it.log.fetch(url, request)sends aRequestpassed asinitwith its own method, body, signal andother settings. Before, only its headers were kept, so
log.fetch(url, new Request(url, { method: "POST", body }))sent a GET with no body, though the span named a POST. Now the request is the onefetch(url, request)sends, plustraceparent.maxItemstrim. Before, a failed batch wentback in front of the queue and the trim dropped it first, so an offline app at
maxItemsreported"OTLP export failed, will retry" for items the retry then found gone. Now the trim drops the
oldest items behind that batch, also while entries are logged during the retry wait, and the
batch is retried whole.
storageuntil its send settles. Before, an entry logged duringthe send saved the queue without the batch, so a process that died then lost it.
storagewhosegetItemthrows keeps what it holds. Before, one failed read at startupdeleted the stored queue, and the first save overwrote it. Now the queue reports "OTLP queue
storage unreadable, stored queue kept and not written to", leaves the stored queue as it is, and
writes nothing to it until the next start; new entries and spans are still sent from memory.
Content that reads but isn't a list of payloads is still discarded.
log.enabled(level)never writes, so a library author's check emits no line. Before, anunknown
logLevelmadeenabled()write the warning, and which caller warned depended on callorder. Now only the level methods warn, once per
stderrsink as before, andenabled()stilltreats an unknown
logLevelasinfo.await end()before exit.A script that awaits neither
end()norflush()now exits without exporting what it queued.Before, a queued entry or span kept the process alive for up to
batchDelayMs, and so did anentry logged while a successful export was in flight, after
await log.flush()had returned.@larvit/log, at this package'sversion. A span's scope was its span name, and records had none, so a query or dashboard
grouping on the scope name sees it change; group on the span name instead.
user:pass@inotlpHttpBaseURIbeside anAuthorizationinotlpAdditionalHeaderswritesone
@larvit/log:line perreportfunction, or perstderrfor a queue aLogbuilt, andthrows from 3.0.0. The
otlpAdditionalHeadersAuthorizationis still sent and the userinfo isnot, as in v2.4.0. Keep one of the two.
resolveFormatter(conf)hands back theEntryFormattera conf writes with. ReadresolveFormatter(log.conf)where you readlog.conf.entryFormatter, which 3.0.0 removes.OTLP export unauthorized, batch dropped. It readOTLP export rejected, batch dropped, so an alert matching that text sees it change.captureRequestHeadersorcaptureResponseHeadersis skipped, with onewarnline perstderr. It rejected every traced call, or turned a response the runtimedelivered into a rejection.
floor: Chrome 80, Firefox 74 or Safari 14. v2.4.0 added
??=, which raised the floor toChrome 85 and Firefox 79, so a bundler leaving
node_modulesuntranspiled gave those browsers aSyntaxError. The build now targets ES2020, so it lowers newer syntax and rejects newerbuilt-ins.
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate CLI.