hk2/sanitize-search

Magento 2 extension to sanitize harmful SQL keywords from search queries

Maintainers

Package info

github.com/basantmandal/magento2-search-sanitizer-module

Type:magento2-module

pkg:composer/hk2/sanitize-search

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-05-12 09:14 UTC

This package is auto-updated.

Last update: 2026-05-12 09:17:35 UTC


README

Version Magento PHP License Packagist
Website LinkedIn Email

HK2 Sanitize Search โ€” Magento 2 Search Query Sanitizer

HK2 SanitizeSearch is a lightweight Magento 2 module that sanitizes user-submitted search queries by stripping harmful SQL keywords and characters. It hooks into Magento\Search\Model\QueryFactory via a beforeCreate plugin, applies a regex filter, and logs sanitization events to a dedicated log file for auditing.

๐Ÿ“„ Overview

The module acts as a defense-in-depth layer against SQL injection attempts entering through the storefront search box. It removes SQL control keywords (SELECT, INSERT, UPDATE, DELETE, DROP, UNION), statement terminators (;), and comment markers (--, #) from user input before it reaches the search pipeline. Clean queries pass through with zero overhead.

๐Ÿง  Problem Statement

Magento's native search accepts arbitrary user input and feeds it into the search query pipeline. While Magento uses prepared statements and proper ORM practices, an unsanitized search box represents an unnecessary attack surface. Malicious actors can probe the system by submitting search strings containing SQL control characters and keywords (e.g., SELECT, UNION, ;, --).

Security best practices dictate that user input should be sanitized at every trust boundary. The search input field โ€” accessible to any visitor โ€” is a clear trust boundary that benefits from proactive sanitization.

๐Ÿ’ก Solution Approach

A plugin intercepts the beforeCreate method of Magento\Search\Model\QueryFactory and applies a preg_replace to remove dangerous patterns from the raw query string:

  • SQL keywords: SELECT, INSERT, UPDATE, DELETE, DROP, UNION (case-insensitive)
  • Statement terminator: ;
  • SQL comment markers: -- and #

If any content is stripped, the event is logged to var/log/sanitizer.log at WARNING level. The sanitizer can be toggled on/off via admin configuration at Stores > Configuration > HK2 > Search Sanitizer.

๐Ÿ†š Alternatives Considered

Approach Why not chosen
Prepared statement reliance only Places full trust in the ORM layer; no defense-in-depth at the input boundary
Full input validation/whitelisting Too restrictive; would break legitimate search queries with special characters
WAF-level filtering Requires external infrastructure; adds latency; harder to audit
Escaping instead of stripping Escaped SQL keywords may still appear suspicious in logs or trigger false alarms
Third-party security module Heavy dependency; most include far more than search sanitization

Stripping is chosen as a minimal, predictable operation โ€” it removes known dangerous patterns without altering the shape of legitimate queries.

๐Ÿ‘ฅ Who is this for?

  • Magento 2 store owners hardening their storefront against SQL injection probes
  • Security-conscious developers needing a zero-dependency, auditable sanitization layer
  • Agencies and system integrators deploying sites that must pass security compliance reviews
  • Merchants in regulated industries (finance, healthcare, e-commerce) with customer data behind the search interface

๐ŸŽฏ Use Cases

  1. E-commerce stores โ€” prevent SQL injection attempts through the product search box
  2. Multi-tenant Magento installations โ€” a vulnerability in one tenant's code could be probed via search
  3. Compliance-driven environments โ€” satisfying audit requirements for input sanitization at all user entry points
  4. Staging/demo sites โ€” quickly add a security layer without modifying core or installing a full security suite
  5. Custom search implementations โ€” where Magento\Search\Model\QueryFactory is still part of the pipeline

โœจ Key Features

  • SQL keyword stripping โ€” removes SELECT, INSERT, UPDATE, DELETE, DROP, UNION, ;, --, and # from search queries (case-insensitive)
  • Dedicated logging โ€” every sanitization event is recorded to var/log/sanitizer.log at WARNING level with original and sanitized values
  • Configurable enable/disable โ€” toggle via Stores > Configuration > HK2 > Search Sanitizer
  • Defense-in-depth โ€” complements Magento's ORM and prepared statements with input-level sanitization
  • Zero impact on clean queries โ€” queries without harmful patterns pass through unmodified
  • Lightweight โ€” single plugin, no database schemas, no API endpoints, no console commands

๐Ÿ—๏ธ Architecture Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Storefront search form                                                โ”‚
โ”‚  User submits:  "product; DROP TABLE customers; --"                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
                           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Magento\Search\Model\QueryFactory::beforeCreate                       โ”‚
โ”‚  (Plugin: HK2\SanitizeSearch\Plugin\SearchSanitizer)                   โ”‚
โ”‚                                                                         โ”‚
โ”‚  1. Check config flag (hk2_sanitizesearch/general/enabled)             โ”‚
โ”‚  2. If disabled โ†’ return original query unchanged                       โ”‚
โ”‚  3. If enabled:                                                         โ”‚
โ”‚     a. preg_replace(/(select|insert|update|delete|drop|union|;|--|#)/i) โ”‚
โ”‚     b. trim()                                                           โ”‚
โ”‚     c. If changed โ†’ log original + sanitized to Monolog (WARNING)      โ”‚
โ”‚     d. Return sanitized query                                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
                           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Normal Magento search pipeline                                        โ”‚
โ”‚  (Query, search results, etc.)                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Logging (when change detected):
    HK2\SanitizeSearch\Logger\Logger (custom Monolog channel)
        โ””โ”€โ”€ HK2\SanitizeSearch\Logger\Handler (writes to var/log/sanitizer.log, WARNING level)

Key files

File Role
Plugin/SearchSanitizer.php Plugin intercepting QueryFactory::beforeCreate
Logger/Logger.php Custom Monolog logger class
Logger/Handler.php Log handler writing to var/log/sanitizer.log
etc/di.xml Plugin registration and logger wiring
etc/module.xml Module declaration sequencing on HK2_Core
etc/adminhtml/system.xml Admin system configuration under HK2 tab
etc/adminhtml/menu.xml Admin menu entry under Content

๐Ÿ“‹ System Requirements

  • Magento: 2.4.x (Open Source / Adobe Commerce)
  • PHP: ^8.1 || ^8.2 || ^8.3 || ^8.4
  • Composer: 2.x
  • Dependencies: hk2/core ^1.0, magento/framework ^103.0.0
  • No database modifications โ€” operates entirely at the PHP plugin layer

๐Ÿš€ Installation

composer require hk2/sanitize-search
bin/magento module:enable HK2_SanitizeSearch
bin/magento setup:upgrade
bin/magento cache:clean

Verify:

bin/magento module:status HK2_SanitizeSearch

โš™๏ธ Configuration

Navigate to Stores > Configuration > HK2 > Search Sanitizer (or Content > Search Sanitizer from the admin menu).

Setting Description
Enable Search Sanitization Set to Yes to enable SQL keyword stripping. Set to No to pass all queries through unchanged.

Default: No (disabled). Ships disabled so operators can enable after testing.

Configuration path: hk2_sanitizesearch/general/enabled

๐Ÿ”’ Content Security Policy (CSP)

This module does not modify Magento's CSP headers or csp_whitelist.xml. It operates exclusively at the server-side PHP layer before the search query enters the ORM pipeline.

HK2 SanitizeSearch complements CSP in a holistic security strategy: CSP prevents malicious scripts from executing in the browser, while search sanitization prevents malicious SQL patterns from entering the database pipeline.

๐Ÿš€ Production Readiness

This module is production-ready and has been designed with the following considerations:

  • Zero database schema changes โ€” no setup patch, no SQL install/upgrade scripts, no data patches
  • Zero API surface โ€” no REST, GraphQL, or SOAP endpoints to secure
  • Minimal performance impact โ€” a single preg_replace on the search query string; disabled by default
  • Configurable at runtime โ€” toggle via admin configuration without code deployment
  • Defense-in-depth โ€” complements existing Magento security layers rather than replacing them
  • Auditable โ€” all sanitization events are logged with original and sanitized values for forensic review

Enable on staging first, test with your store's typical search patterns, then enable in production.

๐Ÿ” Privacy & GDPR

  • No personal data collection โ€” the module does not track, store, or transmit user identities, IP addresses, or session data
  • Log contents โ€” the only persisted data is the original and sanitized query string (written to var/log/sanitizer.log at WARNING level)
  • Log retention โ€” standard Magento log rotation applies; configure per your data protection obligations
  • No third-party services โ€” the module makes no external network calls and sends no data off-server
  • Recommended actions: review log retention for var/log/sanitizer.log, consider disabling query logging if searches may contain PII, include sanitization logging in your data processing register

๐Ÿงช Testing Strategy

Test case Input Expected output
Clean query laptop laptop (unchanged, no log)
SQL keyword SELECT * FROM users * FROM users (logged)
Statement terminator admin'; DELETE admin'' (logged)
Comment marker password-- comment password comment (logged)
Hash comment admin#foo adminfoo (logged)
Mixed case UnIoN Select 1 1 (logged)
Multiple keywords DROP;SELECT;UPDATE `` (empty, logged)
Disabled module any input with config disabled unchanged, no log
Empty input `` `` (no error)

Recommended approach: enable on a staging environment first, submit various test queries, and inspect var/log/sanitizer.log before enabling in production.

No automated test suite ships with the module.

๐Ÿ“š Documentation

Additional documentation is available in the docs/ directory:

โš ๏ธ Known Limitations

  1. Pattern-based, not context-aware โ€” the regex match removes substrings. "selective" becomes "ive". This is by design: the filter errs on the side of removing potential threats.
  2. Defense-in-depth, not primary SQL protection โ€” not a substitute for prepared statements, parameterized queries, or proper ORM usage.
  3. No Unicode / multibyte awareness โ€” non-ASCII homoglyph attacks are not detected.
  4. Log growth โ€” in high-traffic stores with aggressive probing, the log file may grow quickly.

๐Ÿค Contributing

Contributions are welcome. Please open an issue or pull request on the GitHub repository.

All contributions must adhere to the Conventional Commits specification for automated semantic release.

๐Ÿ“„ License

Licensed under the Open Software License 3.0 (OSL-3.0).

The OSL-3.0 is an OSI-approved open source license. It allows you to use, modify, and distribute this software, provided that distributed modifications are made available in source code form.

โš–๏ธ Disclaimer

This module provides defense-in-depth sanitization and is not a replacement for secure coding practices. The author and Basant Mandal are not responsible for any damages or security breaches resulting from the use or misuse of this software. Always follow Magento security best practices, keep your installation up to date, and perform regular security audits.