Data Validation & Sanitization
Data security is handled at two stages: input sanitization and output escaping.
To maintain a high-performance engine, Pragma CMS treats data integrity as a two-step process. We distinguish between Data Sanitization (cleaning input) and Data Escaping (protecting output).
1. Input Sanitization (The POST Rule)
Never store raw HTML directly from a user request. However, running complex filters every time a page is viewed is inefficient.
Pragma CMS Best Practice: Use sanitizeHTML() (powered by HTMLPurifier) only inside your POST controllers.
Why Sanitize on POST?
- Performance: HTMLPurifier is a heavy library. Running it on GET would significantly slow down your page load (TTFB). By running it on POST, the overhead only happens once when the content is saved.
- Data Integrity: Your database becomes a "Trusted Source." You can be confident that any HTML stored has already been stripped of
<script>tags and malicious attributes.
/**
* Example: Handling a Blog Post Submission
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Clean the rich text once before saving
$safeHtml = sanitizeHTML($_POST['blog_content'], 'default');
Database::updateTable(
"UPDATE blog_posts SET content = :content WHERE id = :id",
['content' => $safeHtml, 'id' => $postId]
);
}
2. Type & Format Validation
Before sanitizing or storing data, Pragma CMS ensures the data matches the expected format. This is the first line of defense for data integrity.
- Type Checking: Ensuring numeric values are actually integers or floats (e.g.,
is_numeric()). - Format Validation: Using filters for emails, URLs, or custom regex patterns for handles.
- Strict Enums: Ensuring a status field only contains allowed values (e.g.,
published,draft).
3. Output Escaping (The GET Rule)
When displaying data that does not contain HTML, you must prevent the browser from interpreting it as code.
Using Twig
Twig automatically escapes all output. If you intentionally want to output rich HTML that has already been sanitized, you must use the |raw filter:
{{ page.entry.content | raw }}
Using Native PHP: htmlspecialchars()
Use htmlspecialchars() for every variable echoed in your templates that is not explicitly rich content.
// Standard fields
<title><?= htmlspecialchars($page->metaTitle); ?></title>
<span class="author"><?= htmlspecialchars($page->entry['author_name']); ?></span>
4. Upload Integrity (MIME Types)
Data integrity also applies to files. When a user uploads a file through the MediaManager or a FormBuilder field, Pragma CMS does not rely on the file extension (which can be faked).
The CMS checks the actual MIME type of the file buffer (using finfo) to ensure that a .jpg is truly an image and not a disguised PHP script or malicious binary. Files that fail this "magic byte" inspection are immediately rejected.
5. SQL Integrity (Prepared Statements)
SQL Injection is impossible if you use the core Database methods. By using named placeholders (:value), you ensure that the SQL structure is never mixed with the data.
// ✅ The data is never interpreted as SQL code
$user = Database::fetch("SELECT * FROM users WHERE email = :email", [
'email' => $_POST['email']
]);