Skip to main content

Technical information leak - API

Need

Protection of sensitive technical information in the API

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and handling HTTP requests
  • Usage of express-graphql for integrating GraphQL with Express framework
  • Usage of GraphQL for data query and manipulation

Description

Non compliant code

import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { buildSchema } from 'graphql';

const schema = buildSchema(`
type Query {
hello: String
}
`);

const root = {
hello: () => 'Hello, world!',
};

const app = express();

app.use(
'/graphql',
graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
})
);

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The vulnerability in this code is that it allows introspection queries, which can leak sensitive information about the GraphQL API schema structure. Introspection queries allow clients to query the schema itself to retrieve information about the available types, fields, and relationships.

In this code, the graphqlHTTP middleware from the express-graphql library is used to handle GraphQL requests. The graphiql option is set to true, enabling the GraphiQL interface, which allows users to explore and test the API.

By default, the GraphiQL interface includes an "Explorer" pane that allows users to browse the API schema and execute introspection queries. This means that an attacker can easily retrieve the entire GraphQL API schema structure, including all queries and mutations.

This information can be valuable to an attacker as it provides insights into the API's functionality and can help them identify potential attack vectors. For example, knowing the available mutations and their arguments can allow an attacker to craft malicious requests to modify or delete data.

To mitigate this vulnerability, the code should disable introspection queries. This can be done by setting the introspection option of the graphqlHTTP middleware to false.

Steps

  • Remove the 'graphiql' option from the 'graphqlHTTP' middleware configuration
  • Disable introspection queries by setting the 'introspection' option to 'false' in the 'graphqlHTTP' middleware configuration

Compliant code

import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { buildSchema } from 'graphql';

const schema = buildSchema(`
type Query {
hello: String
}
`);

const root = {
hello: () => 'Hello, world!',
};

const app = express();

app.use(
'/graphql',
graphqlHTTP({
schema: schema,
rootValue: root,
introspection: false,
})
);

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The fixed code addresses the vulnerability by disabling introspection queries in the GraphQL API.

The code starts by importing the necessary modules: express, express-graphql, and graphql.

Next, a GraphQL schema is built using the buildSchema function from the graphql module. In this example, the schema defines a single query type with a hello field that returns a string.

A root resolver object is created with a single method hello that returns the string "Hello, world!".

An Express application is created using express().

The application uses the graphqlHTTP middleware from express-graphql to handle GraphQL requests. The middleware is configured with the created schema, root resolver, and the introspection option set to false. This disables introspection queries, preventing the attacker from gathering the entire GraphQL API schema structure.

The middleware is mounted on the /graphql endpoint using app.use().

Finally, the application listens on port 3000, and a message is logged to the console indicating that the server is running.

By disabling introspection queries, the fixed code prevents the attacker from gaining knowledge of the schema structure, reducing the risk of more dangerous attacks.

References