admin管理员组

文章数量:1391995

Some URLs in my single-page-app (SPA) contain sensitive information like an access token, user information, etc.

Examples:

/callback#access_token=HBVYTU2Rugv3gUbvgIUY
/[email protected]

I see that hotjar allows suppressing DOM elements and images from tracked data. Is it possible to hide params in URL or at least disable tracking for some pages?

Some URLs in my single-page-app (SPA) contain sensitive information like an access token, user information, etc.

Examples:

/callback#access_token=HBVYTU2Rugv3gUbvgIUY
/[email protected]

I see that hotjar allows suppressing DOM elements and images from tracked data. Is it possible to hide params in URL or at least disable tracking for some pages?

Share Improve this question edited Feb 13, 2020 at 13:47 B--rian 5,89611 gold badges48 silver badges100 bronze badges asked Feb 10, 2020 at 12:11 Taras HupaloTaras Hupalo 1,3872 gold badges17 silver badges29 bronze badges 2
  • Have you considered putting those data into request headers using AJAX? – boosted_duck Commented Feb 19, 2020 at 2:59
  • Did you try putting, accessing that data through cookies? – Rajendra kumar Vankadari Commented Feb 20, 2020 at 12:30
Add a ment  | 

3 Answers 3

Reset to default 2 +50

Since you are saying that it is your SPA, you might solve the problem by switching from GET requests (which have the parameters inside the URL) to POST requests. I do not know hotjar, but if you tell the tracking service to analyze URLs only, that would be an option worth considering.

Another option frequently used is to obfuscate your parameters in the URL, see e.g. Best way to obfuscate an e-mail address on a website? However, that is never a really safe solution for sensitive data, since the de-ciphering step is too easy, in particular if your man-in-the-middle has all requests ever send to your SPA.

Edit. I just found in the Hotjar allows RegEx. Assuming you could enter a regular expression of URL-parts to exclude. The general syntax /foo/bar/ means that foo should be replaced by bar, in our case, we want to delete the given snippet, that why it is /foo//.

For the given case of the access token, the regular expression would be

/callback#access_token=[a-zA-Z0-9]{15}//

and respectively for the email part of the URL

/\?email=(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])//

This second RegEx partially taken from How to validate an email address using a regular expression?

It seems to me that it's reasonable to assume that tracking scripts will try to access window.location.href or similar to get the current url which they will store.

So a possible solution would be create a dynamic scope which has a different value for window.location.href (with all sensitive info filtered out)

This is how it might work:

// get the tracker script as a string, so you can eval it in a dynamic scope

let trackerScript = 'console.log("Tracked url:", window.location.href)';

// now lets lock it up
function trackerJail(){
  let window = {
    location: {
      // put your filtered url here
      href: "not so fast mr.bond"
    }
  }
  
  eval(String(trackerScript))
}

trackerJail()

If the tracking snippet is wrapped in a function it might be possible to create a dynamic scope for it without running eval by overriding it's prototype instead. But I'm not sure you can count on tracker scripts being wrapped in a neat function you can modify.

Also, there are a couple more ways the script might try to access the URL, so make sure to cover all the exits

If you control the page and order of scripts, you could read the data from the url then delete it before anything else can get to it.

proofOfConcept.html

<script id="firstThingToLoad.js">
    console.log(window.location.href);
    const keyRegex = /key=[^&]*/;
    const key = window.location.href.match(keyRegex);
    console.log("I have key", key);

    const href = window.location.href.replace(keyRegex, "");
    history.replaceState({}, "", href);
</script>

<script id="someSnoopyCode.js">
    console.log("I'm snooping: ", window.location.href);
</script>

<body>
    <a href="/?key=secret">Link to private</a>
</body>

Of course the Link to private should not exist as is. Also, this does break refresh and most navigation in general, though there are ways to catch and save that.

本文标签: javascriptHow to prevent tracking sensitive data in URLsStack Overflow