The GraphQL API of Magento 2.3+ comes with numerous endpoints. However, some of these endpoints offer little protection against bastards that want to abuse this. My new Yireo_GraphQlRateLimiting offers a rate limiting to try to reduce abuse. Let's see why it is needed.
GraphQL queries and mutations
The Magento GraphQL API offers a flexible API that can be used to build frontends in Vue or React. While it could be debated that the API coverage is not at 100% yet, I often say that it is dead-easy to build new frontends yourself (via custom Magento extensions) as to solve that issue. And because of this, the GraphQL API is good enough to build a new frontend with, assuming that you are offering things at the right price.
However, one thing that still seems to lack is the performance & security bit. Some recursive queries are leading into increased performance. And in some other situations, it is kind of easy to abuse these endpoints as well. A couple of examples:
In a simple
products query, you can request details for each product being returned. Each product can for instance return the categories it resides in. Next, for each category, you can list all of the products. Next, for each of those products, you can list all of the categories. Etcetera. Magento out of the box doesn't have a way to prevent this from happening.
Creating 10.000 customer records in 15 minutes
With another API endpoint, you can create your own new customer account. This happens in my development environment in less than 100 milliseconds. This means I can create about 10.000 records in 15 minutes time using a tool like Faker and a simple CURL script. And there is no security mechanism to impose limits to this kind of attack. Call it a feature, I call it a shortcoming.
Rate limiting mutations and queries
The module I created is simple in its approach: It applies rate limiting based on a certain configuration of how many queries and how many mutations. The same query for instance can only be executed by the same client for a maximum of 30 times in 10 minutes for instance. Or even more important, the same mutation can only occur 5 times in that same time frame. The GraphQlRateLimiting module simply applies these limits to every request coming into the GraphQL API.
Still work in progress
As of yet, the module seems to be working fine. However, any input is welcome. Just head over to the GitHub project, try things out and let's start working together this: https://github.com/yireo/Yireo_GraphQlRateLimiting