introspectre 1.4.0

A GraphQL offensive-security engine: introspection-driven schema analysis, active vulnerability probing, and an interactive attack-surface report.
pub mod access_control;
pub mod dos;
pub mod information_exposure;
pub mod jwt;
pub mod scoring;

use crate::config::PatternConfig;
use crate::types::{Finding, GqlSchema, SchemaStats};
use crate::utils::user_types;

pub fn analyze(
    schema: &GqlSchema,
    patterns: &PatternConfig,
    token: Option<&str>,
) -> (Vec<Finding>, SchemaStats) {
    let mut findings: Vec<Finding> = Vec::new();
    let types = user_types(schema);

    let query_name = schema.query_type.as_ref().map(|t| t.name.as_str());
    let mutation_name = schema.mutation_type.as_ref().map(|t| t.name.as_str());
    let subscription_name = schema.subscription_type.as_ref().map(|t| t.name.as_str());

    let total_fields: usize = types
        .iter()
        .map(|t| t.fields.as_ref().map(|f| f.len()).unwrap_or(0))
        .sum();

    let deprecated_fields: usize = types
        .iter()
        .flat_map(|t| t.fields.iter().flat_map(|v| v.iter()))
        .filter(|f| f.is_deprecated.unwrap_or(false))
        .count();

    let stats = SchemaStats {
        total_types: types.len(),
        object_types: types
            .iter()
            .filter(|t| t.kind.as_deref() == Some("OBJECT"))
            .count(),
        queries: schema.fields_for_type(query_name).len(),
        mutations: schema.fields_for_type(mutation_name).len(),
        subscriptions: schema.fields_for_type(subscription_name).len(),
        enums: types
            .iter()
            .filter(|t| t.kind.as_deref() == Some("ENUM"))
            .count(),
        interfaces: types
            .iter()
            .filter(|t| t.kind.as_deref() == Some("INTERFACE"))
            .count(),
        unions: types
            .iter()
            .filter(|t| t.kind.as_deref() == Some("UNION"))
            .count(),
        total_fields,
        deprecated_fields,
    };

    information_exposure::check_information_exposure(schema, patterns, &mut findings);
    dos::check_dos(schema, &mut findings);
    access_control::check_access_control(schema, patterns, &mut findings);
    jwt::check_jwt(token, patterns, &mut findings);

    (findings, stats)
}