artisanpack-ui/security
Core Laravel security toolkit for ArtisanPack UI: sanitization, escaping (Laminas Escaper), KSES filtering, validation rules, security/CSP middleware, CSP builder with nonce & reporting, rate limiting, audit/scan commands, and testing helpers.
This guide provides comprehensive security best practices for using the ArtisanPack UI Security package effectively to protect your Laravel applications against common web vulnerabilities.
Always validate and sanitize data received from users or external sources:
// Validate before sanitizing
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$cleanEmail = sanitizeEmail($email);
} else {
// Handle invalid email
throw new InvalidArgumentException('Invalid email format');
}
// Sanitize all user input
$userData = [
'name' => sanitizeText($_POST['name']),
'email' => sanitizeEmail($_POST['email']),
'age' => sanitizeInt($_POST['age']),
'bio' => sanitizeText($_POST['bio'])
];
Always escape data before rendering it in different contexts:
// HTML context
echo escHtml($userContent);
// HTML attribute context
echo '<img alt="' . escAttr($userTitle) . '">';
// URL context
echo '<a href="' . escUrl($userUrl) . '">Link</a>';
// JavaScript context
echo '<script>var data = ' . escJs($jsonData) . ';</script>';
// CSS context
echo '<style>.class { content: ' . escCss($userContent) . '; }</style>';
XSS attacks occur when malicious scripts are injected into web pages. Use appropriate escaping functions:
// Prevent XSS in HTML content
$safeContent = escHtml($userContent);
// Prevent XSS in HTML attributes
$safeAttribute = escAttr($userAttribute);
// For rich content that needs some HTML, use kses
$safeHtml = kses($userHtml);
Bad:
echo '<div>' . $userInput . '</div>'; // Vulnerable to XSS
Good:
echo '<div>' . escHtml($userInput) . '</div>'; // Safe from XSS
While this package doesn't directly handle database queries, proper input sanitization helps:
// Sanitize before database operations
$userId = sanitizeInt($_GET['id']);
$userName = sanitizeText($_POST['name']);
// Use with Laravel's query builder or Eloquent (which uses parameterized queries)
User::where('id', $userId)->where('name', $userName)->first();
Always include CSRF protection in forms when handling user input:
<form method="POST" action="/user/update">
[@csrf](https://github.com/csrf)
<input type="text" name="name" value="{{ escAttr($user->name) }}">
<textarea name="bio">{{ escHtml($user->bio) }}</textarea>
<button type="submit">Update</button>
</form>
// Sanitize before storing
$user = new User();
$user->name = sanitizeText($request->name);
$user->email = sanitizeEmail($request->email);
$user->age = sanitizeInt($request->age);
$user->save();
// Sanitize filenames before file operations
$filename = sanitizeFilename($uploadedFile->getClientOriginalName());
$path = storage_path('uploads/' . $filename);
// Additional file security checks
if (!in_array($uploadedFile->getClientMimeType(), ['image/jpeg', 'image/png'])) {
throw new InvalidArgumentException('Invalid file type');
}
// Sanitize data before JSON responses
$responseData = [
'user' => [
'name' => sanitizeText($user->name),
'email' => sanitizeEmail($user->email),
'bio' => sanitizeText($user->bio)
]
];
return response()->json($responseData);
Layer multiple security measures:
class UserController extends Controller
{
public function store(Request $request)
{
// 1. Validate input structure
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|max:255|unique:users',
'bio' => 'nullable|string|max:1000'
]);
// 2. Sanitize input
$userData = [
'name' => sanitizeText($request->name),
'email' => sanitizeEmail($request->email),
'bio' => sanitizeText($request->bio)
];
// 3. Create user with sanitized data
$user = User::create($userData);
// 4. Escape output
return view('user.profile', [
'name' => escHtml($user->name),
'email' => escHtml($user->email),
'bio' => escHtml($user->bio)
]);
}
}
Implement CSP headers alongside output escaping:
// In your middleware or controller
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'");
When using kses() for rich content:
// Allow only safe HTML tags
$allowedTags = [
'p' => [],
'br' => [],
'strong' => [],
'em' => [],
'ul' => [],
'ol' => [],
'li' => []
];
$safeContent = kses($userContent, $allowedTags);
// Never trust user input directly
echo $_POST['content']; // Vulnerable to XSS
// Don't escape already escaped content
echo escHtml(escHtml($content)); // Double escaping
// Don't use wrong escaping context
echo '<script>var data = "' . escHtml($data) . '";</script>'; // Should use escJs
// Don't sanitize display data
$displayName = sanitizeText($user->name); // Only sanitize on input
// Always escape output appropriately
echo escHtml($_POST['content']);
// Escape once, in the right context
echo escHtml($content);
// Use correct escaping for context
echo '<script>var data = ' . escJs($data) . ';</script>';
// Sanitize on input, escape on output
// Input: sanitizeText() -> Store in DB
// Output: escHtml() -> Display to user
escHtml() for HTML contentescAttr() for HTML attributesescUrl() for URLsescJs() for JavaScript contextsescCss() for CSS contextsAlways test your security implementations:
// Test XSS prevention
$maliciousInput = '<script>alert("XSS")</script>';
$safeOutput = escHtml($maliciousInput);
assert($safeOutput === '<script>alert("XSS")</script>');
// Test input sanitization
$dirtyEmail = '<script>bad@email.com';
$cleanEmail = sanitizeEmail($dirtyEmail);
assert($cleanEmail === 'bad@email.com');
If you discover a security vulnerability:
For AI-specific security guidelines, see AI Guidelines.
How can I help you explore Laravel packages today?