bridge
bridge copied to clipboard
cache-control: max-age=0, private not working and causing info leak
Environment
- Operating System:
Windows_NT
- Node Version:
v14.19.1
- Nuxt Version:
2.16.0-27616340.013f051b
- Package Manager:
[email protected]
- Builder:
webpack
- User Config:
srcDir
,alias
,server
,bridge
,head
,serverMiddleware
,css
,styleResources
,plugins
,buildModules
,gtm
,modules
,postcss
,tailwindcss
,typescript
,sentry
,buefy
,image
,axios
,proxy
,render
,i18n
,router
,build
,serverHandlers
,devServerHandlers
- Runtime Modules:
@nuxt/[email protected]
,@nuxtjs/[email protected]
,[email protected]
,@nuxtjs/[email protected]
,@nuxtjs/[email protected]
,[email protected]
,@nuxtjs/[email protected]
,[email protected]
- Build Modules:
()
,@pinia/[email protected]
,@nuxtjs/[email protected]
,@nuxtjs/[email protected]
,@nuxtjs/[email protected]
,@nuxtjs/[email protected]
,@nuxtjs/[email protected]
,@nuxt/[email protected]
Reproduction
I cannot reproduce because this situation happens very comlex code base.
Describe the bug
Although cache-control: max-age=0, private is set in Response Header, nuxt caches this request and this response is returned to other users. Because of this, I am experiencing an info leak.
This only happening on ssr.
Additional context
Our project running in docker and AWS.
Logs
No response
@antlionguard Would you provide a simple reproduction showing how a route ends up being cached? Have you enabled nitro caching on any routes?
@antlionguard Would you provide a simple reproduction showing how a route ends up being cached? Have you enabled nitro caching on any routes?
I will try to create reproduction. And i don't use nitro. Nitro is set false in bridge config.
If you are not using nitro then this is almost certainly not an issue with Bridge. But will happily look at reproduction just in case!
If you are not using nitro then this is almost certainly not an issue with Bridge. But will happily look at reproduction just in case!
Oh probably there's completely different problem exist from pinia. Not related with "cache-control" header or axios, nitro etc.
I have a question. Pinia has any ssr caching mechanism? Do you know this?
There's simple code example from my nuxt-bridge project.
Part of <script setup>
Country Select Component (This component wrapped by <client-only>
. That's an important point):
...
// Country Fetch
const isFetching = ref(true);
const countryOptions = ref();
typeStore.fetchCountryList().then(() => {
countryOptions.value = typeStore.countryList;
isFetching.value = false;
});
...
countryList method inside typeStore (this is pinia store):
...
async fetchCountryList() {
try {
if (isEmpty(this.countryList)) {
const { data } = await this.$nuxt.$api.commonServicesV2.fetchCountryList();
this.countryList = data.data;
}
} catch (error) {
**********
}
},
...
When i refresh the page i cannot see in network tab commonServicesV2.fetchCountryList
was called but countryList is filled. It seems like pinia states was stored on server side. That's very interesting to me. Or there is something I missed about pinia? Shouldn't pinia states only work on the clientside and not be cached?
Ah. Wrapping in <client-only>
doesn't mean that those components don't load on the server - it only means that no HTML is emitted. They may all still run. So if you are initialising and filling a store there, it will be filled even though the HTML isn't rendered.
I'm facing a problem similar to https://github.com/aws-amplify/amplify-js/discussions/7611 Maybe this reproduction will help to solve problem.
And i added cache-control header and that's didn't work. I removed all ssr fetching for user information and ssr authentication for temporarily until this problem is fixed.
And i'm trying to create minimal reproduction.
Oh that's not related with headers or caching.
auth-data-load middleware ->
The code i marked causing problem. If i try read cookie on ssr nuxt(or node idk) returns another user token if both users refresh same time. Any ideas for this? @danielroe am i missing something? Or is this usage is bad practice?
That sounds cross-request state pollution and I would investigate pinia in that case. It doesn't sound like a Bridge issue.
That sounds cross-request state pollution and I would investigate pinia in that case. It doesn't sound like a Bridge issue.
https://vuejs.org/guide/scaling-up/ssr.html#cross-request-state-pollution
There's some recommendations here but i couldn't figure out how to do in nuxt.
It shouldn't be something you need to do. Both Nuxt + pinia should ensure this. Would you create a minimal reproduction so I can look into it further? :pray:
It shouldn't be something you need to do. Both Nuxt + pinia should ensure this. Would you create a minimal reproduction so I can look into it further? 🙏
Here's the reproduction -> https://github.com/antlionguard/cross-request-state-pollution-pinia-nuxt
Reproduction steps:
- install deps.
- yarn build and yarn start (because this not happening on development)
- open 2 browser (i tried with firefox and chrome)
- press set token button in the browser on the right
- and refresh left side browser and after that refresh browser on the right asap (refresh order is important)
example image
The issue is that you are defining your state outside of the factory function:
const InitialAuthState: AuthState = {
token: '',
};
export const useAuthStore = defineStore('auth', {
state: (): AuthState => InitialAuthState,
})
That is why it is shared.
Although the factory function is called fresh each time, it returns the same object. The point of a factory function is to return a different object each time it's called.