Primordyx Framework Documentation

Params
in package

FinalYes

Class Params

Static request parameter handler with comprehensive RESTful support and focused DoS protection. Handles GET, POST, PUT, DELETE, PATCH requests with JSON, form-encoded, and multipart data.

FIXES APPLIED:

  1. ✅ POST multipart requests now properly use PHP's built-in $_FILES and $_POST data
  2. ✅ Files are always copied from $_FILES to self::$files during init()
  3. ✅ Method detection works even if Params::init() isn't called (with fallback)
  4. ✅ Raw input is not read for POST requests (already consumed by PHP)

RESTful verbs...

 GET - Retrieve/read data. Safe & idempotent (no side effects, can repeat safely).
 POST - Create new resources. Not idempotent (creates new thing each time).
 PUT - Update/replace entire resource. Idempotent (same result if repeated).
 PATCH - Partial update of resource. May or may not be idempotent.
 DELETE - Remove resource. Idempotent (safe to repeat).
 HEAD - Like GET but only returns headers (no body). For metadata/existence checks.
 OPTIONS - Get allowed methods/capabilities for a resource. CORS preflight.

Primordyx framework supports all the main ones (GET, POST, PUT, DELETE) in both the Router and HttpClient classes. The Params class handles parsing request data for all these methods, which is especially important for PUT/PATCH/DELETE since PHP doesn't auto-populate $_POST for those.

SECURITY FEATURES (focused purely on DoS/memory protection):

  • Request size limiting to prevent memory exhaustion attacks
  • Line length validation to prevent buffer overflow attempts
  • JSON depth limiting to prevent JSON bomb attacks
  • Multipart boundary validation and part count limiting
  • Filename sanitization and path traversal protection for uploads
  • Dangerous file type blocking for uploads
  • Secure temporary file creation with proper permissions
  • Comprehensive security event logging via EventManager
  • ALWAYS GRACEFUL: Never throws exceptions, always handles issues safely
  • Defensive design: Log issues and continue with safe defaults
Tags
author

Vern Six vernsix@gmail.com

copyright

Copyright (c) 2025

license

MIT License

since
1.0.0
version
1.0.0
link
https://github.com/vernsix/primordyx/blob/master/src/Params.php

Table of Contents

Properties

$files  : array<string|int, mixed>
$formData  : array<string|int, mixed>
$get  : array<string|int, mixed>
$inputData  : array<string|int, mixed>
$json  : array<string|int, mixed>
$maxChunkSize  : int
$maxInputSize  : int
$method  : string
$post  : array<string|int, mixed>
$rawInput  : string
$skipOnSecurityIssues  : bool

Methods

__wakeup()  : mixed
all()  : array<string|int, mixed>
Get all parameters with custom priority
contentType()  : string
except()  : array<string|int, mixed>
Get all except specific keys
files()  : array<string|int, mixed>
formData()  : array<string|int, mixed>
get()  : mixed
Retrieves request parameter with intelligent source prioritization and fallback handling.
has()  : bool
Check if parameter exists
init()  : void
Initialize and parse request parameters with comprehensive security protections.
input()  : mixed
Accesses the intelligently merged input data with unified parameter access.
isDelete()  : bool
isGet()  : bool
isMethod()  : bool
isPatch()  : bool
isPost()  : bool
isPut()  : bool
isRestMethod()  : bool
json()  : array<string|int, mixed>
method()  : string
only()  : array<string|int, mixed>
Get only specific keys
rawInput()  : string
__clone()  : mixed
__construct()  : mixed
buildInputData()  : void
Builds unified input data structure with intelligent priority-based merging.
createTempFileSafely()  : string
Safely create temporary file with security protections Never throws - returns empty string on failure.
extractContentType()  : string
Extract content type from multipart headers
parseInputData()  : void
Intelligently parses request content based on Content-Type header with maximum compatibility.
parseMultipartData()  : void
Parses multipart/form-data with comprehensive security protections for file uploads.
processMultipartFile()  : void
Processes individual multipart file uploads with comprehensive security validation.
readInputSafely()  : string
Safely reads HTTP request body with comprehensive DoS protection mechanisms.
validateInputContent()  : bool
Validates input content structure to prevent various DoS attacks.
validateJsonDepth()  : bool
Validates JSON depth to prevent JSON bomb attacks.

Properties

$files

private static array<string|int, mixed> $files = []

$formData

private static array<string|int, mixed> $formData = []

$get

private static array<string|int, mixed> $get = []

$inputData

private static array<string|int, mixed> $inputData = []

$json

private static array<string|int, mixed> $json = []

$maxChunkSize

private static int $maxChunkSize = 8192

$maxInputSize

private static int $maxInputSize = 52428800

$method

private static string $method = ''

$post

private static array<string|int, mixed> $post = []

$rawInput

private static string $rawInput = ''

$skipOnSecurityIssues

private static bool $skipOnSecurityIssues = true

Methods

__wakeup()

public __wakeup() : mixed

all()

Get all parameters with custom priority

public static all([array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
$priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>

contentType()

public static contentType() : string
Return values
string

except()

Get all except specific keys

public static except(array<string|int, mixed> $keys[, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
$keys : array<string|int, mixed>
$priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>

files()

public static files() : array<string|int, mixed>
Return values
array<string|int, mixed>

formData()

public static formData() : array<string|int, mixed>
Return values
array<string|int, mixed>

get()

Retrieves request parameter with intelligent source prioritization and fallback handling.

public static get(string $key[, mixed|null $default = null ][, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : mixed

This method provides the primary interface for accessing request parameters with built-in fallback logic that searches multiple data sources in priority order. It's designed to handle the complexity of modern web applications that may receive data via multiple channels (URL parameters, form data, JSON payloads) within a single request.

SEARCH PRIORITY (configurable): Default: ['get', 'input', 'post', 'json']

  • 'get': URL query parameters ($_GET)
  • 'input': Merged input data (smart combination of all sources)
  • 'post': Traditional POST data ($_POST)
  • 'json': Parsed JSON request body
  • 'form': Form-encoded data from PUT/PATCH/DELETE requests

PRIORITY RATIONALE:

  • GET parameters take precedence (explicit user intent via URL)
  • Input data provides smart merged view of all body parameters
  • POST data for backward compatibility with traditional applications
  • JSON data as fallback for API-specific parameter access

COMMON USAGE PATTERNS:

Basic Parameter Access:

$name = Params::get('name');              // Search all sources
$email = Params::get('email', 'default'); // With default value

Source-Specific Access:

$id = Params::get('id', null, ['get']);           // Only URL parameters
$data = Params::get('data', [], ['json', 'form']); // API data only

API Development:

$filters = Params::get('filters', [], ['get', 'json']); // URL or JSON
$sort = Params::get('sort', 'id', ['get']);             // URL only

Form Processing:

$username = Params::get('username', '', ['post', 'form']); // Traditional or RESTful

FALLBACK BEHAVIOR:

  • Searches sources in specified order
  • Returns first non-null value found
  • Returns default value if parameter not found in any source
  • Maintains original data types (string, array, etc.)

DATA TYPE PRESERVATION:

  • Strings: Returned as-is
  • Arrays: Complex structures preserved
  • Numbers: Maintains original type (string/int/float)
  • Booleans: Preserved from JSON parsing
  • Null: Treated as "not found", continues search

SECURITY CONSIDERATIONS:

  • All data sources already validated during parsing
  • No additional sanitization performed (use validation layer)
  • Returns raw parameter values for application-level processing
  • No automatic type coercion that could mask security issues

PERFORMANCE CHARACTERISTICS:

  • O(p*s) where p is priority list length, s is source search time
  • Early termination when parameter found
  • Minimal overhead for cached/parsed data access
  • No data copying during search process

ERROR HANDLING:

  • Invalid source names: Silently ignored, continues search
  • Missing data structures: Treated as empty, continues search
  • No exceptions thrown regardless of input

DEBUGGING SUPPORT:

  • Use source() method to determine where parameter originated
  • Clear priority order for predictable behavior
  • All original data sources remain accessible
Parameters
$key : string

Parameter name to search for

$default : mixed|null = null

Default value if parameter not found in any source

$priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']

List of source names in search order

Tags
see
self::input()

For direct access to merged input data

see
self::source()

For determining parameter source

see
self::has()

For checking parameter existence

Return values
mixed

Parameter value from first matching source, or default value

has()

Check if parameter exists

public static has(string $key) : bool
Parameters
$key : string
Return values
bool

init()

Initialize and parse request parameters with comprehensive security protections.

public static init() : void

This method must be called once at the start of your application to parse the incoming HTTP request. It performs several critical security validations to protect against DoS attacks while maintaining maximum compatibility with legitimate requests.

SECURITY PROTECTIONS APPLIED:

  1. Memory exhaustion protection via size limits
  2. Buffer overflow protection via line length limits
  3. JSON bomb protection via nesting depth limits
  4. Multipart abuse protection via part count limits
  5. File upload security via type and path validation

GRACEFUL ERROR HANDLING:

  • Never throws exceptions regardless of input
  • Logs all security issues via EventManager for monitoring
  • Continues processing with safe defaults when issues are detected
  • Skips malicious/oversized content rather than crashing

PARSING BEHAVIOR:

  • Attempts to parse JSON, form-encoded, and multipart data based on Content-Type
  • Unknown content types are safely ignored (stored as raw data only)
  • Combines all parsed data into smart priority-based access methods
  • Maintains backward compatibility with traditional PHP request handling

MEMORY SAFETY:

  • Reads input stream in small chunks to prevent memory spikes
  • Enforces configurable size limits (50MB default, 0 = unlimited)
  • Validates content structure before full parsing
  • Automatically truncates oversized content rather than failing

USAGE: Call this method once during application bootstrap:

Params::init(); // Parse request with security protections

EVENTS FIRED:

  • Params.security.request_too_large: When request exceeds size limits
  • Params.security.input_stream_failed: When php://input cannot be opened
  • Params.security.line_too_long: When input contains extremely long lines
  • Params.security.json_too_deep: When JSON nesting exceeds safe limits
  • Various multipart and file upload security events (see parseMultipartData)
Tags
see
self::readInputSafely()

For details on memory-safe input reading

see
self::validateInputContent()

For content structure validation

see
self::parseInputData()

For multi-format parsing logic

input()

Accesses the intelligently merged input data with unified parameter access.

public static input([string|null $key = null ][, mixed|null $default = null ]) : mixed

This method provides direct access to the merged input data structure created by buildInputData(). It represents the "best" view of all request parameters, combining data from multiple sources using smart prioritization rules. This is typically the preferred method for modern web applications and APIs.

TWO USAGE MODES:

  1. BULK ACCESS (no parameters): Returns the complete merged parameter array containing all request data from all sources, resolved using priority rules.

  2. SINGLE PARAMETER ACCESS (with key): Returns a specific parameter value from the merged data, with optional default value if the parameter doesn't exist.

MERGED DATA COMPOSITION: The returned data structure combines parameters from multiple sources:

  • GET parameters (highest priority)
  • Form-encoded data from request body
  • JSON data from request body
  • POST parameters (backward compatibility)

WHEN TO USE input() vs get():

Use input() when:

  • You want the "smart merged" view of request data
  • Building RESTful APIs with consistent parameter access
  • You trust the priority system to resolve conflicts correctly
  • Working with modern applications that mix parameter sources

Use get() when:

  • You need explicit control over source priority
  • Debugging parameter conflicts between sources
  • Working with legacy applications with specific source requirements
  • You need to override default priority behavior

EXAMPLE USAGE SCENARIOS:

RESTful API Controller:

// Get all request parameters for processing
$requestData = Params::input();
$user = new User($requestData);

// Get specific parameters with defaults
$limit = Params::input('limit', 20);
$offset = Params::input('offset', 0);

Form Processing:

// Handle both traditional forms and API requests
$username = Params::input('username');
$email = Params::input('email');
$preferences = Params::input('preferences', []);

Search/Filter Implementation:

// URL params override JSON body for flexibility
$filters = Params::input('filters', []);
$search = Params::input('q', '');
$page = Params::input('page', 1);

CONFLICT RESOLUTION EXAMPLES:

URL Override: Request: PUT /users/123?status=active with JSON: {"status": "inactive"} Result: Params::input('status') returns "active"

Complementary Data: Request: POST /search?q=php with Form: {"category": "tutorials"} Result: Params::input() returns {"q": "php", "category": "tutorials"}

DATA TYPE PRESERVATION:

  • Maintains original data types from parsing
  • JSON booleans remain boolean, not converted to strings
  • Arrays and objects preserved as complex structures
  • Numbers maintain their original representation

SECURITY CONSIDERATIONS:

  • All data already validated during request parsing
  • No additional sanitization applied (responsibility of application)
  • Priority rules prevent parameter pollution attacks
  • Returns raw values for application-level validation/sanitization

PERFORMANCE CHARACTERISTICS:

  • Bulk access: O(1) direct array access
  • Single parameter: O(1) hash table lookup
  • No data copying, returns references to existing structures
  • Minimal overhead compared to manual source checking

NULL vs MISSING DISTINCTION:

  • Null values: Explicitly set null values are preserved and returned
  • Missing keys: Return the provided default value
  • Empty strings: Preserved as empty strings, not treated as missing

DEBUGGING SUPPORT:

  • Use source() method to determine original parameter source
  • Compare with individual source methods (json(), formData(), etc.)
  • Predictable priority rules for conflict resolution
Parameters
$key : string|null = null

Optional parameter name for single value access

$default : mixed|null = null

Default value returned if key not found (single access mode only)

Tags
see
self::buildInputData()

For details on how merged data is created

see
self::get()

For priority-configurable parameter access

see
self::all()

For custom priority bulk access

Return values
mixed

Full parameter array (bulk access) or single parameter value

isDelete()

public static isDelete() : bool
Return values
bool

isGet()

public static isGet() : bool
Return values
bool

isMethod()

public static isMethod(string $verb) : bool
Parameters
$verb : string
Return values
bool

isPatch()

public static isPatch() : bool
Return values
bool

isPost()

public static isPost() : bool
Return values
bool

isPut()

public static isPut() : bool
Return values
bool

isRestMethod()

public static isRestMethod() : bool
Return values
bool

json()

public static json() : array<string|int, mixed>
Return values
array<string|int, mixed>

method()

public static method() : string
Return values
string

only()

Get only specific keys

public static only(array<string|int, mixed> $keys[, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
$keys : array<string|int, mixed>
$priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>

rawInput()

public static rawInput() : string
Return values
string

__clone()

private __clone() : mixed

__construct()

private __construct() : mixed

buildInputData()

Builds unified input data structure with intelligent priority-based merging.

private static buildInputData() : void

This method creates a single, unified view of all request parameters by intelligently combining data from multiple sources (GET, POST, form-encoded, JSON) using a priority system that matches common web development expectations and RESTful API patterns.

PRIORITY HIERARCHY (highest to lowest):

  1. GET parameters ($_GET) - Highest priority
  2. Form-encoded data (parsed from request body)
  3. JSON data (parsed from request body)
  4. POST parameters ($_POST) - Lowest priority

PRIORITY RATIONALE:

GET Parameters (Highest Priority):

  • Explicitly visible in URL, user's clear intent
  • Common pattern for filtering, pagination, sorting
  • Should override any conflicting body parameters
  • Example: /users?limit=10 should override body {"limit": 20}

Form-Encoded Data (High Priority):

  • Traditional web form submissions
  • More specific than JSON for field-level data
  • Handles PUT/PATCH form submissions properly
  • Maintains backward compatibility with form-based workflows

JSON Data (Medium Priority):

  • Modern API standard for structured data
  • Excellent for complex nested data structures
  • Lower priority allows form overrides for specific fields
  • Common in RESTful API implementations

POST Parameters (Lowest Priority):

  • Included for backward compatibility only
  • Usually redundant with form-encoded data
  • Serves as fallback for edge cases
  • Ensures no data is lost during transition

MERGING BEHAVIOR:

  • Later sources in priority order overwrite earlier sources
  • Only overwrites specific keys, not entire data structures
  • Preserves unique keys from all sources
  • Maintains data type integrity during merging

EXAMPLE MERGING SCENARIOS:

Scenario 1 - Parameter Override: JSON: {"name": "John", "age": 25} Form: {"name": "Jane"} GET: {"age": 30} Result: {"name": "Jane", "age": 30}

Scenario 2 - Complementary Data: JSON: {"user": {"name": "John"}} Form: {"action": "update"} GET: {"debug": "true"} Result: {"user": {"name": "John"}, "action": "update", "debug": "true"}

Scenario 3 - Complex Structures: JSON: {"filters": {"status": "active", "type": "user"}} GET: {"filters": {"status": "inactive"}} Result: {"filters": {"status": "inactive"}} (GET overrides entire filters object)

API DESIGN BENEFITS:

  • Single input() method provides all request data
  • Predictable priority system reduces confusion
  • Supports both traditional forms and modern APIs
  • Enables flexible parameter passing strategies

COMPATIBILITY CONSIDERATIONS:

  • Maintains access to individual data sources (json(), formData(), etc.)
  • Doesn't modify original source data structures
  • Backward compatible with existing parameter access patterns
  • Supports gradual migration from traditional to RESTful patterns

MEMORY EFFICIENCY:

  • Merging creates new references, not data copies
  • Array merge operations are optimized by PHP
  • Minimal memory overhead for the unified view
  • Original data structures remain available

EDGE CASE HANDLING:

  • Empty data sources: Safely ignored during merging
  • Null values: Preserved and can override non-null values
  • Mixed data types: Preserved without type coercion
  • Nested arrays: Replaced entirely, not merged recursively

SECURITY IMPLICATIONS:

  • No additional security risks from merging process
  • All data sources already validated before merging
  • Priority system prevents parameter pollution attacks
  • No data transformation that could introduce vulnerabilities

DEBUGGING AND OBSERVABILITY:

  • Merged data available via input() method
  • Original sources remain accessible for debugging
  • Clear priority rules for predictable behavior
  • Source tracking available via source() method

PERFORMANCE CHARACTERISTICS:

  • O(n) where n is total number of parameters across all sources
  • Minimal CPU overhead for array operations
  • Memory usage proportional to unique parameter count
  • Executed once per request during initialization
Tags
see
self::input()

For accessing the merged parameter data

see
self::get()

For priority-aware parameter access with fallbacks

see
self::source()

For determining parameter source

createTempFileSafely()

Safely create temporary file with security protections Never throws - returns empty string on failure.

private static createTempFileSafely(string $data) : string
Parameters
$data : string
Return values
string

Temporary file path, or empty string on failure

extractContentType()

Extract content type from multipart headers

private static extractContentType(string $headers) : string
Parameters
$headers : string
Return values
string

parseInputData()

Intelligently parses request content based on Content-Type header with maximum compatibility.

private static parseInputData() : void

This method implements a sophisticated content parsing system that handles multiple data formats commonly used in RESTful APIs and web applications. It's designed to maximize compatibility while maintaining security through defensive parsing practices.

SUPPORTED CONTENT TYPES:

  1. application/json: Standard JSON API requests
  2. application/x-www-form-urlencoded: Traditional HTML form submissions
  3. multipart/form-data: File uploads and complex form data
  4. Unknown types: Safely stored as raw data without parsing

PARSING STRATEGY BY TYPE:

JSON (application/json):

  • Uses built-in json_decode with strict array mode
  • Handles malformed JSON gracefully (returns empty array)
  • Preserves nested data structures for complex APIs
  • Already protected by validateJsonDepth() against JSON bombs
  • Stores result in $json property for direct access

Form-Encoded (application/x-www-form-urlencoded):

  • Uses parse_str() to convert URL-encoded data to array
  • Only processes for PUT/PATCH/DELETE (POST handled by PHP automatically)
  • Handles complex field names like arrays: field[key]=value
  • Stores result in $formData property for consistent access
  • Maintains compatibility with traditional form processing

Multipart (multipart/form-data):

  • Custom parser for file uploads via non-POST methods
  • Handles mixed content: text fields + binary files
  • Implements comprehensive security validations (see parseMultipartData)
  • Populates both $formData (fields) and $files (uploads)
  • FIXED: Now processes for ALL methods including POST

Unknown Content Types:

  • No parsing attempted (security by design)
  • Content stored as raw data only
  • No errors generated (graceful degradation)
  • Application can access via rawInput() if needed
  • Prevents parser vulnerabilities from unknown formats

METHOD-SPECIFIC BEHAVIOR:

GET Requests:

  • No request body parsing (follows HTTP semantics)
  • Only $_GET parameters processed
  • Raw input ignored (GET shouldn't have request body)

POST Requests:

  • FIXED: Now properly handles multipart data via PHP's built-in parsing
  • Files from $_FILES are copied to self::$files during init()
  • FormData mirrors $_POST for API consistency
  • Maintains backward compatibility with existing code

PUT/PATCH/DELETE Requests:

  • Full custom parsing (PHP doesn't auto-parse these)
  • Enables RESTful API support with proper data access
  • Handles all content types that POST supports
  • Essential for modern API development

SECURITY CONSIDERATIONS:

  • Never attempts to parse untrusted/unknown formats
  • All parsing operations are defensive (handle malformed input)
  • Size and structure already validated before parsing
  • Parser failures result in empty data, not crashes
  • No execution of dynamic content during parsing

ERROR HANDLING PHILOSOPHY:

  • Malformed JSON: Results in empty array, continues processing
  • Invalid form data: Skips malformed fields, processes valid ones
  • Multipart errors: Detailed handling in parseMultipartData()
  • Unknown formats: Gracefully ignored, no error conditions
  • Parser exceptions: Caught and handled without application impact

COMPATIBILITY NOTES:

  • Maintains full backward compatibility with traditional PHP request handling
  • Extends PHP's capabilities to handle RESTful methods properly
  • No interference with existing $_GET, $_POST, $_FILES usage
  • Additional data available through enhanced access methods

PERFORMANCE CHARACTERISTICS:

  • JSON parsing: O(n) where n is JSON size, efficient built-in parser
  • Form parsing: O(n) URL decoding, minimal overhead
  • Multipart parsing: O(m) where m is number of parts, custom implementation
  • Unknown types: O(1) no parsing overhead
  • Memory usage: Proportional to parsed data size, not raw input size

EXTENSIBILITY:

  • Easy to add support for new content types (XML, MessagePack, etc.)
  • Modular design allows format-specific security validations
  • Parser selection based on Content-Type header inspection
  • Graceful fallback for unsupported types
Tags
see
self::parseMultipartData()

For detailed multipart/form-data handling

see
self::buildInputData()

For priority-based data combination logic

parseMultipartData()

Parses multipart/form-data with comprehensive security protections for file uploads.

private static parseMultipartData() : void

This method implements a custom multipart parser necessary for handling file uploads via PUT, PATCH, and DELETE requests (PHP only auto-parses multipart for POST). It includes extensive security validations to prevent various attack vectors commonly associated with file upload functionality.

IMPORTANT: This parser is NOT used for POST requests because:

  • PHP automatically handles POST multipart and populates $_POST and $_FILES
  • php://input is already consumed by PHP for POST requests
  • POST multipart data is handled in init() by copying $_FILES to self::$files

WHY CUSTOM PARSER IS NEEDED FOR NON-POST METHODS:

  • PHP only populates $_POST and $_FILES for POST requests
  • RESTful APIs need file upload support for PUT/PATCH operations
  • Built-in parser doesn't provide necessary security controls
  • Custom implementation allows fine-grained security policies

MULTIPART FORMAT OVERVIEW:

  • Content separated by boundary strings defined in Content-Type header
  • Each part has headers (Content-Disposition, Content-Type) and data
  • Parts can contain form fields (text) or file uploads (binary)
  • Complex nested structures possible (arrays, objects)

SECURITY PROTECTIONS IMPLEMENTED:

  1. BOUNDARY VALIDATION:
  • Purpose: Prevent parser confusion and resource exhaustion
  • Validation: Boundary must be present and reasonable length (< 256 chars)
  • Attack vector: Missing or extremely long boundaries can cause parser issues
  • Handling: Skip processing entirely if boundary is invalid
  1. PART COUNT LIMITING:
  • Purpose: Prevent resource exhaustion via excessive form parts
  • Limit: Maximum 1000 parts per request
  • Attack vector: Requests with millions of empty parts to consume memory/CPU
  • Handling: Stop processing after limit reached, log security event
  1. HEADER SIZE VALIDATION:
  • Purpose: Prevent buffer overflow attacks via oversized headers
  • Limit: 8KB per part's headers
  • Attack vector: Extremely long Content-Disposition or other headers
  • Handling: Skip individual parts with oversized headers
  1. FIELD NAME VALIDATION:
  • Purpose: Prevent various injection and parsing attacks
  • Validation: Alphanumeric plus underscore, brackets, hyphen only
  • Length limit: 255 characters maximum
  • Attack vector: Field names with special characters, path traversal, etc.
  • Handling: Skip parts with invalid field names
  1. FIELD SIZE LIMITING:
  • Purpose: Prevent memory exhaustion via oversized form fields
  • Limit: 1MB per individual form field
  • Attack vector: Single form field containing GB of data
  • Handling: Skip oversized fields, continue processing others
  1. FILE UPLOAD SECURITY:
  • Comprehensive file validation in processMultipartFile()
  • Filename sanitization and path traversal protection
  • File type validation and dangerous type blocking
  • Individual file size limits
  • Secure temporary file creation with restricted permissions

PARSING ALGORITHM:

  1. Extract and validate boundary from Content-Type header
  2. Split raw data by boundary markers
  3. Process each part individually with security checks
  4. Parse headers using regex with size limits
  5. Validate Content-Disposition header for field name and filename
  6. Apply security validations based on content type (field vs file)
  7. Store validated data in appropriate collections

ERROR HANDLING STRATEGY:

  • Malformed parts: Skip individual parts, continue processing others
  • Invalid headers: Log and skip, don't fail entire request
  • Security violations: Log detailed events, skip violating content
  • Boundary issues: Skip entire multipart processing
  • Resource limits: Stop processing, return partial results

MEMORY EFFICIENCY:

  • Processes parts sequentially, not all at once
  • Immediately validates and rejects oversized content
  • No unnecessary data copying during processing
  • Temporary files created only for valid uploads
  • Progressive parsing reduces peak memory usage

SECURITY EVENT LOGGING:

  • Boundary validation failures
  • Part count limit exceeded
  • Header size violations
  • Invalid field names
  • Field size violations
  • File upload security events
  • Processing completion statistics

COMPATIBILITY NOTES:

  • Handles standard RFC 7578 multipart/form-data format
  • Compatible with most HTTP clients and browsers
  • Supports nested field names (arrays, objects)
  • Maintains compatibility with $_FILES structure for uploads

ATTACK SCENARIOS PREVENTED:

  • Resource exhaustion via thousands of tiny parts
  • Memory exhaustion via oversized individual parts
  • Parser confusion via malformed boundaries
  • Buffer overflow via extremely long headers
  • Path traversal via malicious filenames
  • Code execution via dangerous file types
  • Temporary file attacks via insecure file creation

PERFORMANCE CHARACTERISTICS:

  • Linear processing: O(n) where n is number of parts
  • Memory usage: O(largest_part) not O(total_size)
  • Early rejection: Invalid content rejected before expensive processing
  • Streaming approach: Processes data as it's encountered
Tags
see
self::processMultipartFile()

For detailed file upload security

see
self::createTempFileSafely()

For secure temporary file creation

processMultipartFile()

Processes individual multipart file uploads with comprehensive security validation.

private static processMultipartFile(string $name, string $filename, string $headers, string $data) : void

This method handles the secure processing of file uploads from multipart/form-data requests. It implements multiple layers of security validation to prevent common file upload attack vectors while maintaining compatibility with legitimate uploads.

SECURITY VALIDATIONS IMPLEMENTED:

  1. FILENAME LENGTH ATTACKS:
  • Attack: Extremely long filenames to cause buffer overflows
  • Protection: 255 character limit (filesystem standard)
  • Action: Reject oversized filenames, continue processing
  • Rationale: Most filesystems have 255 char filename limits
  1. PATH TRAVERSAL ATTACKS:
  • Attack: Filenames containing ../ or ..\ to escape upload directory
  • Protection: Pattern detection and rejection
  • Action: Reject suspicious filenames, log attempt
  • Rationale: Prevents files from being written outside intended directory
  1. FILE SIZE ATTACKS:
  • Attack: Extremely large files to exhaust disk space or memory
  • Protection: 10MB limit per individual file
  • Action: Reject oversized files, log attempt, continue processing
  • Rationale: Prevents single files from consuming excessive resources
  1. DANGEROUS FILE TYPE ATTACKS:
  • Attack: Upload executable files that could be executed on server
  • Protection: Block known dangerous MIME types
  • Dangerous types: PHP scripts, executables, shell scripts
  • Action: Reject dangerous types, log attempt, continue processing
  • Note: Content-Type can be spoofed, additional validation recommended
  1. TEMPORARY FILE ATTACKS:
  • Attack: Exploit insecure temporary file creation
  • Protection: Secure temp file creation with restricted permissions (0600)
  • Location: Dedicated upload directory with proper isolation
  • Cleanup: Automatic cleanup on script termination

VALIDATION SEQUENCE:

  1. Filename length validation (< 255 characters)
  2. Path traversal detection (../ and ..\ patterns)
  3. File size validation (< 10MB per file)
  4. Content-Type extraction and validation
  5. Dangerous file type detection
  6. Secure temporary file creation
  7. Data writing with integrity verification
  8. File structure population for application use

DANGEROUS FILE TYPES BLOCKED:

  • application/x-php: PHP scripts
  • application/x-httpd-php: Alternative PHP MIME type
  • text/x-php: PHP source files
  • application/x-executable: Binary executables
  • application/x-msdownload: Windows executables
  • application/x-sh: Shell scripts

SECURE FILE HANDLING:

  • Temporary files created with 0600 permissions (owner read/write only)
  • Files stored in isolated temporary directory
  • Automatic cleanup prevents temporary file accumulation
  • Basename() used to strip path information from filenames
  • Content integrity verified during write operations

COMPATIBILITY WITH PHP $_FILES:

  • Maintains standard $_FILES array structure
  • Compatible with existing file upload processing code
  • Standard error codes (UPLOAD_ERR_OK)
  • Consistent field naming and data types

ERROR HANDLING PHILOSOPHY:

  • Individual file failures don't affect other files
  • Detailed logging for security analysis
  • Graceful degradation: skip problematic files, continue processing
  • No exceptions thrown regardless of input

SECURITY EVENT LOGGING: Each validation failure generates detailed events including:

  • Specific validation failure reason
  • Original filename and field name
  • File size and content type
  • IP address and user agent (for attack attribution)
  • Timestamp and request context

PERFORMANCE CONSIDERATIONS:

  • Validations performed in order of computational cost (cheap first)
  • Early rejection prevents expensive operations on invalid files
  • Streaming file creation avoids memory duplication
  • Efficient pattern matching for security validations

DEFENSE IN DEPTH: This method provides the first layer of file upload security. Additional recommended protections include:

  • Virus scanning of uploaded files
  • File content validation (magic number checking)
  • Sandboxed execution environment for file processing
  • Regular cleanup of temporary directories
  • Monitoring for unusual upload patterns

USAGE NOTES:

  • Called automatically during multipart parsing
  • Creates entries in self::$files array for valid uploads
  • Invalid files are silently skipped with security logging
  • Application should verify file existence before use
Parameters
$name : string

Form field name for the file upload

$filename : string

Original filename from client

$headers : string

Raw headers from multipart section

$data : string

Raw binary file data

Tags
see
self::createTempFileSafely()

For secure temporary file creation details

see
self::extractContentType()

For Content-Type header parsing

readInputSafely()

Safely reads HTTP request body with comprehensive DoS protection mechanisms.

private static readInputSafely() : string

This method implements multiple layers of protection against memory exhaustion attacks while maintaining compatibility with legitimate large requests. It's designed to prevent attackers from crashing your application by sending extremely large request bodies.

ATTACK VECTORS PREVENTED:

  1. Memory exhaustion: Attackers sending GB-sized requests to consume all available memory
  2. Resource starvation: Multiple concurrent large requests overwhelming the server
  3. Application crashes: Malformed or oversized content causing PHP memory limit errors

PROTECTION MECHANISMS:

  1. Content-Length validation: Checks declared size before reading any data
  2. Chunked reading: Reads data in small chunks (8KB default) to prevent memory spikes
  3. Progressive size checking: Monitors actual bytes read during streaming
  4. Automatic truncation: Safely limits content to maximum allowed size
  5. Stream failure handling: Gracefully handles I/O errors without crashing

SECURITY EVENT LOGGING:

  • Request size violations with actual vs allowed sizes
  • Stream access failures with error context
  • Progressive size monitoring for attack pattern detection
  • Successful truncation events for forensic analysis

MEMORY CHARACTERISTICS:

  • Peak memory usage: O(maxChunkSize) not O(requestSize)
  • CPU overhead: O(requestSize / chunkSize) linear streaming
  • I/O efficiency: Stream-based reading with optimal chunk sizes
  • Memory safety: Automatic garbage collection of processed chunks

TRUNCATION BEHAVIOR:

  • Truncates at maxInputSize boundary, preserving partial content
  • Logs truncation events for security monitoring
  • Continues processing with partial content rather than failing
  • Provides application-level indication of truncation occurrence

COMPATIBILITY NOTES:

  • Compatible with all HTTP methods and content types
  • Works with both declarative (Content-Length) and chunked transfer encoding
  • Handles edge cases like empty requests and malformed headers gracefully
  • No interference with PHP's built-in request handling for supported methods

PERFORMANCE OPTIMIZATIONS:

  • Early size validation prevents unnecessary I/O for oversized requests
  • Optimal chunk size balances memory usage and I/O efficiency
  • Progressive validation reduces latency for size violations
  • Stream-based approach minimizes memory allocation overhead
Tags
see
self::validateInputContent()

For structural content validation

Return values
string

Raw request body content (possibly truncated if oversized)

validateInputContent()

Validates input content structure to prevent various DoS attacks.

private static validateInputContent() : bool

This method performs lightweight structural validation of request content to identify and reject potentially malicious payloads before expensive parsing operations. It's designed to catch common attack patterns while maintaining very low false positive rates.

VALIDATION CHECKS PERFORMED:

  1. LINE LENGTH VALIDATION:
  • Purpose: Prevent buffer overflow attacks via extremely long lines
  • Limit: 64KB per line (accommodates legitimate large content)
  • Attack vector: Single lines with millions of characters
  • Performance: O(n) linear scan, very fast
  1. JSON BOMB PROTECTION:
  • Purpose: Prevent exponential memory/CPU consumption via nested JSON
  • Method: Depth limit validation using PHP's built-in parser controls
  • Limit: 32 levels of nesting (reasonable for legitimate use)
  • Attack vector: Deeply nested JSON structures that expand exponentially

DESIGN PHILOSOPHY:

  • Structural validation only: No semantic content analysis
  • Fast rejection: Identifies obvious attacks quickly
  • Low false positives: Conservative limits accommodate legitimate use cases
  • Defensive parsing operations
  • Comprehensive: Multiple validation layers for different attack vectors
  • Observable: All rejections logged with detailed context for investigation

FALSE POSITIVE PREVENTION:

  • Line length limit chosen to accommodate legitimate large content
  • JSON depth limit allows for complex but reasonable data structures
  • No content-based pattern matching (removed to prevent false positives)
  • Focus on structural rather than semantic content validation

PERFORMANCE IMPACT:

  • Line scanning: O(n) where n is content length, very fast
  • JSON validation: O(1) depth check using built-in parser limits
  • Memory usage: O(1) - no content duplication during validation
  • CPU usage: Minimal overhead, linear scan of content

ERROR HANDLING:

  • Invalid content: Logs event, returns false, calling code handles gracefully
  • Validation errors: Never throws exceptions, always returns boolean result
  • System errors: Treats as validation failure, logs and continues
  • Edge cases: Empty content always passes validation (safe default)

INTEGRATION WITH PARSING:

  • Called before expensive parsing operations (JSON, multipart)
  • Provides early rejection of obviously malicious content
  • Allows parsers to operate on pre-validated, safer content
  • Reduces attack surface by filtering content before complex processing

MONITORING CAPABILITIES:

  • Detailed logging of all validation failures with context
  • Performance metrics for validation operations
  • Content samples (truncated) for security analysis
  • IP tracking for attack pattern identification
Tags
see
self::validateJsonDepth()

For JSON-specific bomb protection

Return values
bool

True if content structure is safe for processing, false if potentially dangerous

validateJsonDepth()

Validates JSON depth to prevent JSON bomb attacks.

private static validateJsonDepth() : bool

Never throws - always returns safe assessment.

Return values
bool

True if JSON is safe, false if too deep


        
On this page

Search results