07-04-2016 09:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-04-2016 09:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Fitbit API sends us incorrect header. Here is an example:
Referer:https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fclient_id%3DXXXXXX%26redirect_uri%3Dhttps%253A%252F%252Fdomain%252Fpath%252Ffitbit%252Fcallback%26response_type%3Dcode%26scope%3Dactivity%26state
How to reproduce:
1. User is redirected to Fitbit from our side
2. User logs in and allows our application to access to Fitbit data.
3. User is redirected to our site. (Normal referer header is sent.)
4. User removes all information about Fitbit in our application. (We don't know if user already ask our application to connect with Fitbit.)
5. User logs out from Fitbit.
6. User asks our application to connect with Fitbit second time.
7. User is redirected to Fitbit from our side.
9. User logs in.
10. User is redirected to our site. (Incorrect referer header is sent.)
Our XSS filter rejects requests with data encoded more than once. This is security feature. Multiple-encoded values is used in XSS attacks.
Could you please fix this problem. I can create defect in our bug tracking system if you point me where it is.
Answered! Go to the Best Answer.
Accepted Solutions
07-18-2016 11:58 - edited 07-18-2016 12:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



07-18-2016 11:58 - edited 07-18-2016 12:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Fitbit is doing the correct behavior and your XSS filter is incorrect to assume there are no legitimate reasons to double encode values.
When following your reproduction steps, because the person has not revoked access to your application on Fitbit's side and your application does not request an increase in scope, the person is immediately redirected to your redirect_uri after signing in. This is the documented behavior.
In this particular case, the Referer header will be something like:
https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fclient_id%3D228YX6%26expires_in%26redirect_uri%3Dhttps%253A%252F%252Fexample.com%252F%26response_type%3Dtoken%26scope%3Dactivity%2Bprofile%26state
The `redirect` parameter on Fitbit's /login page is for knowing where to redirect the user after signing in. It must be URI encoded. But in this case, the originating URI contains URI encoded parameters. The `redirect` value will be decoded once for the redirect after signing in. As described above, there will be a double redirect for a previously authorized app. The browser preserves the URI that initiated the redirect sequence. Thus, it is correct to have double encoded values in the Referer header.

07-05-2016 13:24
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-05-2016 13:24
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@JeremiahFitbit Can you help?

07-06-2016 14:14
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



07-06-2016 14:14
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Hey @kostya we're looking in to this now. In the meantime, please provide the following:
- The two different referer headers.
- In step 4, is this where the user is revoking access to your application?
07-07-2016 08:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-07-2016 08:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @DavidSFitbit,
We have fixed this problem on our side by adding prompt=consent in the request.
Incorrect referer header you can find in my first post.
Here is a correct header after adding prompt parameter:
Referer:https://www.fitbit.com/oauth2/authorize?client_id=XXXXXX&prompt=consent&redirect_uri=https%3A%2F%2Fdomain%2Fvitality%2Fpath%2Fcallback&response_type=code&scope=activity&state
The user isn't revoking access. He didn't do anything on Fitbit side, in step 4.
Just want to clarify this is no longer problem for us.

07-08-2016 11:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



07-08-2016 11:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Great! Thanks for letting us know.

07-18-2016 11:58 - edited 07-18-2016 12:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



07-18-2016 11:58 - edited 07-18-2016 12:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Fitbit is doing the correct behavior and your XSS filter is incorrect to assume there are no legitimate reasons to double encode values.
When following your reproduction steps, because the person has not revoked access to your application on Fitbit's side and your application does not request an increase in scope, the person is immediately redirected to your redirect_uri after signing in. This is the documented behavior.
In this particular case, the Referer header will be something like:
https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fclient_id%3D228YX6%26expires_in%26redirect_uri%3Dhttps%253A%252F%252Fexample.com%252F%26response_type%3Dtoken%26scope%3Dactivity%2Bprofile%26state
The `redirect` parameter on Fitbit's /login page is for knowing where to redirect the user after signing in. It must be URI encoded. But in this case, the originating URI contains URI encoded parameters. The `redirect` value will be decoded once for the redirect after signing in. As described above, there will be a double redirect for a previously authorized app. The browser preserves the URI that initiated the redirect sequence. Thus, it is correct to have double encoded values in the Referer header.

07-18-2016 14:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-18-2016 14:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hello @JeremiahFitbit,
Thank you for answer.
We are using 'The OWASP Enterprise Security API' to check values. The explanation why double encoded data can be dangerous here: https://www.owasp.org/index.php/Double_Encoding
Sorry if my first post wasn't polite for somebody. It's just other point of view.

