Modern QA2026Security Testing — tiles
Log inJoin
44 / 65 · 14 API Testing Fundamentals · GraphQL Testing← prev⊞ allnext →☰ Read as one page

6.5Security Testing

Introspection

GraphQL introspection allows clients to query the entire schema — useful in development but a security risk in production.

def test_introspection_disabled_in_production(prod_url):
    """Introspection should be disabled in production."""
    query = """
    query {
        __schema {
            types { name }
        }
    }
    """
    r = requests.post(f"{prod_url}/graphql", json={"query": query})
    data = r.json()
    # Should either error or return no data
    assert "errors" in data or data.get("data", {}).get("__schema") is None

Query Depth Limiting

Deeply nested queries can be used for denial-of-service attacks:

def test_query_depth_limit(api, base_url):
    """Deeply nested queries should be rejected."""
    # Build a deeply nested query
    query = "{ user(id: \"1\") { " + \
        "friends { " * 20 + \
        "name" + \
        " }" * 20 + \
        " } }"

    r = requests.post(f"{base_url}/graphql",
        json={"query": query},
        headers=api.headers)

    data = r.json()
    assert "errors" in data  # Should be rejected due to depth limit

def test_query_complexity_limit(api, base_url):
    """Queries requesting too many resources should be limited."""
    query = """
    query {
        users(first: 1000) {
            edges {
                node {
                    name
                    posts(first: 1000) {
                        edges {
                            node {
                                title
                                comments(first: 1000) {
                                    edges { node { body } }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    """
    r = requests.post(f"{base_url}/graphql",
        json={"query": query},
        headers=api.headers)

    data = r.json()
    assert "errors" in data  # Should be rejected due to complexity