Penligent Header

GraphQL Penetration Testing: Authorization, Cost and Evidence

A GraphQL penetration test needs a map of identities, resolvers and data relationships, not just a count of HTTP endpoints. One URL can expose a broad graph of reads, mutations and nested fields. A useful engagement proves selected authorization rules and resource limits through that graph, then gives engineers enough evidence to retest the repair.

This guide defines a proposed assessment method for an owned staging application. It is not a finding against GraphQL itself. The OWASP GraphQL Cheat Sheet supplies the defensive foundation: validate input, enforce access control, limit expensive requests and handle errors deliberately. The worksheet below turns those controls into observable acceptance cases.

Quote the graph and the business rules

Give a provider the schema revision, operation inventory, authentication method and role model. Include subscriptions, persisted operations, file or export delivery, federation boundaries and any administrative surface actually used by the deployment. State whether introspection is permitted in the engagement. Disabling introspection can change discovery effort; it does not demonstrate that resolvers enforce authorization.

For an initial bounded pilot, choose a synthetic document workflow. Create owner A, peer B in the same tenant, user C in another tenant, and a support role whose access is explicitly defined. Seed two unmistakably fictional records. Write the expected policy before testing: who may discover, read, modify, export and delete each record? Include a permitted control for every denied operation so an outage cannot look like successful protection.

Scope unitWhat to enumerateWhy the quote changes
Object relationshipOwner, peer, tenant and delegated accessOne resolver may require several identity comparisons.
Field sensitivityPublic metadata, internal notes, restricted fieldsAn allowed object does not imply every field is allowed.
Execution pathDirect lookup, nested lookup, list, mutation and subscriptionEquivalent data can be reached through different enforcement points.
State and costAsync job, export link, cache, pagination and complexity controlsThe initial response may not reveal the final access or resource outcome.
GraphQL authorization testing distinguishes direct and nested object access, field visibility and mutation side effects.
Proposed staging matrix: compare the same fixture through each path

Test object, field and operation authorization separately

Start with a valid owner read and record the schema, subject and returned synthetic marker. Repeat the documented operation with B and C according to the agreed policy. Then examine nested and list paths that legitimately reach the same object. A protected direct lookup does not establish that a nested relationship or search result applies the same rule.

Keep field authorization separate. A user may be entitled to a document title while its internal review note remains restricted. Inspect both the returned data and the errors array. A response can contain permitted fields and errors for denied fields. Classify whether the prohibited marker was returned rather than treating either HTTP 200 or the presence of an error as the verdict.

For a mutation, inspect the resulting state using the owner’s approved workflow. An error returned after a change is different from a denial before the change. Use disposable staging objects and a reversible write agreed in scope. Do not perform real billing, permission grants or destructive actions merely to obtain a dramatic proof.

CaseExpected evidenceCommon false conclusion
Peer reads owner-only objectProhibited marker absent; owner control still worksHTTP 200 automatically means unauthorized disclosure.
Allowed object, restricted fieldField decision and partial-data result retainedAn object-level allow covers every property.
Read-only role invokes controlled mutationNo unauthorized state change, plus decision logAn error proves no write happened.
User removed from tenantMeasured behavior across sessions, cache and subscriptionA new login check proves old subscriptions were revoked.

Bound query-cost testing before executing it

OWASP discusses depth, amount, batching and rate controls because one request can request substantial work. Test these through a staged plan with an explicit ceiling, monitoring owner and stop condition. Begin with low-cost controls and configuration evidence. Increase only within the approved resource budget; a production denial-of-service demonstration is unnecessary.

Record what the control measures. Query depth, alias count, returned object count and downstream database work are different units. A shallow operation can still retrieve many objects; a request-rate limit can still allow one expensive operation. Ask the service owner to correlate the chosen case with its actual cost signal, such as resolver duration or backend work, without claiming a universal safe depth value.

GraphQL resource testing distinguishes request rate, graph depth, returned amount and downstream work.
Measure the enforced unit before accepting a limit

Require an evidence packet and a complete retest

Each case should retain the schema and application revision, pseudonymous test identity, operation name, variables with only synthetic identifiers, expected rule, returned marker, resulting state and request correlation ID. Redact bearer tokens and secrets. Separate a confirmed boundary failure from an inconclusive case whose identity or side effect could not be verified.

Case: support role reads restricted review note
Fixture: synthetic document owned by tenant A
Expected: title allowed; review note denied
Observed data: record exact permitted and prohibited markers
Side effect: none expected
Evidence: redacted operation, response, policy revision, request ID
Retest: denied field stays absent; permitted title remains readable

For procurement, ask the finalist to complete this small matrix before expanding the engagement. Require blocked cases, untested paths and resource ceilings in the report. A list of generic GraphQL warnings or an endpoint inventory cannot substitute for the specific relationship tests you purchased.

Retest the same forbidden path after the fix and repeat the valid control. If the repair changes shared authorization logic, revisit equivalent nested, list and asynchronous paths within scope. Close the issue when the required evidence supports the repaired rule; keep an unverified path visible as an exception.

Use the resolver, identity and cost matrix as the pilot brief when evaluating Penligent. Confirm supported operations and the expected evidence before expanding the scope.

The official Penligent 3.0 video below demonstrates the general product workflow. It illustrates product use; the article’s assessment proposals and source findings are evaluated separately.

Method: AI-assisted review of the linked primary sources, checked November 12, 2026, with an original assessment framework. No exploit, production target or customer environment was tested for this article.

Share the Post:
Related Posts
en_USEnglish