graphqlx

package
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package graphqlx provides transport-agnostic GraphQL logic shared by the scanner modules: the canonical introspection query, a schema model parsed from an introspection response, a builder that turns a schema into concrete operations (mirroring how an OpenAPI spec is expanded into requests), typed example-value synthesis, and lightweight detection/fingerprint helpers.

Nothing here performs I/O — callers own the HTTP layer — so the package is pure and cheaply unit-testable.

Index

Constants

View Source
const (
	// DefaultMaxOperations bounds fed traffic so an enormous schema cannot flood
	// the pipeline.
	DefaultMaxOperations = 40
	// DefaultMaxSelectionFields bounds selection-set width per operation.
	DefaultMaxSelectionFields = 6
)
View Source
const (
	KindScalar      = "SCALAR"
	KindObject      = "OBJECT"
	KindInterface   = "INTERFACE"
	KindUnion       = "UNION"
	KindEnum        = "ENUM"
	KindInputObject = "INPUT_OBJECT"
	KindList        = "LIST"
	KindNonNull     = "NON_NULL"
)

Kind constants for GraphQL type kinds as returned by introspection.

View Source
const IntrospectionQuery = `` /* 500-byte string literal not displayed */

IntrospectionQuery is the canonical full introspection query (fragment-free, depth-bounded ofType chain) used to enumerate the complete schema. It matches the OWASP WSTG reference query and the depth used by the jsext helper.

View Source
const TypenameQuery = `{"query":"{ __typename }"}`

TypenameQuery is the minimal probe used to confirm an endpoint speaks GraphQL.

Variables

This section is empty.

Functions

func ConfirmsTypename

func ConfirmsTypename(body []byte) bool

ConfirmsTypename reports whether a probe response actually reflects the __typename query result, i.e. a real GraphQL engine answered. A generic 200 JSON page or GraphiQL HTML will not carry both the data envelope and the echoed __typename key.

func IntrospectionBody

func IntrospectionBody() string

IntrospectionBody returns the JSON request body carrying the full introspection query, ready to POST with Content-Type application/json.

func LooksLikeGraphQLResponse

func LooksLikeGraphQLResponse(body []byte) bool

LooksLikeGraphQLResponse reports whether a response body is plausibly from a GraphQL backend: it must be JSON-shaped and carry a GraphQL envelope key ("data" or a spec-shaped "errors" array), not merely contain the word graphql. This is a necessary (not sufficient) signal — callers combine it with a positive probe (e.g. __typename echoed back).

func LooksLikeIntrospection

func LooksLikeIntrospection(body []byte) bool

LooksLikeIntrospection reports whether a response body is a GraphQL introspection result, cheaply (substring), without full parsing. Requires the __schema marker plus a structural companion so a request that merely echoes "__schema" as a string does not match.

func QueryBody

func QueryBody(query string) string

QueryBody wraps a raw GraphQL document into a JSON POST body.

func QuoteString

func QuoteString(s string) string

QuoteString returns query, escaped as a GraphQL string literal.

Types

type BuildOptions

type BuildOptions struct {
	// IncludeMutations enables synthesizing mutation operations. Off by default:
	// mutations change state, so they are only exercised under an explicit
	// aggressive/deep opt-in.
	IncludeMutations bool
	// MaxOperations caps the number of operations returned (0 → DefaultMaxOperations).
	MaxOperations int
	// MaxSelectionFields caps leaf fields selected per object return type
	// (0 → DefaultMaxSelectionFields).
	MaxSelectionFields int
	// OnlyArgless restricts generation to root fields with no required args —
	// the safest, most data-yielding subset (pure enumeration).
	OnlyArgless bool
}

BuildOptions tunes operation generation.

type Field

type Field struct {
	Name string
	Args []*InputValue
	Type *TypeRef
}

Field is a field on an object/interface type.

type IDLookupField

type IDLookupField struct {
	Field *Field
	IDArg string // the identifier argument name
}

IDLookupField is a root query field that fetches a single object by an id-like scalar argument — the BOLA/IDOR probe surface.

func (IDLookupField) IDArgType

func (l IDLookupField) IDArgType() string

IDArgType returns the named type of the identifier argument ("ID", "Int", …).

type InputValue

type InputValue struct {
	Name         string
	Type         *TypeRef
	DefaultValue string // raw GraphQL literal, "" when absent
}

InputValue is a field argument or an input-object field.

type OpKind

type OpKind string

OpKind is the GraphQL root operation kind.

const (
	KindQuery    OpKind = "query"
	KindMutation OpKind = "mutation"
)

type Operation

type Operation struct {
	Kind      OpKind
	RootField string   // the root field this operation invokes
	Query     string   // the raw GraphQL document
	Body      string   // JSON POST body
	ArgNames  []string // required argument names filled (for reporting)
}

Operation is a concrete, ready-to-send GraphQL operation synthesized from the schema. Body is the JSON request body ({"query":"..."}).

func BuildOperations

func BuildOperations(s *Schema, opts BuildOptions) []Operation

BuildOperations enumerates the root query (and optionally mutation) fields and synthesizes a minimal valid operation for each: required arguments filled with typed example literals, and a leaf-biased selection set for object returns. A root field is skipped when any required argument cannot be confidently rendered, so every emitted operation is well-formed rather than garbage.

type Schema

type Schema struct {
	QueryType        string
	MutationType     string
	SubscriptionType string
	Types            []*Type
	// contains filtered or unexported fields
}

Schema is the subset of an introspection result needed to build operations.

func ParseSchema

func ParseSchema(body []byte) (*Schema, bool)

ParseSchema decodes an introspection response body into a Schema. It returns (nil, false) when the body is not a usable introspection result (no __schema, or no types) so callers can cheaply gate on the boolean.

func (*Schema) DepthProbe

func (s *Schema) DepthProbe(depth int) (string, bool)

DepthProbe builds a deeply-nested query by following a self-referential object relationship reachable from an argument-free root query field, to the given depth. It returns ("", false) when the schema has no usable cycle. The probe is a single non-amplified query (no aliasing, no large list arguments) — its only purpose is to observe whether the server enforces a depth/complexity limit, never to exhaust resources.

func (*Schema) IDLookupFields

func (s *Schema) IDLookupFields() []IDLookupField

IDLookupFields returns root query fields that take an "id" argument and return a single (non-list) object — where every other required argument is renderable. These are the fields probed for predictable-ID object access.

func (*Schema) QueryFields

func (s *Schema) QueryFields() []*Field

QueryFields returns the root query fields (nil-safe, introspection fields excluded).

func (*Schema) RenderProbe

func (s *Schema) RenderProbe(f *Field, idArg, idLiteral string, maxSel int) (string, bool)

RenderProbe builds a query document invoking f with its id argument set to idLiteral (a ready GraphQL literal) and all other required args auto-filled, selecting leaf fields. Returns ("", false) if a required arg is unrenderable.

func (*Schema) TypeByName

func (s *Schema) TypeByName(name string) *Type

TypeByName returns the named type or nil.

type Type

type Type struct {
	Kind        string
	Name        string
	Fields      []*Field
	InputFields []*InputValue
	EnumValues  []string
}

Type is a named GraphQL type from the schema.

type TypeRef

type TypeRef struct {
	Kind   string
	Name   string
	OfType *TypeRef
}

TypeRef is a possibly-wrapped reference to a type (NON_NULL / LIST wrappers around a named type).

func (*TypeRef) IsList

func (t *TypeRef) IsList() bool

IsList reports whether the type is a list at any wrapper level below an optional leading NON_NULL.

func (*TypeRef) IsRequired

func (t *TypeRef) IsRequired() bool

IsRequired reports whether the outermost wrapper is NON_NULL (and the type has no default value — callers pass the default separately).

func (*TypeRef) Named

func (t *TypeRef) Named() string

Named resolves through NON_NULL / LIST wrappers to the underlying named type. Returns "" if the reference has no named base (malformed).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL