Sanitizing Inputs – Our Approach and Discussion
In our team, we recently discussed how we want to handle input sanitization for ConcreteCMS extensions. We identified three key layers of defence:
- GUI – Rendering views for the client
- API – Handling data via the REST API
- Database – Interacting with the database
GUI
On the frontend, all variables must be passed through the h()
function to ensure proper HTML escaping.
If we need to preserve line breaks, we use nl2br()
in combination with h()
.
In rare cases where we explicitly need to allow specific HTML tags, we rely on the HTMLPurifier library. However, this often leads to complications in software design, so we try to avoid it unless absolutely necessary.
API
When receiving arrays through the API, we map the data to a new, sanitized structure.
All input values are cast to their native data types. Strings, however, require special handling.
Whenever possible, we use the functions provided by the SanitizeService
class, with sanitizeString()
as a fallback if no more specific function fits the use case.
For WYSIWYG content submitted via the frontend, we use the core class LinkAbstractor
with its translateTo()
and translateFrom()
methods, which also provide sanitization.
Database
Sanitizing at the database level is straightforward: we always use Doctrine’s parameter binding via ?1
or :key
, which protects against SQL injection.
What do you think of this approach?
How do you handle input sanitization in your projects?