add: per request statement timeout using prefer header#4584
add: per request statement timeout using prefer header#4584taimoorzaeem wants to merge 1 commit intoPostgREST:mainfrom
Conversation
d074eb9 to
2c5589f
Compare
5f1d601 to
6963e9a
Compare
|
We should also fail in case a value exceeds the per role timeout. Otherwise it's abusable. This failure should happen at the plan level, before hitting the db. I think it will need a new error code. |
a82c07f to
0d6370e
Compare
0d6370e to
6481e8e
Compare
6481e8e to
a37d497
Compare
1998a61 to
cef3feb
Compare
cd53ca3 to
356cecf
Compare
356cecf to
a1f19e7
Compare
001ee79 to
e77acb3
Compare
e52e45f to
77602ac
Compare
4a92e87 to
c8f4f27
Compare
Adds a feature to set `statement_timeout` using `Prefer: timeout` header. This also introduces a `PGRST129` error which is returned when the timeout preferred exceeds the per-role or global timeout. Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
c8f4f27 to
7c49b66
Compare
| failPreferTimeout Preferences{preferTimeout=(Just (PreferTimeout t)), preferHandling=Just Strict} AppConfig{..} AuthResult{..} = | ||
| case roleTimeout of | ||
| Nothing -> Right () | ||
| Just rt -> when (t > rt) $ Left $ ApiRequestError $ TimeoutConstraintError rt |
There was a problem hiding this comment.
This check is problematic because it undermines the whole idea of this header.
Who would want to set the timeout header to a value less than the role setting? What for?
The only realistic use case is that a client might want to increase statement_timeout for a particular query.
So sensible limit is greater than the role setting. Don't know: maybe 2x role setting should be the limit? But then - why not simply set the role setting to a greater value?
Thinking about it: it looks like having any limit is contradictory to the idea of this header. OTOH not having a limit is a security vulnerability. No good choice here, I'm afraid.
@taimoorzaeem @steve-chavez WDYT?
There was a problem hiding this comment.
This check is problematic because it undermines the whole idea of this header.
Thinking about it: it looks like having any limit is contradictory to the idea of this header. OTOH not having a limit is a security vulnerability. No good choice here, I'm afraid.
I think you're right. My idea with the limit was to make the header safe to expose to untrusted clients but that makes it less useful. Also, it might never be totally safe because setting a 1s timeout could force some queries to fail and flood logs on the server.
So this header should fall in the same category as prefer:tx and Accept: application/vnd.pgrst.plan, it can only be exposed to trusted users.
This means it should be gated by a config and that we should remove the statement_timeout limit.
Thoughts?
To expose this header to an untrusted network, a similar thing to https://docs.postgrest.org/en/latest/references/observability.html#securing-the-execution-plan could be used.
Adds a feature to set
statement_timeoutusingPrefer: timeoutheader. This also introduces aPGRST129error which is returned when the timeout preferred exceeds the per-role timeout, which prevents misuse of this feature.Closes #4381.