This document defines recommended defaults for pff2 applications.
For production:
$pffConfig['development_environment'] = false;
$pffConfig['show_all_errors'] = false;
$pffConfig['show_exception_details'] = false;Why:
- Prevents stack traces and sensitive internals from being shown to end users.
- Keeps logs server-side.
Recommended:
$pffConfig['security_cookie_httponly'] = true;
$pffConfig['security_cookie_samesite'] = 'Lax';
$pffConfig['security_cookie_secure'] = null; // auto-detect HTTPS/proxy headers
$pffConfig['security_session_strict_mode'] = true;Behavior:
- Session module enforces cookie-based sessions and strict mode.
- Cookies and session cookies use secure attributes based on config and HTTPS detection.
HTMLOut sends the following headers by default on every HTML response:
| Header | Default |
|---|---|
| X-Content-Type-Options | nosniff |
| X-Frame-Options | DENY |
| Referrer-Policy | strict-origin-when-cross-origin |
Override via config:
$pffConfig['security_headers'] = [
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'SAMEORIGIN',
'Referrer-Policy' => 'strict-origin-when-cross-origin',
'Content-Security-Policy' => "default-src 'self'",
];Set a header to null to suppress it. Override per-controller:
$this->_output->setHeader('X-Frame-Options', 'SAMEORIGIN');
$this->_output->removeHeader('Referrer-Policy');Enable the csrf module in your config:
$pffConfig['modules'] = ['session', 'csrf', ...];When autoValidate is true (default), the module automatically validates
CSRF tokens on POST/PUT/PATCH/DELETE requests. Tokens are single-use.
In forms:
<?= \pff\Core\ModuleManager::loadModule('csrf')->tokenField('my_form') ?>For AJAX, send the token via the X-CSRF-Token header.
Configure excluded routes and token lifetime in module.conf.yaml.
Recommended auth setting:
passwordType: password_hashGuidance:
- Use
password_hash()for new passwords. - Use
password_verify()for validation. md5andsha256modes now triggerE_USER_DEPRECATEDwarnings.- They use
hash_equals()internally to prevent timing attacks. - Both will be removed in pff2 5.0.
- Use
$this->e($value)to escape dynamic output in templates:html(default):htmlspecialcharswithENT_QUOTES | ENT_HTML5attr: same as htmljs:json_encodewith hex escapingurl:rawurlencode
- Access template data via
$this->get('key')—extract()has been removed. - Default framework error templates escape exception messages automatically.
Use the safe input accessors on App instead of accessing superglobals directly:
$this->_app->getQuery('search', '', FILTER_SANITIZE_SPECIAL_CHARS);
$this->_app->getPost('email', '', FILTER_VALIDATE_EMAIL);
$this->_app->getServer('REQUEST_METHOD');
$this->_app->getCookie('theme', 'light');- Use least privilege for writable directories.
- Framework scripts now target
775by default for generated writable directories. - Avoid
777in production.
Before production deploy:
- Verify HTTPS termination and proxy headers.
- Verify exception pages do not leak stack traces.
- Verify session cookie flags in browser dev tools.
- Verify auth login and rehash paths in staging.
- Verify security headers with
curl -I. - Verify CSRF tokens are present in all state-changing forms.