Skip to main content

Auto Prepend File Protection

Pro Feature

Auto Prepend File protection is available with the Pro license. Get your Pro license to access this feature.

The Auto Prepend File protection is an additional security layer covering requests that reach a PHP file without going through PrestaShop. Every such access is recorded, and one carrying a known attack is refused with a 403, unless it comes from a trusted IP or goes to a URL never blocked.

Why is it important?​

By default, Sentinel only protects your site when requests go through the PrestaShop system (via index.php). However, an attacker could try to directly access a vulnerable PHP file:

https://yourstore.com/modules/vulnerablemodule/exploit.php

This request would not go through Sentinel as it doesn't pass through the PrestaShop dispatcher.

How it works​

Auto Prepend File protection configures PHP to automatically execute a Sentinel file before any other PHP file on your site.

Workflow Diagram​

Without Auto Prepend:

Attacker → exploit.php → Vulnerable code executed ❌

With Auto Prepend:

Attacker → auto_prepend_file.php → Logged, and refused when it carries a known attack ✓

What auto_prepend_file.php does​

The auto_prepend_file.php file:

  1. Records all requests to direct PHP files
  2. Logs POST/PUT/PATCH/DELETE requests with their payload
  3. Logs uploaded files (name, size, type)
  4. Adds an HTTP header X-Sentinel-Protected: 1 to confirm activation
  5. Refuses a request matching a threat signature, with a bare 403, unless it comes from a trusted IP or goes to a URL never blocked

Signature detection on direct accesses​

Threat detection normally runs from a PrestaShop hook, so it only ever sees requests that boot PrestaShop. A request straight to modules/some-module/vulnerable.php is dispatched by nothing, and was therefore inspected by nothing.

The Auto Prepend File stage closes that gap: the same signature set is applied, before PrestaShop starts, to any request that reaches a PHP file directly.

  • Only direct accesses are inspected. Requests going through index.php are already covered by the hook, and a normal page pays nothing for this stage.
  • The refusal is a bare 403, with no page and no mention of Sentinel. The caller here is a scanner or an exploit, not a customer to inform, and a branded page would confirm both that the file executes and what protects the shop.
  • It follows the threat detection switch. Turning off the Real-time threat detection switch of the Threat detection tab of Sentinel > Configuration stops this stage from blocking too: direct accesses are still logged, none is refused.
  • A trusted IP is not refused. A request from an address of the Trusted IPs card goes through even when it matches a signature: see What is never blocked.
  • A listed file is not refused. A request to a PHP file of the URLs never blocked list, reached by its plain path, goes through even when it matches a signature.
  • A Free shop blocks nothing. Its signature file is empty, so there is nothing to match against: see Signature Updates.
  • Anything unexpected lets the request through. A missing or unreadable signature file, or any error during detection, never turns a page into an error.

Blocked attempts appear in the Security Logs, in the file logs tab, marked Blocked with the signature that matched; a request let through for a trusted IP is marked Not blocked — trusted IP, and one let through for a listed file Not blocked — trusted URL, with the same signature.

Log Example​

[2025-12-17 10:30:45] [INFO] AUTO PREPEND FILE {
"ip": "192.168.1.100",
"uri": "/modules/vulnerable/upload.php",
"method": "POST",
"user_agent": "Mozilla/5.0...",
"timestamp": "2025-12-17 10:30:45",
"source": "auto_prepend",
"post_data": {
"action": "upload"
},
"files": {
"file": {
"name": "shell.php",
"size": 1234,
"type": "application/x-php"
}
}
}

Installation​

  1. Open the Threat detection tab of Sentinel > Configuration
  2. In the Direct PHP File Access Protection card, under the Direct Access Protection Not Active notice, click Try Automatic Installation

Only an employee who can configure the Sentinel module runs the installation; the others see the tab read-only. See Who can change the settings.

Sentinel goes through the following steps:

  1. It looks for an existing auto_prepend_file. The effective PHP value is checked first, which also covers a system php.ini, a PHP-FPM pool and a parent .htaccess. The files at the root of your shop are then scanned. If another prepend is already declared, Sentinel stops there and writes nothing: replacing it would disable whatever protection it belongs to.
  2. It picks the only method that can work on your server, based on how PHP runs:
    • PHP as an Apache module (mod_php) → .htaccess, because .user.ini is ignored in that setup
    • PHP-FPM, CGI, LiteSpeed and others → .user.ini
  3. It writes a marked block into that single file. Nothing else is touched.
  4. It verifies the result by requesting a throwaway script over HTTP and looking for the X-Sentinel-Protected header.
info

There is no fallback from one method to the other, and this is deliberate. A .user.ini is ignored by mod_php, and a php_value directive in an .htaccess is an unknown directive for a server without mod_php — which would answer every page of your shop with a 500 error.

Installing from the Command Line​

When Sentinel is installed or updated from the command line — bin/console prestashop:module install, a deployment pipeline, Composer — the PHP that runs the command is not the one that serves your shop. Its configuration says nothing about how the web server runs PHP, nor about an auto_prepend_file declared on the web side.

Sentinel therefore asks the web server that serves your shop, over HTTP, and decides on its answer, not on the command line's PHP:

  • PHP as an Apache module (mod_php) → the block goes into .htaccess, and the badge says On right away.
  • PHP-FPM and others → the block goes into .user.ini. The badge says Activation In Progress until PHP reads the file, then On, as with an installation from the back office.
  • Another auto_prepend_file is active on the web side → Automatic Installation Not Possible, and nothing is written, even when the command line's PHP does not see that prepend. See Conflict with an existing prepend.
  • The web server does not answer the command line → nothing is written: Sentinel never guesses the method. The badge stays on Off until the first back-office page load, which completes the installation with the same outcome as above.

There is nothing to run by hand in the last case: opening the back office once is enough.

Installation States​

The Direct PHP File Access Protection card of the Threat detection tab shows one of these badges, and below it a notice when the protection is not on:

BadgeNoticeMeaningWhat to do
On—The prepend runs, confirmed over HTTPNothing
Activation In ProgressActivation In ProgressThe configuration was written but PHP has not read it yetWait, then click Check Now
OffAutomatic Installation Not PossibleAnother auto_prepend_file is already configuredSee Conflict with an existing prepend
OffDirect Access Protection Not ActiveThe protection is not installed, the automatic installation did not succeed, or an installation from the command line is waiting for the back officeClick Try Automatic Installation, follow the Manual Installation Instructions under the notice, or open the back office to complete a command-line installation

When the automatic installation did not succeed, the Direct Access Protection Not Active notice adds Automatic installation did not succeed on this server. Use one of the manual methods below.

On the free plan, the card only shows the Pro invitation: see Threat detection.

Why "Activation In Progress"?​

PHP caches .user.ini files for the duration of user_ini.cache_ttl, five minutes by default. A file written a moment ago is therefore usually not live yet, and the verification cannot confirm it.

Sentinel keeps the configuration in place in that case rather than concluding it failed, and shows the remaining delay after Estimated time remaining:. Check Now reloads the tab, which re-runs the verification, and the badge switches to On on its own once PHP picks the file up.

With the .htaccess method there is no such delay: the verification is conclusive immediately, and a failed check causes Sentinel to remove what it just wrote.

Conflict with an Existing Prepend​

When another auto_prepend_file is already configured, the Automatic Installation Not Possible notice of the Threat detection tab shows its value after Current auto_prepend_file: and where it is declared after Declared in:. Sentinel does not touch it.

Two ways forward:

  • Ask your hosting provider to chain both prepend files.

  • Include Sentinel from the existing prepend, by adding this line to it:

    require_once '/absolute/path/to/prestashop/modules/sentinel/auto_prepend_file.php';

Once the other auto_prepend_file has been removed, reload the tab: the automatic installation is offered again.

Manual Installation​

The Manual Installation Instructions block, under the Direct Access Protection Not Active notice, lists the methods in the order that makes sense for your server, the most likely to work first. The path must always be absolute.

.user.ini File (PHP-FPM, CGI, LiteSpeed)​

Create a .user.ini file at the root of your PrestaShop installation:

; BEGIN Sentinel Security Module
auto_prepend_file = "/absolute/path/to/prestashop/modules/sentinel/auto_prepend_file.php"
; END Sentinel Security Module
caution

Ignored when PHP runs as an Apache module. Allow up to five minutes for PHP to read the file.

.htaccess File (Apache with mod_php)​

Add this block to the .htaccess file at the root of your PrestaShop installation, before the # ~~start~~ comment:

# BEGIN Sentinel Security Module
<IfModule mod_php.c>
php_value auto_prepend_file "/absolute/path/to/prestashop/modules/sentinel/auto_prepend_file.php"
</IfModule>
<IfModule mod_php7.c>
php_value auto_prepend_file "/absolute/path/to/prestashop/modules/sentinel/auto_prepend_file.php"
</IfModule>
# END Sentinel Security Module
caution

The two points above both matter.

Before # ~~start~~: PrestaShop rewrites everything between its # ~~start~~ and # ~~end~~ markers whenever it regenerates the .htaccess — when you rebuild friendly URLs, for instance. Only what sits outside those markers is kept.

Inside <IfModule>: an unguarded php_value is a fatal directive for a server without mod_php, which would answer every request with a 500 error.

php.ini File​

Add this line to your php.ini file:

; BEGIN Sentinel Security Module
auto_prepend_file = "/absolute/path/to/prestashop/modules/sentinel/auto_prepend_file.php"
; END Sentinel Security Module
warning

The path must be absolute, not relative. Example:

  • ✓ Correct: /var/www/html/prestashop/modules/sentinel/auto_prepend_file.php
  • ✗ Incorrect: modules/sentinel/auto_prepend_file.php

After configuring auto_prepend_file by hand, reload the Threat detection tab: Sentinel re-runs its verification each time the page is displayed and picks up the change.

Verification​

To verify that Auto Prepend File is active:

Method 1: Via Sentinel Interface​

Open the Threat detection tab of Sentinel > Configuration and check the badge of the Direct PHP File Access Protection card:

  • ✓ On: the protection is in place; it only blocks while threat detection is active (see Signature detection on direct accesses)
  • ✗ Activation In Progress or Off: the protection is not active; the notice below the badge says why

Method 2: Manual Test​

Create a test.php file at the root of PrestaShop:

<?php
echo 'Test';

Access https://yourstore.com/test.php and inspect HTTP headers:

curl -I https://yourstore.com/test.php

If you see X-Sentinel-Protected: 1, protection is active. ✓

Don't forget to delete test.php after testing.

Generated Logs​

Auto Prepend File generates logs in the same file as other Sentinel logs:

/var/logs/sentinel-YYYY-MM-DD.log

Log Types​

GET Requests to PHP Files​

[2025-12-17 10:30:45] [INFO] AUTO PREPEND FILE {
"ip": "192.168.1.100",
"uri": "/modules/module/file.php",
"method": "GET",
"source": "auto_prepend"
}

POST Requests with Payload​

[2025-12-17 10:30:45] [INFO] AUTO PREPEND FILE {
"ip": "192.168.1.100",
"uri": "/modules/module/upload.php",
"method": "POST",
"source": "auto_prepend",
"post_data": {
"param1": "value1"
},
"raw_body": "param1=value1&param2=value2"
}

File Uploads​

[2025-12-17 10:30:45] [INFO] AUTO PREPEND FILE {
"ip": "192.168.1.100",
"uri": "/modules/module/upload.php",
"method": "POST",
"source": "auto_prepend",
"files": {
"file": {
"name": "document.pdf",
"size": 52480,
"type": "application/pdf"
}
}
}

Use Cases​

Detecting Vulnerable Module Exploitation​

An attacker attempts to exploit a vulnerable module:

POST /modules/oldmodule/upload.php

Without Auto Prepend, this request would not be detected.

With Auto Prepend, you'll have a complete log:

  • Attacker's IP
  • Targeted file
  • Sent POST data
  • Uploaded files

Forensic Analysis After Incident​

In case of security incident, Auto Prepend logs allow:

  • Identifying all directly accessed PHP files
  • Viewing sent payloads
  • Tracing attack origin
  • Understanding the timeline

Compatibility​

Compatible with​

  • ✓ Apache with mod_php
  • ✓ Apache with PHP-FPM
  • ✓ Nginx with PHP-FPM
  • ✓ LiteSpeed
  • ✓ Shared hosting (if custom PHP configuration is allowed)

May Require Technical Support​

  • ⚠️ Shared hosting with restrictions
  • ⚠️ Servers with locked PHP configuration

Uninstallation​

Uninstalling Sentinel removes the marked block from every configuration file it may have written to, and deletes a file that becomes empty as a result. Content that belongs to someone else in a shared file is preserved.

The auto_prepend_file.php file itself ships with the module and stays in place; without a auto_prepend_file directive pointing at it, it is never executed.

If you want to disable the protection by hand:

  1. Remove the lines between BEGIN Sentinel Security Module and END Sentinel Security Module from your PHP configuration file
  2. Reload PHP configuration (restart Apache/Nginx/PHP-FPM)

Troubleshooting​

Stuck on "Activation In Progress"​

Expected for up to five minutes with the .user.ini method, the time it takes PHP to refresh its cache. Beyond that, the badge switches to Off on its own and the Direct Access Protection Not Active notice appears.

If it does not clear:

  1. Check that PHP does not run as an Apache module, in which case .user.ini is ignored — use the .htaccess method instead
  2. Check the value of user_ini.cache_ttl and user_ini.filename in your PHP configuration
  3. Check that the .user.ini file is readable by the web server

"Automatic Installation Not Possible"​

Another auto_prepend_file is already configured on the server. See Conflict with an existing prepend. Sentinel deliberately writes nothing in this situation.

Protection Won't Activate​

  1. Check auto_prepend_file.php file permissions
  2. Verify the path is absolute in the configuration
  3. Reload PHP configuration
  4. Check PHP error logs

500 Error After Activation​

If you get a 500 error after enabling Auto Prepend:

  1. Check PHP error logs: /var/log/apache2/error.log
  2. Verify the path to auto_prepend_file.php is correct
  3. Check /var/logs directory permissions

Logs Not Created​

If logs are not being created:

  1. Check /var/logs directory permissions
  2. Create the directory if necessary: mkdir -p /var/logs && chmod 755 /var/logs
  3. Verify PHP can write to this directory

Next: Security Logs