Reputation: 17
Could anyone explain what are the security pitfall of storing a session(sensitive) data in (new Map()) constructor. The data live throughout the life cycle of the app unless the browser tab is then closed. According to MDN it says that all data types can be stored in it, so i guess if binary data type are included. (Just a clue)
In my code
class example {
constructor() {
this.cache = new Map();
this.loc = window.location.href;
}
async getdata() {
let data;
if (this.cache.has(this.loc)) {
data = this.cache.get(this.loc);
} else {
let res = fetch(this.loc);
if (res.ok) {
data = res.json();
this.cache.set(this.loc, data);
}
}
// use data here e.g
`<span>${data.username}</span>`
}
}
Upvotes: 1
Views: 354
Reputation: 4877
There are no specific security concerns with a Map vs any other data structure like an object or a string constant.
They are vulnerable to the same classes of attack - dumping memory, access to global variables.
I would put it inside a closure and pass around the reference to the closure in the application to make it opaque to any other code running on the page.
See this article for more discussion on avoiding global exposed state: https://joshwulf.com/blog/2020/02/avoid-global-state/
In terms of structuring your code, I would use more of separation of concerns - like this:
class DataCache {
constructor(href) {
this.cache = new Map();
this.loc = href;
}
async _fetchData() {
const res = await fetch(this.loc);
if (res.ok) {
data = res.json();
this.cache.set(this.loc, data);
return data
}
}
async getdata() {
return (this.cache.has(this.loc)) ? this.cache.get(this.loc) : this._fetchData()
}
}
And then do DOM manipulation somewhere else.
This way your class is more testable, although it does still do a URL fetch, which is a side-effect.
So something else constructs it and passes in the window.location.href
, calls getdata
, and then updates the DOM.
Upvotes: 1