hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.17k stars 2.77k forks source link

docs: document security for action handlers #4645

Closed danielkcz closed 1 year ago

danielkcz commented 4 years ago

Current behavior

By default, the action handlers have a single security layer - by obscurity. Unless action handlers URLs are predictable or stored somewhere (migration files in VCS).

The second "easy" protection layer is setting up roles for the backend while using the admin secret. That certainly helps prevent unwanted access to data but it still doesn't prevent anyone from calling that handler directly. Without proper checks in those handlers, it could be breaking the app flow unexpectedly.

Enabling "Forward client headers to webhook" for action handlers means we get the Authorization header, but without knowing the signature key we cannot easily validate it. Nor I don't feel we should.

Proposed solution

There was some discussion at Discord today and some said they have their own solution for rotating keys that are sent to headers of action handler.

While that's nice, I wonder why everyone has to develop such a solution on their own. I think Hasura should have additional security layer out of the box.

I have the following idea that's definitely rough around the edges as I am not a security expert. I haven't used migrations in practice yet so I am not sure how it would work there.

Auto-generated action secret

Hasura can auto-generate a secret key (different from admin secret) which is then passed to all action handlers in headers/body. This secret would be manually obtainable from the console and could be stored in action handlers env. Alternatively, the backend could run an admin-only graphql query to obtain the current (and previous) secret (in serverless) or even a subscription (with a full server).

The main point this is solving is to avoid manually updating each action one-by-one. The generated secret would be automatically used for all the actions or opt-out completely.

Additionally, the rotation of such a key would be useful in case of an accidental leak. It's probably enough to do it manually.


In other words ... https://github.com/hasura/graphql-engine/issues/4645#issuecomment-643344612 and https://github.com/hasura/graphql-engine/issues/4645#issuecomment-644491468. No need to read rest which mainly focuses on making a more secure variant with HMAC which isn't part of this issue.

njaremko commented 4 years ago

Still trying to sneak hmac into this, eh? 😛

In your example, you're required to have the admin secret (which I'll assume is a separate action secret) on both ends to create/verify the hmac, in which case you can just include it directly as a header or as part of the request session variables and rely on TLS.

As I said above, adding hmac to hasura at all is a separate issue.

haf commented 4 years ago

@njaremko Lol, well, it's a standard cryptographic primitive for a reason.

In your example, you're required to have the admin secret (which I'll assume is a separate action secret) on both ends to create/verify the hmac,

No, again, this is wrong. You have to have this key;

43312aced847bc29bc4504f4660f04ba10fae8753a0a8c9f6ceac18299e845da

on the client-side. On the server-side, Hasura, you always have an admin key when you're in production. But if you unintentionally expose this derived key, an attacker cannot derive the master key from it, and you can rotate it by setting an action variable. Do I need to implement this in both Haskell and handler code, for you to understand me?

As I said above, adding hmac to hasura at all is a separate issue.

As I said above and gave Haskell code for doing, HMAC is a cryptographic primitive and is present in basically all standard libraries. I don't understand your love for TLS; it's called transport layer encryption for a reason and is not about message validation or app-level auth for the umpteenth time.

njaremko commented 4 years ago

You're hijacking this issue again. If you want to discuss HMAC (I'd love to), make a separate issue, it doesn't belong here.

We're trying to automate an existing hasura authentication flow, not invent a new one.

webdeb commented 4 years ago

The title of this issue is just "Built-in security for action handlers". It does not exclude anything.

  1. I agree, that HMAC should go into a separate issue, maybe a RFC, with code examples and implementation details for different backends especially nodejs / express, to show it in glitch.

  2. The idea of one ACTION_KEY makes sense (on the first view), but it's limited, because people are using different backends, and you probably do not want to share a single key between backends.

  3. Like already mentioned, the OP asked for a security concept. So the answer is already described in the docs as we figured out: https://hasura.io/docs/1.0/graphql/manual/actions/action-handlers.html#securing-your-action-handler

@FredyC personally I am suggesting to close it. At the end of this week there will be about 1000 issues here. So for all those who are reading this, I would like to encourage you to help to clean this board.

njaremko commented 4 years ago
  1. I agree HMAC authentication should be a different issue, an RFC makes sense, it'll need justification (I think it could be justified, but not for the reasons people have tried above. You'd have to argue that plain HTTP endpoints are valid).
  2. It's definitely limiting, but it's probably sufficient for 99% of use cases (single key between backends isn't really a huge issue if you own them all), and the remaining 1% can do fancy stuff like calling the hasura management api to configure random secrets at runtime.
  3. I think the issue started with wanting two things, a way to secure endpoints (already exists and is documented because of this issue), and a way to automatically do that for your endpoints (which the proposed automatic inclusion of an "action secret" if you provide a HASURA_ACTION_SECRET env var solves)
  4. Not sure why you suggest closing it. To reopen and get more attention?
webdeb commented 4 years ago

Yes, I would reopen a new one to keep the attention focused on a concrete suggestion. This thread is already too over-flooded. It's unreasonable to let others go through all of it to take decisions. I am even not sure what the current suggestion here is.

Personally I am also for the 2. its actually simple enough to do, but it makes sense to have it built-in, to have a standard flow of defining it each time you would need it.

  1. set HASURA_AUTH_KEY
  2. If set: Opt-In in the console, checkbox to include the default HASURA_AUTH_KEY into the headers (events, actions, remote graphql servers)
danielkcz commented 4 years ago

I think my initial comment is still good enough to summarize what is this about. I've updated it and linked to some comments summarizing the idea. I don't see a need to close this.

jbek7 commented 3 years ago

I still don't get why hasura is not sending Authorization header to mutation action webhook? I need the Authorization header to extract user to associate with the action.

aroraenterprise commented 3 years ago

You get x-hasura-user-Id in the action. You don’t need the authorization token.

On Tue, Sep 14, 2021 at 1:39 PM Bek @.***> wrote:

I still don't get why hasura is not sending Authorization header to mutation action webhook? I need the Authorization header to extract user to associate with the action.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_hasura_graphql-2Dengine_issues_4645-23issuecomment-2D919370965&d=DwMCaQ&c=slrrB7dE8n7gBJbeO0g-IQ&r=8_YpxMTBaJijwQRqgmU3BA&m=C5jCMCJJz7WnnY9Im9mzfJizNMwqssBRINj0Rnt0gbE&s=6-GNjURz-ry7IVCpgAIrcQZqohFVbDhP2xCX021J4vs&e=, or unsubscribe https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_notifications_unsubscribe-2Dauth_ACTJTZ7MTPRUCC4OL6JQOP3UB6CEHANCNFSM4MXLFDDQ&d=DwMCaQ&c=slrrB7dE8n7gBJbeO0g-IQ&r=8_YpxMTBaJijwQRqgmU3BA&m=C5jCMCJJz7WnnY9Im9mzfJizNMwqssBRINj0Rnt0gbE&s=Zn0c55mQxpz4r1nv9p0FxAYnwZKQSWrr2r8vapzFSGc&e= . Triage notifications on the go with GitHub Mobile for iOS https://urldefense.proofpoint.com/v2/url?u=https-3A__apps.apple.com_app_apple-2Dstore_id1477376905-3Fct-3Dnotification-2Demail-26mt-3D8-26pt-3D524675&d=DwMCaQ&c=slrrB7dE8n7gBJbeO0g-IQ&r=8_YpxMTBaJijwQRqgmU3BA&m=C5jCMCJJz7WnnY9Im9mzfJizNMwqssBRINj0Rnt0gbE&s=VZNmAGzhzz3FHFrm4qRal7zZClggojOSfrHJBKOJP9U&e= or Android https://urldefense.proofpoint.com/v2/url?u=https-3A__play.google.com_store_apps_details-3Fid-3Dcom.github.android-26referrer-3Dutm-5Fcampaign-253Dnotification-2Demail-2526utm-5Fmedium-253Demail-2526utm-5Fsource-253Dgithub&d=DwMCaQ&c=slrrB7dE8n7gBJbeO0g-IQ&r=8_YpxMTBaJijwQRqgmU3BA&m=C5jCMCJJz7WnnY9Im9mzfJizNMwqssBRINj0Rnt0gbE&s=2ir6cwrNJ9cyi9qJbtLoAiJr5DnFhmuu9c7lmc5S9wI&e=.

tirumaraiselvan commented 1 year ago

I guess it should be at least documented in a better way. Maybe some blog article about securing actions could come out of this :)

Hey folks, we have added the documentation for securing your Action handlers here: https://hasura.io/docs/latest/actions/action-handlers/#securing-action-handlers

Feel free to raise another ticket for any enhancement to security features for Actions.