GraphQL solves some real problems with REST. The flexibility, the strong typing and the developer experience are all genuine wins. The trouble is that the same features that make GraphQL pleasant to work with also create vulnerability classes that traditional API testing methodologies struggle to spot. Many teams adopt GraphQL without realising that the threat model needs a different lens.
Introspection Tells Attackers Too Much
GraphQL introspection lets clients ask the server what types and fields exist. This is invaluable during development. In production it is a gift to attackers, because the entire schema, including admin-only fields, can be enumerated with a single query. Disable introspection in production environments. The cost is minimal. The benefit is denying an attacker a map of your entire API. A focused web application pen testing will always test for this in the first ten minutes.
Query Complexity Becomes A Weapon
A single GraphQL query can request deeply nested data, sometimes traversing relationships in ways that hit the database hundreds of times. Without query depth limits, complexity analysis and timeouts, a single request can take a production database to its knees. The denial of service surface is bigger than most teams expect. Worse, the same complexity attack can be used to enumerate data slowly without triggering rate limits aimed at high request counts.
Expert Commentary
William Fieldhouse, Director of Aardwolf Security Ltd

We routinely find GraphQL endpoints where a single carefully crafted query returns more data than the application would ever willingly serve through its standard UI. Authorisation tends to be checked at the resolver level inconsistently, and gaps appear in the deeper nested fields that nobody thought to protect.
Caching And Batching Add Complexity
GraphQL queries can include the same data multiple times through different paths in the graph, which makes simple caching strategies awkward. Some teams solve this with persisted queries that limit clients to a predefined set of allowed query shapes. Others solve it with rigorous complexity analysis and timeouts. Either approach is significantly better than naive deployment, where every client can submit arbitrary queries and the back end has no defence against expensive operations. Persisted queries also help with performance and observability, which makes them easier to sell to development teams who might otherwise resist the constraint. The security benefit comes alongside operational improvements rather than as a pure overhead.
Authorisation Lives In Every Resolver
REST endpoints make it relatively easy to apply a single authorisation check at the controller. GraphQL resolvers run in a tree, and each resolver might need its own check depending on what data it returns. Miss a single resolver and an attacker can pull sensitive data through an unprotected sub-field even though the parent query was authorised correctly. A serious vulnerability scan services approach for GraphQL involves mapping every resolver and validating that its authorisation logic is consistent with its peers.
GraphQL is not insecure by nature. It is unfamiliar enough that the testing approach matters more than usual. GraphQL implementations vary widely in how seriously they take security. Choose your framework with the maturity question in mind alongside the developer experience. Web application security is a discipline that rewards patient investment. The teams that treat it as ongoing work consistently outperform the ones that treat it as a project with an end date.