Skip to content

Exclude accessToken in cache #2526

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

Closed
bmarden opened this issue Jul 19, 2022 · 3 comments
Closed

Exclude accessToken in cache #2526

bmarden opened this issue Jul 19, 2022 · 3 comments

Comments

@bmarden
Copy link

bmarden commented Jul 19, 2022

Hello, we are using redux toolkit and RTK Query in an expo based React Native project. We recently did some internal auditing and discovered that RTK Query's (we think) cache is saving the entire request and response objects.

This presents a problem in that the user's accessToken is also saved in this cache. Our goal is to prevent this accessToken from being saved anywhere in the cache to reduce potential attack vectors.

{
  "type": "api.response",
  "payload": {
    "request": {
      "url": "https://example.api.com",
      "method": "PUT",
      "data": "{...}",
      "headers": {
        "content-type": "application/json",
        "authorization": "Bearer 'access token we want to hide'"
      },
      "params": "~~~ null ~~~"
    },
    "response": {
      "body": {},
      "status": 200,
      "headers": {}
    },
    "duration": 528
  },
  "important": "~~~ false ~~~",
  "date": "2022-07-17T21:31:42.104Z",
  "deltaTime": 559
}

I'm not 100% sure this is even coming from RTK Query, but I don't think there is anything else that would be storing the entire request/response in this format. From what I've seen using Reactotron dev tools and inspecting the state for api, there isn't anything that is formatted exactly like this. However, I've had a hard time figuring out what the internal cache key and object looks like.

I found this issue #1904, which seems like what may be causing the accessToken to be included in the cache. . We are currently setting our header in the same way using prepareHeaders within fetchBaseQuery.

Sorry for the long explanation, but my question is:
Is there a way to prevent the accessToken from being stored in the cache at all? If so, how would we do that? Thank you!

@phryneas
Copy link
Member

phryneas commented Jul 20, 2022

"type": "api.response", does not look like anything RTK Query is doing, so you'll have to search elsewhere.

RTK Query does not directly cache the request or response headers, you can click through the devtools to verify that. All that's going to be stored is response bodies. If you send your token as a response, it will be stored, but if you use a mutation it will also be gone once the requesting component unmounts.

Apart from that though: if your JavaScript can access your access token, it can access the access token - there is not a lot of security to be gained from only saving it in place A or B. The point here is "JavaScript accessible". If your attack scenario includes external JavaScript injected into your site (via third-party resources or a browser extension), it's insecure. If that cannot happen, it's probably okay but not best practice.

Best practice would in all cases be to use a httpOnly cookie sent by the server as that will automatically be exchanged between client and server without ever being accessible from JavaScript in the first place.

@bmarden
Copy link
Author

bmarden commented Jul 20, 2022

Hi phyrneas, thanks for the response. I figured that it might not be rtk query storing it, but that helps to rule this out.

As far as storing it as an httpOnly cookie, it's a react native project so we are storing the accessToken in expo's SecureStore and want to keep it there only. I didn't think httpOnly cookies worked with RN, but maybe I'll look into that again and see if I can figure something out.

I'll close this, since this isn't related to redux toolkit. Thanks! :)

@bmarden bmarden closed this as completed Jul 20, 2022
@phryneas
Copy link
Member

In that case, as long as you are not loading external JavaScript into your application, having it in a Redux store or not doesn't make any difference to a normal variable (because that's what Redux is) - just don't persist it into unsafe storage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants