The core Laravel security toolkit in the ArtisanPack UI ecosystem. Focused on input sanitization, output escaping, KSES filtering, security headers, XSS protection, basic rate limiting, and Content Security Policy.
Security 2.0 — core-only. Authentication, 2FA, RBAC, file uploads, analytics, and compliance have moved to dedicated sibling packages. See UPGRADE.md for migrating from 1.x.
- Sanitization —
sanitizeEmail,sanitizeUrl,sanitizeText,sanitizeInt,sanitizeArray, … - Escaping —
escHtml,escAttr,escUrl,escJs,escCss(Laminas Escaper backed) - KSES filtering —
kses()WordPress-style allowed-tag filtering - Validation rules —
NoHtml,SecureUrl - Middleware —
csp,security.headers,xss.protection,api.security,api.rate_limit - Content Security Policy — nonce generator, policy builder, presets, violation reporting endpoint, CSP dashboard Livewire component (optional — requires
livewire/livewire), Artisan commands (csp:test,csp:stats,csp:prune,security:generate-csp) - Security audit commands —
security:audit,security:scan,security:baseline,security:benchmark,security:check-config,security:test-headers,security:scan-deps - Testing infrastructure — OWASP scanner, configuration scanner, penetration testing helpers, performance benchmarks, report generators
| Capability | Package |
|---|---|
| Authentication, 2FA, password complexity, breach checking, account lockout, advanced sessions | artisanpack-ui/security-auth |
| WebAuthn / FIDO2, SSO (SAML/OIDC), social auth, biometrics, device fingerprinting | artisanpack-ui/security-advanced-auth |
| Roles + permissions (Blade directives, Gate integration, Artisan commands) | artisanpack-ui/rbac |
| Secure uploads, malware scanning (ClamAV / VirusTotal), upload rate limiting | artisanpack-ui/secure-uploads |
| Security event logging, anomaly detection, threat intel, SIEM export, dashboards | artisanpack-ui/security-analytics |
| GDPR / CCPA / LGPD — consent, DSR, DPIA, data minimization, retention | artisanpack-ui/compliance |
composer require artisanpack-ui/securityPublish the config:
php artisan vendor:publish --tag=security-configuse ArtisanPackUI\Security\Facades\Security;
$cleanEmail = Security::sanitizeEmail($userEmail);
echo Security::escHtml($userContent);Or use the global helpers:
$cleanEmail = sanitizeEmail($userEmail);
echo escHtml($userContent);Route::middleware(['csp', 'security.headers', 'xss.protection'])->group(function () {
// ...
});
Route::middleware('api.rate_limit:api')->group(function () {
// ...
});<script @csp_nonce>
// ...
</script>The package fires a small set of artisanpack-ui/hooks filters and actions so host apps can extend sanitization, escaping, KSES, and CSP handling without subclassing. Register subscribers with addFilter() / addAction().
| Hook | Type | When it fires | Payload |
|---|---|---|---|
ap.security.sanitizedInput |
filter | Wraps the return of every Security::sanitize* method (email, url, filename, password, int, date, datetime, float, array, text). sanitizeArray fires text per element before firing array on the whole result. |
(mixed $value, string $type, mixed $original) — $type is the sanitizer name (email, url, filename, password, int, date, datetime, float, array, text) |
ap.security.escapedOutput |
filter | Wraps the return of every Security::esc* method |
(string $value, string $context, string $original) — $context is one of html, attr, url, js, css |
ap.security.ksesAllowedTags |
filter | At the start of Security::kses() only when the caller uses the default $config = 1; a non-empty return overrides htmLawed's element whitelist for that call. Explicit non-default $config bypasses this hook so caller intent isn't silently overridden. |
(array $allowedTags) — lowercase element names, e.g. ['a', 'p', 'strong'] |
ap.security.csp.directives |
filter | Inside CspPolicyService::getPolicy() before the header is serialized; the mutated array is what gets serialized |
(array<string, array<string>|bool> $directives, Illuminate\Http\Request $request) |
ap.security.csp.violationHandled |
action | At the end of CspViolationHandler::handle() when a violation was stored (csp.reporting.storeViolations = true) |
(ArtisanPackUI\Security\Models\CspViolationReport $report) |
Security note.
ap.security.sanitizedInputandap.security.escapedOutputsubscribers receive the already sanitized/escaped value and can return anything — including the untouched original — which effectively lets them weaken the guarantees this package provides. Only register callbacks you fully trust, and prefer narrowing (further sanitization) over broadening. The same applies toap.security.ksesAllowedTags: a subscriber that returns a permissive tag list expands the attack surface of everykses()call in the app.
Example:
// Force every escaped URL through your own allowlist before it's emitted.
addFilter( 'ap.security.escapedOutput', function ( string $value, string $context, string $original ): string {
if ( $context !== 'url' ) {
return $value;
}
return app( UrlAllowlist::class )->passes( $original ) ? $value : '#blocked';
} );
// Ship every stored CSP violation into your own alerting queue.
addAction( 'ap.security.csp.violationHandled', function ( CspViolationReport $report ): void {
SecurityAlerts::dispatch( $report );
} );- PHP 8.2+
- Laravel 10 / 11 / 12 / 13 (Laravel 13 requires PHP 8.3+)
MIT — see LICENSE.
