| name | mass-assignment-testing |
| description | Mass assignment testing for unauthorized field binding and privilege escalation via API parameters |
Mass Assignment Testing
penkit51 AI — professional penetration testing skill pack. Authorized testing only.
Deep Exploitation Guide
Mass Assignment
Mass assignment binds client-supplied fields directly into models/DTOs without field-level allowlists. It commonly leads to privilege escalation, ownership changes, and unauthorized state transitions in modern APIs and GraphQL.
Attack Surface
- REST/JSON, GraphQL inputs, form-encoded and multipart bodies
- Model binding in controllers/resolvers; ORM create/update helpers
- Writable nested relations, sparse/patch updates, bulk endpoints
Reconnaissance
Surface Map
- Controllers with automatic binding (e.g., request.json → model)
- GraphQL input types mirroring models; admin/staff tools exposed via API
- OpenAPI/GraphQL schemas: uncover hidden fields or enums
- Client bundles and mobile apps: inspect forms and mutation payloads for field names
Parameter Strategies
- Flat fields:
isAdmin, role, roles[], permissions[], status, plan, tier, premium, verified, emailVerified
- Ownership/tenancy:
userId, ownerId, accountId, organizationId, tenantId, workspaceId
- Limits/quotas:
usageLimit, seatCount, maxProjects, creditBalance
- Feature flags/gates:
features, flags, betaAccess, allowImpersonation
- Billing:
price, amount, currency, prorate, nextInvoice, trialEnd
Shape Variants
- Alternate shapes: arrays vs scalars; nested JSON; objects under unexpected keys
- Dot/bracket paths:
profile.role, profile[role], settings[roles][]
- Duplicate keys and precedence:
{"role":"user","role":"admin"}
- Sparse/patch formats: JSON Patch/JSON Merge Patch; try adding forbidden paths
Encodings and Channels
- Content-types:
application/json, application/x-www-form-urlencoded, multipart/form-data, text/plain
- GraphQL: add suspicious fields to input objects; overfetch response to detect changes
- Batch/bulk: arrays of objects; verify per-item allowlists not skipped
Key Vulnerabilities
Privilege Escalation
- Set role/isAdmin/permissions during signup/profile update
- Toggle admin/staff flags where exposed
Ownership Takeover
- Change ownerId/accountId/tenantId to seize resources
- Move objects across users/tenants
Feature Gate Bypass
- Enable premium/beta/feature flags via flags/features fields
- Raise limits/seatCount/quotas
Billing and Entitlements
- Modify plan/price/prorate/trialEnd or creditBalance
- Bypass server recomputation
Nested and Relation Writes
- Writable nested serializers or ORM relations allow creating or linking related objects beyond caller's scope
Advanced Techniques
GraphQL Specific
- Field-level authz missing on input types: attempt forbidden fields in mutation inputs
- Combine with aliasing/batching to compare effects
- Use fragments to overfetch changed fields immediately after mutation
ORM Framework Edges
- Rails: strong parameters misconfig or deep nesting via
accepts_nested_attributes_for
- Laravel: $fillable/$guarded misuses;
guarded=[] opens all; casts mutating hidden fields
- Django REST Framework: writable nested serializer, read_only/extra_kwargs gaps, partial updates
- Mongoose/Prisma: schema paths not filtered;
select:false doesn't prevent writes; upsert defaults
Parser and Validator Gaps
- Validators run post-bind and do not cover extra fields
- Unknown fields silently dropped in response but persisted underneath
- Inconsistent allowlists between mobile/web/gateway; alt encodings bypass validation pipeline
Bypass Techniques
Content-Type Switching
- Switch JSON ↔ form-encoded ↔ multipart ↔ text/plain; some code paths only validate one
Key Path Variants
- Dot/bracket/object re-shaping to reach nested fields through different binders
Batch Paths
- Per-item checks skipped in bulk operations
- Insert a single malicious object within a large batch
Race and Reorder
- Race two updates: first sets forbidden field, second normalizes
- Final state may retain forbidden change
Testing Methodology
- Identify endpoints - Create/update endpoints and GraphQL mutations
- Capture responses - Observe returned fields to build candidate list
- Build sensitive-field dictionary - Per resource: role, isAdmin, ownerId, status, plan, limits, flags
- Inject candidates - Alongside legitimate updates across transports and encodings
- Compare state - Before/after diffs across roles
- Test variations - Nested objects, arrays, alternative shapes, duplicate keys, batch operations
Validation
- Show a minimal request where adding a sensitive field changes persisted state for a non-privileged caller
- Provide before/after evidence (response body, subsequent GET, or GraphQL query) proving the forbidden attribute value
- Demonstrate consistency across at least two encodings or channels
- For nested/bulk, show that protected fields are written within child objects or array elements
- Quantify impact (e.g., role flip, cross-tenant move, quota increase) and reproducibility
False Positives
- Server recomputes derived fields (plan/price/role) ignoring client input
- Fields marked read-only and enforced consistently across encodings
- Only UI-side changes with no persisted effect
Impact
- Privilege escalation and admin feature access
- Cross-tenant or cross-account resource takeover
- Financial/billing manipulation and quota abuse
- Policy/approval bypass by toggling verification or status flags
Pro Tips
- Build a sensitive-field dictionary per resource and fuzz systematically
- Always try alternate shapes and encodings; many validators are shape/CT-specific
- For GraphQL, diff the resource immediately after mutation; effects are often visible even if the mutation returns filtered fields
- Inspect SDKs/mobile apps for hidden field names and nested write examples
- Prefer minimal PoCs that prove durable state changes; avoid UI-only effects
Summary
Mass assignment is eliminated by explicit mapping and per-field authorization. Treat every client-supplied attribute—especially nested or batch inputs—as untrusted until validated against an allowlist and caller scope.
Platform Methodology
Mass Assignment Testing
penkit51 AI — professional penetration testing skill pack. Authorized testing only.
Deep Exploitation Guide
Mass Assignment
Mass assignment binds client-supplied fields directly into models/DTOs without field-level allowlists. It commonly leads to privilege escalation, ownership changes, and unauthorized state transitions in modern APIs and GraphQL.
Attack Surface
- REST/JSON, GraphQL inputs, form-encoded and multipart bodies
- Model binding in controllers/resolvers; ORM create/update helpers
- Writable nested relations, sparse/patch updates, bulk endpoints
Reconnaissance
Surface Map
- Controllers with automatic binding (e.g., request.json → model)
- GraphQL input types mirroring models; admin/staff tools exposed via API
- OpenAPI/GraphQL schemas: uncover hidden fields or enums
- Client bundles and mobile apps: inspect forms and mutation payloads for field names
Parameter Strategies
- Flat fields:
isAdmin, role, roles[], permissions[], status, plan, tier, premium, verified, emailVerified
- Ownership/tenancy:
userId, ownerId, accountId, organizationId, tenantId, workspaceId
- Limits/quotas:
usageLimit, seatCount, maxProjects, creditBalance
- Feature flags/gates:
features, flags, betaAccess, allowImpersonation
- Billing:
price, amount, currency, prorate, nextInvoice, trialEnd
Shape Variants
- Alternate shapes: arrays vs scalars; nested JSON; objects under unexpected keys
- Dot/bracket paths:
profile.role, profile[role], settings[roles][]
- Duplicate keys and precedence:
{"role":"user","role":"admin"}
- Sparse/patch formats: JSON Patch/JSON Merge Patch; try adding forbidden paths
Encodings and Channels
- Content-types:
application/json, application/x-www-form-urlencoded, multipart/form-data, text/plain
- GraphQL: add suspicious fields to input objects; overfetch response to detect changes
- Batch/bulk: arrays of objects; verify per-item allowlists not skipped
Key Vulnerabilities
Privilege Escalation
- Set role/isAdmin/permissions during signup/profile update
- Toggle admin/staff flags where exposed
Ownership Takeover
- Change ownerId/accountId/tenantId to seize resources
- Move objects across users/tenants
Feature Gate Bypass
- Enable premium/beta/feature flags via flags/features fields
- Raise limits/seatCount/quotas
Billing and Entitlements
- Modify plan/price/prorate/trialEnd or creditBalance
- Bypass server recomputation
Nested and Relation Writes
- Writable nested serializers or ORM relations allow creating or linking related objects beyond caller's scope
Advanced Techniques
GraphQL Specific
- Field-level authz missing on input types: attempt forbidden fields in mutation inputs
- Combine with aliasing/batching to compare effects
- Use fragments to overfetch changed fields immediately after mutation
ORM Framework Edges
- Rails: strong parameters misconfig or deep nesting via
accepts_nested_attributes_for
- Laravel: $fillable/$guarded misuses;
guarded=[] opens all; casts mutating hidden fields
- Django REST Framework: writable nested serializer, read_only/extra_kwargs gaps, partial updates
- Mongoose/Prisma: schema paths not filtered;
select:false doesn't prevent writes; upsert defaults
Parser and Validator Gaps
- Validators run post-bind and do not cover extra fields
- Unknown fields silently dropped in response but persisted underneath
- Inconsistent allowlists between mobile/web/gateway; alt encodings bypass validation pipeline
Bypass Techniques
Content-Type Switching
- Switch JSON ↔ form-encoded ↔ multipart ↔ text/plain; some code paths only validate one
Key Path Variants
- Dot/bracket/object re-shaping to reach nested fields through different binders
Batch Paths
- Per-item checks skipped in bulk operations
- Insert a single malicious object within a large batch
Race and Reorder
- Race two updates: first sets forbidden field, second normalizes
- Final state may retain forbidden change
Testing Methodology
- Identify endpoints - Create/update endpoints and GraphQL mutations
- Capture responses - Observe returned fields to build candidate list
- Build sensitive-field dictionary - Per resource: role, isAdmin, ownerId, status, plan, limits, flags
- Inject candidates - Alongside legitimate updates across transports and encodings
- Compare state - Before/after diffs across roles
- Test variations - Nested objects, arrays, alternative shapes, duplicate keys, batch operations
Validation
- Show a minimal request where adding a sensitive field changes persisted state for a non-privileged caller
- Provide before/after evidence (response body, subsequent GET, or GraphQL query) proving the forbidden attribute value
- Demonstrate consistency across at least two encodings or channels
- For nested/bulk, show that protected fields are written within child objects or array elements
- Quantify impact (e.g., role flip, cross-tenant move, quota increase) and reproducibility
False Positives
- Server recomputes derived fields (plan/price/role) ignoring client input
- Fields marked read-only and enforced consistently across encodings
- Only UI-side changes with no persisted effect
Impact
- Privilege escalation and admin feature access
- Cross-tenant or cross-account resource takeover
- Financial/billing manipulation and quota abuse
- Policy/approval bypass by toggling verification or status flags
Pro Tips
- Build a sensitive-field dictionary per resource and fuzz systematically
- Always try alternate shapes and encodings; many validators are shape/CT-specific
- For GraphQL, diff the resource immediately after mutation; effects are often visible even if the mutation returns filtered fields
- Inspect SDKs/mobile apps for hidden field names and nested write examples
- Prefer minimal PoCs that prove durable state changes; avoid UI-only effects
Summary
Mass assignment is eliminated by explicit mapping and per-field authorization. Treat every client-supplied attribute—especially nested or batch inputs—as untrusted until validated against an allowlist and caller scope.
Validation & Reporting
- Confirm every finding with reproducible PoC before reporting
- Document: severity (CVSS), affected asset, steps, evidence, remediation
- Use
record_vulnerability when running inside the penkit51 platform
- Chain low-severity findings into higher-impact attack paths
- Never report without evidence — distinguish hypothesis from confirmed vuln
Validation & Reporting
- Confirm every finding with reproducible PoC before reporting
- Document: severity (CVSS), affected asset, steps, evidence, remediation
- Use
record_vulnerability when running inside the penkit51 platform
- Chain low-severity findings into higher-impact attack paths
- Never report without evidence — distinguish hypothesis from confirmed vuln