Technical information leak - API - Typescript
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
Insecure Code Example
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
Secure Code Example
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
Last updated
2023/09/18