Security 101

I am using Dgraph cloud and am currently adding various security layers to prevent maliscious attacks. I built a social network and chose Dgraph to manage the deep relationships between users. However, now that I am trying to implement security rules on the backend, I am starting to struggle. There are a number of things that I would need to confidently publish my app:

  1. Field authorization
    An example for this would be private users. While the frontend will not display content stemming from private users, I want to secure private users’ posts on the backend as well. This means that first of all, private users’ posts should not be visible to the public, unless a private user accepted a follow request. To implement this, combined with general authorization, I believe I need some kind of nested auth rules.
    When setting my auth rules like this, an authenticated user can query their own profile, and users that are not private. However, I only want to hide private users’ posts, so that their profile would still be returned for basic search operations, like searching for a user by username. How can I add further rules to prevent private users’ posts from being queried, while the rest of their profile can be retrieved?
type User @auth(
	query: { rule: """
        query($USER: String!) {
            queryUser(filter: { email: { eq: $USER}, or: {isPrivate: false}},) {
               username
            }
        }"""}){
        username: String
        posts: [Post]
        followers:[User]
        }

Also, is there away to generally secure the endpoint so that non-authorized users cannot retrieve any data at all?

  1. Followers
    To specify this even more, I would like to add an exception to the just mentioned rule, if a user is private, but the requesting user’s ID is included in the private user’s followers?

  2. Securing API keys
    This more general question is concerned with securing API keys. As an added layer of security, want to disable anonymous access, but I am unsure where to store my client API key. As the main platforms will be iOS and Android, I would not want to ship my API key to the client side code. Does Dgraph have solutions for securely storing API keys in the cloud, so that every query first reaches out to grab the API key from a secure storage that is never visible to the client side and is only accessible to authorized users, but also never leaves the server?

  3. Spam protection
    Besides securing private users’ data, my main concern are spam attacks that request enormous amounts of data, driving up the bill at the end of the month. Does Dgraph cloud have its own spam protection to prevent such things from happening?

I would appreciate some guidance regarding my securtiy concerns, and dgraph security best practices.

Yup (1 and 2), this should hopefully be available when nested filters becomes available at the end of the month (probably early next month).

(3) Your client api key should not be a big threat if you secure your app correctly. Even if you use it in a client side JS, a non-experience hacker could get a hold of it. You must make sure your security makes sense. Same principal for an app, although harder to hack.

(4) Spammers usually post, not query. The best security against queries is to not show lots of data unless a user is logged in. However, that is not always feasible for things like a blog etc. The only way I can think of securing this for the moment is to use Custom Lambda Queries for items that are available to non-logged in users. You would write your own security in the lambda. There are obviously limitations here. I would guess that a lot of apps are not protected from bulk queries unfortunately.

J

Thank you for your reply!

Great to hear nested auth will be added soon!
I assume that the rules set for GraphQL queries and mutations also apply to DQL operations? Or could somebody send unrestricted DQL requests to my backend? I am aware that the paranoia is probably not justified, but I believe it is important for me to understand these concepts.

Umm… that linked reply does not make the commitment for this feature in the next release, just saying…

Smh. I guess I was getting myself excited for nothing.

Hopefully in the nearer future.

J