-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat: Introduce 'sanitizeKeys' config option #1264
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -535,6 +535,30 @@ function serializeKeysForMessage(keys, maxLength) { | |
| return ''; | ||
| } | ||
|
|
||
| function sanitize(input, sanitizeKeys) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how does this deal with cycles? or will the data be guaranteed by this point not to have any? how strong is that guarantee? (afraid of freezing a browser in some weird scenario) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It didn't. Thanks for catching that! |
||
| sanitizeKeys = isArray(sanitizeKeys) ? sanitizeKeys : []; | ||
|
||
| var sanitizeMask = '********'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i know we use asterisks elsewhere, but i think something explicit like probably not worth breaking with the precedent though |
||
|
|
||
| if (isArray(input)) { | ||
| return input.map(function(val) { | ||
| return sanitize(val, sanitizeKeys); | ||
| }); | ||
| } | ||
|
|
||
| if (isPlainObject(input)) { | ||
| return Object.keys(input).reduce(function(acc, k) { | ||
| if (sanitizeKeys.indexOf(k) > -1) { | ||
| acc[k] = sanitizeMask; | ||
| } else { | ||
| acc[k] = sanitize(input[k], sanitizeKeys); | ||
| } | ||
| return acc; | ||
| }, {}); | ||
| } | ||
|
|
||
| return input; | ||
| } | ||
|
|
||
| module.exports = { | ||
| isObject: isObject, | ||
| isError: isError, | ||
|
|
@@ -566,5 +590,6 @@ module.exports = { | |
| fill: fill, | ||
| safeJoin: safeJoin, | ||
| serializeException: serializeException, | ||
| serializeKeysForMessage: serializeKeysForMessage | ||
| serializeKeysForMessage: serializeKeysForMessage, | ||
| sanitize: sanitize | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,107 +3,100 @@ import Raven = require('..'); // or import * as Raven from '..' | |
| Raven.config('https://[email protected]/1').install(); | ||
|
|
||
| var options: Raven.RavenOptions = { | ||
| logger: 'my-logger', | ||
| ignoreUrls: [ | ||
| /graph\.facebook\.com/i, | ||
| 'graph.facebook.com' | ||
| ], | ||
| ignoreErrors: [ | ||
| /fb_xd_fragment/, | ||
| 'fb_xd_fragment' | ||
| ], | ||
| includePaths: [ | ||
| /https?:\/\/(www\.)?getsentry\.com/, | ||
| 'https://www.sentry.io' | ||
| ], | ||
| whitelistUrls: [ | ||
| /https?:\/\/google\.com/, | ||
| 'https://www.google.com' | ||
| ], | ||
| autoBreadcrumbs: { | ||
| xhr: false, | ||
| console: false, | ||
| dom: true, | ||
| location: false, | ||
| sentry: true | ||
| }, | ||
| breadcrumbCallback: function (data) { | ||
| return data | ||
| } | ||
| logger: 'my-logger', | ||
| ignoreUrls: [/graph\.facebook\.com/i, 'graph.facebook.com'], | ||
| ignoreErrors: [/fb_xd_fragment/, 'fb_xd_fragment'], | ||
| includePaths: [/https?:\/\/(www\.)?getsentry\.com/, 'https://www.sentry.io'], | ||
| whitelistUrls: [/https?:\/\/google\.com/, 'https://www.google.com'], | ||
| autoBreadcrumbs: { | ||
| xhr: false, | ||
| console: false, | ||
| dom: true, | ||
| location: false, | ||
| sentry: true | ||
| }, | ||
| breadcrumbCallback: function(data) { | ||
| return data; | ||
| }, | ||
| sanitizeKeys: ['token', 'userPassword', 'csrf_token'] | ||
| }; | ||
|
|
||
| Raven.config('https://[email protected]/1', options).install(); | ||
|
|
||
| var throwsError = () => { | ||
| throw new Error('broken'); | ||
| throw new Error('broken'); | ||
| }; | ||
|
|
||
| try { | ||
| throwsError(); | ||
| } catch(e) { | ||
| Raven.captureException(e); | ||
| Raven.captureException(e, {tags: { key: "value" }}); | ||
| throwsError(); | ||
| } catch (e) { | ||
| Raven.captureException(e); | ||
| Raven.captureException(e, {tags: {key: 'value'}}); | ||
| } | ||
|
|
||
| // ErrorEvent requires at least Typescript 2.3.0 due to incorrect ErrorEvent definitions | ||
| // prior to that version. | ||
| var throwsErrorEvent = () => { | ||
| throw new ErrorEvent('oops', {error: new Error('Oops')}); | ||
| throw new ErrorEvent('oops', {error: new Error('Oops')}); | ||
| }; | ||
|
|
||
| try { | ||
| throwsErrorEvent(); | ||
| } catch(ee) { | ||
| Raven.captureException(ee); | ||
| Raven.captureException(ee, {tags: { key: "value" }}); | ||
| throwsErrorEvent(); | ||
| } catch (ee) { | ||
| Raven.captureException(ee); | ||
| Raven.captureException(ee, {tags: {key: 'value'}}); | ||
| } | ||
|
|
||
| Raven.captureException('Something broke'); | ||
| Raven.captureException('Something broke', {tags: { key: "value" }}); | ||
| Raven.captureException('Something broke', {tags: {key: 'value'}}); | ||
|
|
||
| Raven.context(throwsError); | ||
| Raven.context({tags: { key: "value" }}, throwsError); | ||
| Raven.context({tags: {key: 'value'}}, throwsError); | ||
| Raven.context(throwsErrorEvent); | ||
| Raven.context({tags: { key: "value" }}, throwsErrorEvent); | ||
| Raven.context({tags: {key: 'value'}}, throwsErrorEvent); | ||
|
|
||
| setTimeout(Raven.wrap(throwsError), 1000); | ||
| Raven.wrap({logger: "my.module"}, throwsError)(); | ||
| Raven.wrap({logger: 'my.module'}, throwsError)(); | ||
| Raven.wrap(throwsErrorEvent)(); | ||
| Raven.wrap({logger: "my.module"}, throwsErrorEvent)(); | ||
| Raven.wrap({logger: 'my.module'}, throwsErrorEvent)(); | ||
|
|
||
| Raven.setUserContext(); | ||
| Raven.setUserContext({ | ||
| email: '[email protected]', | ||
| id: '123' | ||
| email: '[email protected]', | ||
| id: '123' | ||
| }); | ||
|
|
||
| Raven.setExtraContext({foo: 'bar'}); | ||
| Raven.setExtraContext(); | ||
| Raven.setTagsContext({env: 'prod'}); | ||
| Raven.setTagsContext(); | ||
| Raven.clearContext(); | ||
| var obj:Object = Raven.getContext(); | ||
| var err:Error = Raven.lastException(); | ||
| var obj: Object = Raven.getContext(); | ||
| var err: Error = Raven.lastException(); | ||
|
|
||
| Raven.captureMessage('Broken!'); | ||
| Raven.captureMessage('Broken!', {tags: { key: "value" }}); | ||
| Raven.captureMessage('Broken!', { stacktrace: true }); | ||
| Raven.captureMessage('Warning', { level: 'warning' }); | ||
| Raven.captureMessage('Broken!', {tags: {key: 'value'}}); | ||
| Raven.captureMessage('Broken!', {stacktrace: true}); | ||
| Raven.captureMessage('Warning', {level: 'warning'}); | ||
| Raven.captureBreadcrumb({ | ||
| message: "This is a breadcrumb message." | ||
| message: 'This is a breadcrumb message.' | ||
| }); | ||
| Raven.captureBreadcrumb({ | ||
| category: 'console', | ||
| level: 'log', | ||
| message: 'A console.log() message' | ||
| }); | ||
| Raven.captureBreadcrumb({category: "console", level: "log", message: "A console.log() message"}); | ||
|
|
||
| Raven.setRelease('abc123'); | ||
| Raven.setEnvironment('production'); | ||
|
|
||
| Raven.setDataCallback(function (data: any) {}); | ||
| Raven.setDataCallback(function (data: any, original: any) {}); | ||
| Raven.setShouldSendCallback(function (data: any) {}); | ||
| Raven.setShouldSendCallback(function (data: any, original: any) {}); | ||
| Raven.setDataCallback(function(data: any) {}); | ||
| Raven.setDataCallback(function(data: any, original: any) {}); | ||
| Raven.setShouldSendCallback(function(data: any) {}); | ||
| Raven.setShouldSendCallback(function(data: any, original: any) {}); | ||
|
|
||
| Raven.showReportDialog({ | ||
| eventId: 'abcdef123456' | ||
| eventId: 'abcdef123456' | ||
| }); | ||
|
|
||
| Raven.setDSN('https://[email protected]/2'); | ||
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.
(worth being explicit here that this doesn't scrub or match on string values or query encoded data)
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.
also worth mentioning that sentry itself can do do server side sanitizing and this is different
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.
basically i think people are really gonna want to know what guarantees they get from this feature so it's worth writing a longer explanation