Giter Site home page Giter Site logo

icewkz / shieldql Goto Github PK

View Code? Open in Web Editor NEW

This project forked from oslabs-beta/shieldql

1.0 0.0 0.0 296 KB

A JavaScript library for GraphQL that adds authentication, authorization, and query sanitization to prevent malicious queries and injection attacks.

JavaScript 67.73% TypeScript 32.27%

shieldql's Introduction


ShieldQL 🛡️

ShieldQL is a lightweight, powerful, easy-to-use JavaScript library for GraphQL that adds authentication, authorization, and query sanitization to prevent malicious queries and injection attacks.

  • Authentication: ShieldQL helps you implement user authentication in your GraphQL APIs, ensuring that only authenticated users can access certain parts of your API.
  • Authorization: With ShieldQL, you can define granular access controls for different types and fields in your GraphQL schema. This way, you can control what data each user can access based on their role and permissions.
  • Query Sanitization: ShieldQL gives you the tools to sanitize incoming GraphQL queries to prevent potential malicious operations and protect your backend from excessively deep and excessively long queries used in denial-of-service attacks.

Features

  • shieldqlConfig: A Javascript function that allows you to configure how sanitizeQuery will restrict queries and creates a secret for each role in the shieldql.json file, storing all of this information in the .env file and the process.env object

    • Where to use: Recommended use is next to importation of ShieldQL functionality in main server file (similar to dotenv.config())
    • shieldqlConfig accepts 3 params: strictShieldQL (a boolean), maxDepthShieldQL (a number), and maxLengthShieldQL (a number), which are used to configure sanitizeQuery (see sanitizeQuery for more details)
      • strictShieldQL: (default false) boolean value that determines whether or not sanitizeQuery will be run on strict mode or not (strictmode allows queries to be checked against the blocklist)
      • maxDepthShieldQL: (default 10) number that establishes the upper bound for the maximum depth of a graphQL query
      • maxLengthShieldQL: (default 2000) number that establishes the upper bound for total characters in a graphQL query
  • loginLink: Express middleware function that authenticates the client, creates a jwt access token, and stores it as a cookie on the client's browser to authorize future graphQL queries and mutations aligned with the user's role-based permissions described in the shieldql.json file

    • Where to use: loginLink should be invoked in a separate login-related route, so that the request body includes the access token in subsequent requests to the /graphql endpoint

    • Assumes that res.locals.role has already been populated with the user's role (that matches roles defined in the shieldql.json file) by a previous middleware function

    • NOTE: Access token expires after one day

  • validateUser: Express middleware function that verifies that the client making a graphQL query or mutation is authorized to do so through jwt verification

    • Where to use: validateUser should be invoked as part of the middleware chain for the /graphql route
  • sanitizeQuery: Express middleware function users will require and invoke in their applications to sanitize graphQL queries

    • Where to use: sanitizeQuery should be invoked as the first piece of middleware in the middleware chain for the /graphql route

    • sanitizeQuery works even if shieldqlConfig is never invoked, although if used without shieldqlConfig, default parameters will be used (strictmode set to false, maxDepth set to 10, maxLength set to 2000)

  • sanitize: Pure function users can require and invoke in their applications to sanitize the passed-in query.

    • Accepts 4 params:
      • input (required, a graphQL query type string)
      • strict (a bool value, default false, that enables additional query sanitization)
      • maxDepth (the maximum query nesting depth permitted, type integer)
      • maxLength (maximum permitted query length, type integer) that
    • Can be used as a standalone function and is also invoked within the body of the sanitizeQuery function

Setup

  • Make sure dotenv has been imported, that it is properly configured, and that a .env file already exists
  • Ensure that the .env file is in the root directory

Screenshot of sample demo app directory.

  • Create a shieldql.json file in root directory. This file will define the roles and permissions that will be enforced throughout the user's graphQL application.
    • E.g.:
{
  "admin": {
    "query": ["."],
    "mutation": ["."]
  },
  "user": {
    "query": ["feed", "news"]
  },
  "job-applicant": {
    "query": ["job-description"]
  }
}
  • Ensure that the appropriate graphQL role from the shieldqlConfig.js file is passed into the graphQL route through res.locals.role in order for loginLink to enforce authentication and authorization

    • A common approach to this problem is the following (see below for an example)

      • Insert a middleware function preceding loginLink that queries the user database
      • Extracts the graphQL role
      • Stores it in res.locals.role
const express = require('express');
const graphqlHttp = require('express-graphql');
const shieldql = require('shieldql');
const dotenv = require('dotenv');
dotenv.config();

// shieldqlConfig configures settings for sanitizeQuery
// if the first arg is true, sanitizeQuery will check queries against the blocklist
// second arg indicates maxDepth allowed
// third arg indicates maxLength allowed
shieldql.shieldqlConfig(true, 15, 5000); 

const app = express();

app.post('/login',
  populateResLocalsRole, //this middleware function will pass role via res.locals.role
  shieldql.loginLink, // loginLink will use the role to create an access token
  (req, res) => {
    return res.status(200).json(res.locals);
  }
);

app.post(
  '/graphql',
  shieldql.sanitizeQuery, // developers can invoke sanitizeQuery to sanitize queries based on the rules passed into shieldqlConfig
  shieldql.validateUser, // validateUser checks if user is authorized to make the query based on their role and the permissions set in shieldql.json
  graphqlHttp({
    schema: graphQlSchema,
    rootValue: graphQlResolvers,
    graphiql: true,
  })
);
  • NOTE: ShieldQL will NOT be able to authenticate and authorize graphQL queries unless roles are passed into loginLink through res.locals.role :shipit:

Installation

npm i shieldql

Security Considerations

While ShieldQL offers essential security features, it's crucial to keep your application and dependencies up to date to stay protected against emerging security threats. Always follow best practices for securing your GraphQL APIs.

Future direction

  • allowListing configuration and implementation for sanitize.js
  • Amount limiting (limiting number of times a query can be called)
  • make app compatible with multiple root level queries/mutations in a single request
  • implement refresh tokens
  • Jest/End-to-end Testing
  • Add error handling for GraphQL queries
  • Developing a graphical interface for configuring permissions and user roles
  • Integrate a database to restrict malicious query runs.
  • Typescript

Contribution guidelines

We welcome contributions to ShieldQL!

Following Meta's lead with React, we have adopted the Contributor Covenant as our code of conduct for future contributors. Please read it to ensure that you understand and accept the terms and conditions described therein.

Branch management

  • Please submit any pull requests to the dev branch. All changes will be reviewed before merging by OSLabs and prior contributors.

Bugs and suggestions

  • For help with existing issues, please read our GitHub issues page
  • If you cannot find support in the issues page, please file a report on the same issues page.
  • Suggestions and other feedback are more than welcome!

Contributors

Inspired by graphQLock.

License

ShieldQL is ISC licensed.

Thank you for using ShieldQL! We hope this library helps you secure your GraphQL APIs effectively. If you encounter any issues or need further assistance, please don't hesitate to reach out to us.

Happy coding!

shieldql's People

Contributors

rscalderon avatar simk209 avatar joie-zhang avatar xjqiu28 avatar sifulsidd avatar

Stargazers

Michael Zhang avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.