[pitboss] phase 21: Track M.3 — ScheduledJob + GraphQLResolver + WebSocket + Middleware + Migration

This commit is contained in:
pitboss 2026-05-20 18:05:31 -05:00
parent 00b0fbaea9
commit f9bd51c024
84 changed files with 5898 additions and 40 deletions

View file

@ -0,0 +1,9 @@
// Phase 21 — Apollo resolver benign control.
const _NYX_ADAPTER_MARKER = "require('@apollo/server')";
function resolveUser(parent, args, ctx) {
const id = String(args.id || '').replace(/[^A-Za-z0-9_-]/g, '');
return { id, name: 'user-' + id };
}
module.exports = { resolveUser };

View file

@ -0,0 +1,14 @@
// Phase 21 (Track M.3) — Apollo GraphQL resolver vuln fixture.
//
// `resolveUser(parent, args)` is a resolver from an Apollo schema that
// splices `args.id` into a SQL query via raw string concatenation —
// classic GraphQL → SQLi shape.
const _NYX_ADAPTER_MARKER = "require('@apollo/server')";
function resolveUser(parent, args, ctx) {
// SINK: tainted args.id concatenated into SQL.
const query = "SELECT * FROM users WHERE id = '" + args.id + "'";
return { id: args.id, name: 'user-' + args.id, _query: query };
}
module.exports = { resolveUser };

View file

@ -0,0 +1,15 @@
// Phase 21 — gqlgen benign control.
package benign
// import "github.com/99designs/gqlgen/graphql"
import "regexp"
var idAllow = regexp.MustCompile(`^[A-Za-z0-9_-]+$`)
func ResolveUser(id string) (string, error) {
if !idAllow.MatchString(id) {
return "", nil
}
return "user-" + id, nil
}

View file

@ -0,0 +1,23 @@
// Phase 21 (Track M.3) — gqlgen GraphQL resolver vuln fixture.
//
// `resolveUser(ctx, id)` is a gqlgen resolver (substring marker only —
// the real gqlgen runtime is not on the workdir's go.mod). The
// resolver splices the id into a shell command via os/exec.
package vuln
// import "github.com/99designs/gqlgen/graphql"
import (
"os/exec"
)
// type queryResolver struct{}
func ResolveUser(id string) (string, error) {
// SINK: tainted id concatenated into shell command.
out, err := exec.Command("/bin/sh", "-c", "echo lookup-"+id).Output()
if err != nil {
return "", err
}
return string(out), nil
}

View file

@ -0,0 +1,9 @@
"""Phase 21 — Graphene resolver benign control."""
import re
_NYX_ADAPTER_MARKER = "import graphene"
def resolve_user(self, info, id):
safe = re.sub(r"[^A-Za-z0-9_-]", "", str(id))
return "user-" + safe

View file

@ -0,0 +1,15 @@
"""Phase 21 (Track M.3) — Graphene resolver vuln fixture.
`resolve_user(self, info, id)` is a Graphene query resolver that
splices the tainted `id` into a shell command via `os.system`.
"""
import os
_NYX_ADAPTER_MARKER = "import graphene"
_NYX_OBJECT_TYPE_MARKER = "class Query(graphene.ObjectType):"
def resolve_user(self, info, id):
# SINK: tainted id concatenated into shell command.
os.system("echo lookup-" + str(id))
return "user-" + str(id)

View file

@ -0,0 +1,10 @@
//! Phase 21 — Juniper resolver benign control.
// use juniper::graphql_object;
pub fn resolve_user(id: &str) -> String {
let safe: String = id
.chars()
.filter(|c| c.is_ascii_alphanumeric() || *c == '_' || *c == '-')
.collect();
format!("user-{}", safe)
}

View file

@ -0,0 +1,15 @@
//! Phase 21 (Track M.3) — Juniper GraphQL resolver vuln fixture.
//!
//! `resolve_user(id)` is a Juniper resolver (substring marker only —
//! the real `juniper` crate is not on the workdir's Cargo.toml). The
//! resolver builds a SQL query via raw string concat — classic
//! GraphQL → SQLi shape.
// use juniper::graphql_object;
pub fn resolve_user(id: &str) -> String {
// SINK: tainted id concatenated into SQL.
let query = format!("SELECT * FROM users WHERE id = '{}'", id);
let _ = query;
format!("user-{}", id)
}

View file

@ -0,0 +1,9 @@
// Phase 21 — graphql-relay benign control.
const _NYX_ADAPTER_MARKER = "require('graphql-relay')";
function resolveNode(parent, args) {
const id = String(args.id || '').replace(/[^A-Za-z0-9_-]/g, '');
return { id };
}
module.exports = { resolveNode };

View file

@ -0,0 +1,10 @@
// Phase 21 (Track M.3) — graphql-relay vuln fixture.
const _NYX_ADAPTER_MARKER = "require('graphql-relay')";
function resolveNode(parent, args, ctx, info) {
// SINK: tainted globalId interpolated into SQL.
const sql = "SELECT * FROM nodes WHERE id = '" + args.id + "'";
return { id: args.id, _sql: sql };
}
module.exports = { resolveNode };