| Version | Supported | PHP Version | Status |
|---|---|---|---|
| 6.0.x | ✅ | 8.0+ | Current |
| 5.0.x | ✅ | 7.4 - 8.2 | Maintenance |
| 4.0.x | ❌ | 7.1 - 7.4 | End of Life |
| 3.0.x | ❌ | 5.4 - 7.4 | End of Life |
v6 replaces unsafe unserialize() with JSON serialization:
// v5 (vulnerable to object injection)
$data = unserialize($sessionData);
// v6 (safe)
$data = json_decode($sessionData, true);Prevents XSS attacks through JSONP callbacks:
// Validates callback names against safe patterns
// Only allows: letters, numbers, dots, underscores, $
// Example: myCallback, jQuery.callback, callbacks[0]Uses EXTR_SKIP flag to prevent variable overwriting:
// Prevents malicious data from overwriting critical variables
extract($data, EXTR_SKIP);Automatic type validation and coercion:
/**
* @param int $id User ID {@min 1}{@max 999999}
* @param string $email {@type email}
*/
public function updateUser(int $id, string $email): array
{
// $id and $email are automatically validated
}DO NOT open public GitHub issues for security vulnerabilities.
- Email: Send details to arul@luracast.com
- Subject: "Security Vulnerability Report - Restler"
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Your suggested fix (if any)
- Initial Response: Within 48 hours
- Status Update: Within 7 days
- Fix Timeline: Depends on severity
- Critical: 1-7 days
- High: 7-30 days
- Medium: 30-90 days
- Low: Next release
- We will investigate and confirm the vulnerability
- We will develop and test a fix
- We will prepare a security advisory
- We will release a patched version
- We will credit you (if desired) in the security advisory
# .htaccess
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]$r = new Restler(true); // Disables debug infouse Luracast\Restler\Routes;
Routes::addAuthenticator(YourAuth::class);use Luracast\Restler\Routes;
Routes::setFilters(RateLimit::class);/**
* @param string $email {@type email}
* @param string $password {@min 8}{@max 100}
*/
public function register(string $email, string $password): array
{
// Input is pre-validated by Restler
}public function getHtml(): string
{
$userInput = $this->getUserInput();
return htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
}use Luracast\Restler\Defaults;
// Be specific with allowed origins
Defaults::$accessControlAllowOrigin = 'https://yourdomain.com';
// Don't use '*' with credentials
Defaults::$accessControlAllowCredentials = true;# .htaccess
<FilesMatch "^(composer\.(json|lock)|\.env|\.git|cache)">
Order allow,deny
Deny from all
</FilesMatch>composer update
composer audit// Don't hardcode credentials
$dbPassword = getenv('DB_PASSWORD');
// Use .env files (never commit them!)Vulnerable:
public function getUser(int $id): array
{
$sql = "SELECT * FROM users WHERE id = $id";
return $db->query($sql);
}Secure:
public function getUser(int $id): array
{
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}Vulnerable:
public function display(string $name): string
{
return "<h1>Hello $name</h1>";
}Secure:
public function display(string $name): string
{
$safeName = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
return "<h1>Hello $safeName</h1>";
}Protect forms with tokens:
/**
* @class Forms {@csrf}
*/
class MyAPI
{
public function postForm(array $data): array
{
// CSRF token automatically validated
}
}Always check authentication:
/**
* @access protected
*/
public function deleteUser(int $id): bool
{
// Only authenticated users can access
}Hide sensitive data:
public function getUser(int $id): array
{
$user = $this->db->getUser($id);
// Remove sensitive fields
unset($user['password']);
unset($user['salt']);
unset($user['reset_token']);
return $user;
}Before deploying to production:
- HTTPS enabled
- Production mode enabled
- Authentication implemented
- Rate limiting configured
- CORS properly configured
- Input validation on all endpoints
- Output sanitization for HTML
- SQL parameterization
- CSRF protection on forms
- Sensitive files protected
- Error messages don't leak info
- Dependencies updated
- Security headers configured
- File upload validation (if applicable)
- API key/token storage secure
Configure your web server to send security headers:
# .htaccess or httpd.conf
Header set X-Frame-Options "DENY"
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()";use Luracast\Restler\Defaults;
Defaults::$headerSecurity = [
'X-Frame-Options' => 'DENY',
'X-Content-Type-Options' => 'nosniff',
'X-XSS-Protection' => '1; mode=block',
];We encourage responsible security research. If you want to test:
- Set up locally - Don't test on production
- Use the examples - Test the included example APIs
- Report findings - Email arul@luracast.com
- Don't be malicious - No DoS, data destruction, etc.
When we receive a security report:
- We confirm the vulnerability
- We develop a fix
- We release a patched version
- We publish a security advisory
- We credit the reporter (unless they prefer anonymity)
Responsible Disclosure Timeline:
- Day 0: Report received
- Day 1-2: Initial response sent
- Day 3-7: Investigation and confirmation
- Day 7-30: Patch development and testing
- Day 30-90: Public disclosure (after patch release)
We thank the following security researchers:
- (Your name could be here - report responsibly!)
Last Updated: November 2024 Next Review: March 2025