View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0010172 | Taler | merchant backend | public | 2025-07-09 16:55 | 2025-07-10 09:25 |
Reporter | sebasjm | Assigned To | Florian Dold | ||
Priority | normal | Severity | major | Reproducibility | have not tried |
Status | feedback | Resolution | open | ||
Summary | 0010172: should not be able to create to create tokens with a token | ||||
Description | This works, and I can use the token returned to create more tokens (on any scope) $ curl 'http://merchant.taler.test/private/token' -H 'Authorization: Bearer secret-token:GVP8MZ2R22XGNY1KA9Q72RVMHZZ0E7K35E924ZJQECJTT0TFQ6NG' --data-raw '{"scope":"all","duration":{"d_us":"forever"}}' { "access_token": "secret-token:H6QTCSWAD2458EDG09J3JCH98N63ARM0SCXKG4EM3PMP6W942CP0", "token": "secret-token:H6QTCSWAD2458EDG09J3JCH98N63ARM0SCXKG4EM3PMP6W942CP0", "scope": "all", "refreshable": false, "expiration": { "t_s": "never" } } The problem is that this is the normal token used by the merchant SPA. I think we should either have a special scope for tokens to create new tokens (1) or only allow the creation of tokens with Basic, not Bearer (2). I think (2) is the simplest and safest. We can also go for (1) for a "spa-session" scope. This allows the full management (like all) but prevents the creation of new tokens if leaked. | ||||
Tags | No tags attached. | ||||
|
You should not be able to create a token with a broader scope than the one you present. I also though it had to be refreshable. Need to check the code. |
|
What is the "normal token used by the SPA"? Because we do not have a scope for that, so I guess you already have a scope with "all". So your description would not be correct. We can define a special scope for SPAs, if you can provide me with a clear requirement and set of permissions required. |
|
(Note: "all" always was and still is defined as "can do anything including refresh") |
|
We cannot limit the token endpoint to only Basic, because that is what ":refreshable" is about. |
|
Your proposal (1) also does not work, because you can request scope "spa-session:refeshable" and get a token that can be refreshed. |
|
The SPA clearly should ask for a non-refreshable token, possibly with a lifetime restriction that the user can configure on login. When the SPA is used to create *another* token for export, I think it makes sense for the SPA to require the user to re-enter username/password for this. Maybe this is a pure SPA issue and not something that requires changes in the backend? |
|
1) the only way to create a new session should be using username and password (or even 2fa) 2) the refresh mechanism re-create the __same__ token (not a new one, in fact, refreshing should invalidate the previous one) This way the user can keep control of the number of open sessions for an account. I have shown a way to overcome this two restriction, having a token I can create a new token without user/password and a token without refresh. a) do we want to have a scope that allow user of the token to create new tokens? (like the "all" scope) (consider that the user of the token may be a script or third party) I think this is wrong, I don't see any reason why this would be a good idea and the merchant could potentially find an unreasonable amount of new open sessions. b) how can we fix this? I proposed 2 ways: - only allow the creation of tokens using usr/pwd, the refreshing explained in (2) should care about the rest. - modify the scope definition to exclude token creation permission or to ask for it if needed (again I don't see why but you sound like you have a reason) If you insist on having a scope that can create tokens, then we need a scope that have "all - creation_of_tokens" __by definition__ since the SPA backoffice should have access to all API but the UI will ask (and test) user password before creating a new token. > The SPA clearly should ask for a non-refreshable token, possibly with a lifetime restriction that the user can configure on login. The spa will always ask for refreshable and max duration, this allows the backend server to impose the expiration (spa always check expiration independently of duration). It needs to be refreshable so the session only ends with the user hitting "log out" (or app close for too long) Asking for non-refreshable token will make the SPA prompt for "enter the username and password again" before expiration (manually refresh) this is worse UX. > When the SPA is used to create *another* token for export, I think it makes sense for the SPA to require the user to re-enter username/password for this. The creation of new token is working as you describe. SPA ask for password (and test it) even if not required right now (that's why I'm creating this issue against backend). Password is always thrown away after used, the SPA never ever saves the password. > You should not be able to create a token with a broader scope than the one you present Off course, this is not the case. In the example I have started the issue I'm asking for a token (H6QT) with refreshable:false using the token (GVP8). I succeded to create a new token without user/password (using token GVP8 and also using token H6QT) with a token which is not refreshable which makes refreshable property useless. I can also use H6QT again in the same way. > What is the "normal token used by the SPA"? A token with scope "all", since the spa session should have access to all endpoints no other scope make sense. |
|
The token with scope all is always refreshable. That is actually a bug: The "refreshable" field is set incorrectly in this special case and the refreshability is not indicated. You claim (1) is still unsubstantiated and everything hinges on the argument why this is a requirement. Why should this not be possible? See also https://oauth.net/2/refresh-tokens/ on how this is a common pattern. If you mean that the token refresh should invalidate an old token I agree. That would also be a new requirement an behaviour, but I can see why it makes sense. Tokens are also not sessions. Maybe that is the case for the SPA but a token is simply a token. The bigger problem is that we are mixing access tokens from login (session tokens) with third party access tokens. Those are actually thwo different things. Maybe this requires a bigger refactor: Separate login tokens (/private/token) from third party tokens (/private/third_party/token) I think in general we are using terms here in the wrong way. Like access token, session and refresh. |
|
Ok, I'm also not sure that we need this, schanzen's arguments here seem quite reasonable. Shall we "wontfix" it? |
Date Modified | Username | Field | Change |
---|---|---|---|
2025-07-09 16:55 | sebasjm | New Issue | |
2025-07-09 17:03 | Christian Grothoff | Assigned To | => schanzen |
2025-07-09 17:03 | Christian Grothoff | Status | new => assigned |
2025-07-09 18:07 | schanzen | Note Added: 0025469 | |
2025-07-09 18:09 | schanzen | Note Added: 0025470 | |
2025-07-09 18:11 | schanzen | Note Added: 0025471 | |
2025-07-09 18:12 | schanzen | Note Added: 0025472 | |
2025-07-09 18:12 | schanzen | Note Added: 0025473 | |
2025-07-09 20:37 | Christian Grothoff | Note Added: 0025474 | |
2025-07-09 20:37 | Christian Grothoff | Assigned To | schanzen => sebasjm |
2025-07-09 20:37 | Christian Grothoff | Status | assigned => feedback |
2025-07-10 04:23 | sebasjm | Note Added: 0025479 | |
2025-07-10 07:53 | schanzen | Note Added: 0025480 | |
2025-07-10 09:25 | Christian Grothoff | Note Added: 0025485 | |
2025-07-10 09:25 | Christian Grothoff | Assigned To | sebasjm => Florian Dold |