delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

delete window.intercomSettings on shutdown - #481

Merged
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown
Jun 27, 2022
Merged

delete window.intercomSettings on shutdown#481
devrnt merged 4 commits into
devrnt:masterfrom
ekilah:deleteIntercomSettingsOnShutdown

Conversation

@ekilah

Copy link
Copy Markdown
Contributor

this library adds a new piece of data to window: window.intercomSettings. this piece of data contains data about the intercom user, like their name, email, and even the user_hash, which is a security token used to guarantee the user chatting with you is who they say they are.

This data should be cleared whenever logging out of your application, otherwise that user_hash and other user information is sitting around in the tab after the user has logged out.

shutdown is the API you are supposed to call when logging out, so this function should do this cleanup, too.

hardShutdown does this already, but it also deletes window.Intercom. That's problematic because if someone logs back in in the same session/tab, you don't want window.Intercom to be missing (nothing adds it back)

this library adds a new piece of data to `window`: `window.intercomSettings`. this piece of data contains data about the intercom user, like their name, email, and even the `user_hash`, which is a security token used to guarantee the user chatting with you is who they say they are.
This data should be cleared whenever logging out of your application, otherwise that `user_hash` and other user information is sitting around in the tab after the user has logged out.
`shutdown` is the API you are supposed to call when logging out, so this function should do this cleanup, too.
`hardShutdown` does this already, but it also deletes `window.Intercom`. That's problematic because if someone logs back in in the same session/tab, you don't want `window.Intercom` to be missing (nothing adds it back)
@devrnt

Copy link
Copy Markdown
Owner

Hi, thanks for creating this PR, really appreciate it.

Some remarks: at the moment the shutdown, follows the suggested shutdown flow, see https://www.intercom.com/help/en/articles/16845-how-do-i-end-a-session. I can't find any docs/fora where it's recommended to delete the window.intercomSettings.
If I can't trace back where the cleanup is recommended I'll keep the recommended "shutdown flow".

@ekilah

Copy link
Copy Markdown
ContributorAuthor

I am under the impression that the Intercom library does not read window.intercomSettings directly, though I don't have proof of that one way or another.

Their "Basic Javascript" docs do tell you to set window.intercomSettings, but then the code blob that it tells you to paste right under that just uses that in the update call it makes. I imagine that for non-SPAs the window variable there is just used to have a global you can edit later if needed.

Right below those docs are the separate Single Page Application docs and those instructions never tell you to set window.intercomSettings, and you can see instead the docs just tell you to call window.Intercom('boot')(and update, etc) with the raw settings object as needed. This library's implementation follows the SPA docs by calling window.Intercom('boot'), 'update', etc, but for some reason it also sets window.intercomSettings.

So, it looks like this library is doing a bit of both. I imagine you could just stop setting intercomSettings completely in this library without affecting React SPAs, but I didn't aim to make that large of a change. It would be easy to test - either Intercom works, or it doesn't. I would be shocked if Intercom's JS bundle required window.intercomSettings to be set while also requiring an object in the boot call, but I've seen weirder.

The goal of this PR is just to delete the data about the previously-logged-in user after logging out, which is what the Intercom('shutdown') API already does (by deleting their own cookies). This change is in the spirit of their shutdown docs, though I admit their docs don't mention clearing this directly. I will email their support team, because I think it should be included there, too.


Without this PR's change, if someone logs out of a website using Intercom and leaves the tab open, an attacker could read window.intercomSettings, copy the user_hash stored there, log in to the application as a different user, set their own user_hash to the stolen one, and pretend to be the first user. This is just as bad as not clearing the cookies, which shutdown already does.

@devrnt

Copy link
Copy Markdown
Owner

Thanks for taking your time and explaining this, really appreciate it! I can totally follow your need to remove window.intercomSettings, but as you mentioned I'll wait for the response to your mail. If you receive no response I'll probably merge this anyway, but let's make sure that we don't break any current behaviour

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Sounds good! I sent Intercom a message, we'll see what they say. I'll update here when I receive a response.

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Got a reply yesterday. Their response confirms that they don't expect an SPA integration like this one to be setting window.intercomSettings at all:

Thanks for the report and your patience!

The basic javascript section of the installation guide assumes that the website will be "...a web app with multiple pages where each one triggers a new page refresh..." which means the previous window.intercomSettings object should be destroyed on page navigation (i.e. logout -> homepage). Whereas the single page installation section assumes the opposite, so examples in that section don't set the window.intercomSettings object directly – showing instead to pass the information directly into the messenger's JS API calls.

[...] there isn't a security vulnerability here but we could update our documentation on how to end sessions so it's more explicit about this. I'll follow up with the team to have that updated appropriately – hope that's helpful.

Thanks,
Josh

@devrnt

Copy link
Copy Markdown
Owner

Thanks for the update! so TLDR, window.intercomSettings isn't relevant when Intercom is used in an SPA? The Intercom API expects you to pass in all options/settings through the arguments of the according method?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Correct...! My PR here doesn't remove it completely, but we/you/I could do that instead, or separately.

@hjoelh

Copy link
Copy Markdown

Hey guys, sounds good. Any news here?

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Hi there @hjoelh - I am mostly waiting for @devrnt to reply. I think this PR is mergeable now, and I'd be happy to follow up with a second PR to remove window.intercomSettings completely if that was desired also.

We could combine them into one PR as well if that is easier on @devrnt , I don't have much of a preference, it's just a slightly larger change I think.

My concern was mostly about making sure this library cleaned up after itself, which this PR does already!

@trevorwhealy

Copy link
Copy Markdown

Noticing the same behavior here. Authenticated user sessions are still persisting even after shutdown is called which is exposing the user-protected Intercom articles and chat messages to a logged out user

@ekilah

Copy link
Copy Markdown
ContributorAuthor

@trevorwhealy feel free to delete window.intercomSettings yourself after you call shutdown until this merges, I tested it on my own application and still have that running in production waiting for this to be released 🤓

@devrnt
devrnt merged commit 38db4b9 into devrnt:masterJun 27, 2022
@ekilah
ekilah deleted the deleteIntercomSettingsOnShutdown branch June 27, 2022 17:08
@ekilah

Copy link
Copy Markdown
ContributorAuthor

🥳

@devrnt

Copy link
Copy Markdown
Owner

v2.0.0

@ekilah

Copy link
Copy Markdown
ContributorAuthor

Thanks for the release @devrnt !

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ekilah@devrnt@hjoelh@trevorwhealy