Security Notes

Security considerations for WPZylos CLI Core.

Input Validation

When building generators that accept user input, always validate:

Class Names

// Bad: Dangerous: arbitrary input
$className = $this->argument('name');

// Good: Safe: validate class name
$className = preg_replace('/[^a-zA-Z0-9_]/', '', $this->argument('name'));

if (empty($className)) {
    throw new \InvalidArgumentException('Invalid class name');
}

File Paths

// Bad: Path traversal vulnerability
$path = $basePath . '/' . $this->argument('file');
file_put_contents($path, $content);

// Good: Validate path is within allowed directory
$targetPath = $basePath . '/' . $this->argument('file');
$realPath = realpath(dirname($targetPath));
$realBase = realpath($basePath);

if ($realPath === false || !str_starts_with($realPath, $realBase)) {
    throw new \InvalidArgumentException('Invalid path');
}

Namespace Validation

// Good: Validate namespace format
$namespace = $this->argument('namespace');

if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_\\\\]*$/', $namespace)) {
    throw new \InvalidArgumentException('Invalid namespace');
}

Stub Security

Escape Dynamic Content

If stubs contain user-provided content that will be executed:

// In stub
$message = '{{message}}';

// Bad: Dangerous: unescaped
$compiler->compile('stub', ['message' => $userInput]);

// Good: Safe: escape for PHP string
$compiler->compile('stub', [
    'message' => addslashes($userInput),
]);

Avoid Code Injection

Never compile stubs with executable code from user input:

// Bad: Code injection risk
$compiler->compile('stub', [
    'method' => $userInput, // Could contain malicious code
]);

// Good: Validate against whitelist
$allowed = ['get', 'post', 'put', 'delete'];
if (!in_array($userInput, $allowed, true)) {
    throw new \InvalidArgumentException('Invalid method');
}

File System Security

Directory Permissions

// Use restrictive permissions
$writer = new FileWriter(overwrite: false, dirPermissions: 0755);

Temporary Files

// Good: Use system temp directory
$tempPath = sys_get_temp_dir() . '/cli-core-' . uniqid();

// Clean up after use
unlink($tempPath);

Security Checklist

Before deploying generators:

  • All class names are validated
  • All file paths are validated and constrained
  • All namespaces are validated
  • Dynamic content in stubs is properly escaped
  • No arbitrary code execution from user input
  • File permissions are appropriately restrictive
  • Temporary files are cleaned up