Skip to content

Commit

Permalink
Allow limiting batched queries to avoid batching attacks (razee-io#1354)
Browse files Browse the repository at this point in the history
* Allow limiting batched queries to avoid batching attacks, ref https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#batching-attacks

* linting
  • Loading branch information
carrolp authored Mar 11, 2024
1 parent 58ed7a4 commit 5f66ee8
Show file tree
Hide file tree
Showing 3 changed files with 822 additions and 790 deletions.
29 changes: 28 additions & 1 deletion app/apollo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

const { execute, subscribe } = require( 'graphql' );
const { execute, subscribe, parse } = require( 'graphql' );
const { SubscriptionServer } = require( 'subscriptions-transport-ws' );
const { makeExecutableSchema } = require( '@graphql-tools/schema' );
let subscriptionServer;
Expand Down Expand Up @@ -342,6 +342,33 @@ const apollo = async (options = {}) => {
app.use(graphqlUploadExpress());
//Note: there does not yet appear to be an automated test for upload, it is unclear if this even functioning.

// Protect against batched queries of both forms described here: https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#batching-attacks
const GQL_BATCH_LIMIT = process.env.GRAPHQL_BATCH_LIMIT || -1;
const countQueries = function( payload ) {
let count = 0;
if( Array.isArray(payload) ) {
for( const q of payload ) {
count += countQueries(q);
}
}
else {
const parsedQuery = parse( payload.query );
for( let def of parsedQuery.definitions ) {
if( def.selectionSet && def.selectionSet.selections ) count += def.selectionSet.selections.length;
}
}
return( count );
};
app.use(GRAPHQL_PATH, (req,res,next)=>{
// Fail if limit defined and batch greater than limit
if( GQL_BATCH_LIMIT > 0 && countQueries( req.body ) > GQL_BATCH_LIMIT ) {
res.status(400).send( { errors: [ { message: 'Batched query limit exceeded' } ] } );
}
else {
next();
}
});

server.applyMiddleware({
app,
cors: {origin: true},
Expand Down
Loading

0 comments on commit 5f66ee8

Please sign in to comment.