关于 typo3-security
面向 TYPO3 v14 项目的安全加固技能,提供配置、文件系统、用户访问及常见 Web 漏洞防护指导。适用于负责部署和维护 TYPO3 网站的开发者与管理员。
主要功能
- 01TYPO3 v14 安全配置指导
- 02主机名与文件访问限制
- 03安装工具和后台账号加固
- 04CSP、SQL 注入与 XSS 防护
- 05CSRF 防护实践
适用场景
- 01检查 TYPO3 上线前的安全设置
- 02限制安装工具的网络访问
- 03为后台账号配置 MFA
- 04审查扩展中的查询和模板
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dirnbauer/ webconsulting-skills --skill typo3-security安装后在 Claude Code 中输入/typo3-security确认已加载。
附带文件references/checklists.mdreferences/v14-notes.md
详细介绍
TYPO3 安全加固
兼容性: TYPO3 v14.x 本技能中的所有安全配置均适用于 TYPO3 v14。
TYPO3 API 优先: 创建自定义实现前,务必优先使用 TYPO3 内置 API、核心功能和成熟惯例。不要重复实现 TYPO3 已提供的功能。务必查阅 TYPO3 官方文档,确认所用 API 和方法在 TYPO3 v14 中存在且未弃用。
1. 关键配置设置
config/system/settings.php(TYPO3 v14)
<?php
return [
'BE' => [
// Disable debug in production
'debug' => false,
// Session security (example hardening values — tune for proxies/load balancers)
'lockIP' => 4, // Example: bind backend sessions to the full IPv4 address
'lockIPv6' => 8, // Lock to IPv6 prefix
'sessionTimeout' => 3600, // 1 hour session timeout
'lockSSL' => true, // Example: require HTTPS for backend requests
// Password policy (TYPO3 v14)
'passwordHashing' => [
'className' => \TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2idPasswordHash::class,
'options' => [],
],
],
'FE' => [
'debug' => false,
'lockIP' => 0, // Common for frontend sessions; mobile users / proxies often change IPs
'sessionTimeout' => 86400,
// `lockSSL` is BE-only (there is no `FE.lockSSL`) — enforce HTTPS for the frontend at the **web server / proxy** and send **HSTS** (`Strict-Transport-Security: max-age=31536000; includeSubDomains`) for production hosts
'passwordHashing' => [
'className' => \TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2idPasswordHash::class,
'options' => [],
],
],
'SYS' => [
// NEVER display errors in production
'displayErrors' => 0,
'devIPmask' => '', // No dev IPs in production
'errorHandlerErrors' => E_ALL & ~E_NOTICE & ~E_DEPRECATED,
'exceptionalErrors' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_DEPRECATED,
// Encryption key (generate unique per installation)
'encryptionKey' => 'generate-unique-key-per-installation',
// Trusted hosts pattern (CRITICAL) — Core wraps the pattern in `/^...$/`; omit `^` and `$`. Avoid `.*example\\.com` (without `\\.` before `example` — matches `evil-example.com`). Note: `.*\\.example\\.com` requires a subdomain and won't match bare `example.com`.
'trustedHostsPattern' => '(www\\.)?example\\.com',
// File handling security
'textfile_ext' => 'txt,html,htm,css,js,tmpl,ts,typoscript,xml,svg',
'mediafile_ext' => 'gif,jpg,jpeg,png,webp,svg,pdf,mp3,mp4,webm',
// Security feature toggles — names and availability differ by minor release; confirm in Core docs for your exact version
'features' => [
'security.backend.enforceReferrer' => true,
// Frontend CSP toggles (names stable from v12+; confirm in reference for your minor)
'security.frontend.enforceContentSecurityPolicy' => false,
'security.frontend.reportContentSecurityPolicy' => false,
],
],
'LOG' => [
'writerConfiguration' => [
\Psr\Log\LogLevel::WARNING => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => [
'logFile' => 'var/log/typo3-warning.log',
],
],
\Psr\Log\LogLevel::ERROR => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => [
'logFile' => 'var/log/typo3-error.log',
],
\TYPO3\CMS\Core\Log\Writer\SyslogWriter::class => [],
],
],
],
];
2. 可信主机模式
关键: 务必配置 trustedHostsPattern,以防止主机标头注入。
// ❌ DANGEROUS - Allows any host
'trustedHostsPattern' => '.*',
// ✅ SECURE - Explicit host list (Core adds `/^...$/` around the pattern)
'trustedHostsPattern' => '(?:example\\.com|www\\.example\\.com)',
// ✅ SECURE - Regex for subdomains (tie to your registrable domain)
'trustedHostsPattern' => '(.*\\.)?example\\.com',
// Development with DDEV
'trustedHostsPattern' => '(?:(?:.*\\.)?example\\.com|.*\\.ddev\\.site)',
3. 文件系统安全
fileDenyPattern(上传/公开文件访问)
保持 Core 的拒绝列表严格,仅在了解风险后才扩展:
警告: 设置
fileDenyPattern会完全替换 Core 的默认模式。务必以 v14 默认模式(\\.(php[3-8]?|phpsh|phtml|pht|phar|shtml|cgi)(\\..*)?$|\\.pl$|^\\.htaccess$)为基础进行追加,绝不要删除pht、phpsh、shtml或^\.htaccess$。
// Example: keep Core's v14 default and append extra executable extensions (adjust to your policy)
$GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] = '\\.(php[3-8]?|phpsh|phtml|pht|phar|shtml|cgi|sh|bash|py|asp|aspx|jsp)(\\..*)?$|\\.pl$|^\\.htaccess$';
目录权限
# Set correct ownership (adjust www-data to your web user)
chown -R www-data:www-data /var/www/html
# Directories: 2775 (group sticky)
find /var/www/html -type d -exec chmod 2775 {} \;
# Files: 664
find /var/www/html -type f -exec chmod 664 {} \;
# Configuration files: more restrictive
chmod 660 config/system/settings.php
chmod 660 config/system/additional.php
# var directory (writable)
chmod -R 2775 var/
# public/fileadmin (writable for uploads)
chmod -R 2775 public/fileadmin/
chmod -R 2775 public/typo3temp/
需要保护的关键文件
切勿在 public/ 中公开以下文件:
❌ var/log/
❌ config/
❌ .env
❌ composer.json
❌ composer.lock
❌ .git/
❌ vendor/ (should be outside public)
.htaccess 安全(Apache)
# public/.htaccess additions
# Block access to hidden files
<FilesMatch "^\.">
Require all denied
</FilesMatch>
# Block access to sensitive file types
<FilesMatch "\.(sql|sqlite|bak|backup|log|sh)$">
Require all denied
</FilesMatch>
# Block PHP execution in upload directories
<Directory "fileadmin">
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
</Directory>
# Security headers
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
Nginx 安全
# Block hidden files
location ~ /\. {
deny all;
}
# Block sensitive directories
location ~ ^/(config|var|vendor)/ {
deny all;
}
# Block PHP in upload directories
location ~ ^/fileadmin/.*\.php$ {
deny all;
}
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
4. 安装工具安全
禁用安装工具
# Remove enable file after installation
# Composer-based TYPO3 v14: file is in var/transient/
rm var/transient/ENABLE_INSTALL_TOOL
安装工具密码安全
生成强密码并妥善保存:
# Generate random password
openssl rand -base64 32
通过安装工具或特定环境的 config/system/additional.php 设置哈希后的密码;切勿提交占位符或空字符串。
安装工具 IP 限制
在 Web 服务器级别将安装工具入口(基于 Composer 的 v14 中为 /typo3/install.php)限制为可信 IP:
# Apache: in the vhost or .htaccess
<LocationMatch "^/typo3/install\.php">
Require ip 203.0.113.0/24
Require ip 198.51.100.42
</LocationMatch>
# Nginx
location = /typo3/install.php {
allow 203.0.113.0/24;
allow 198.51.100.42;
deny all;
# ...existing fastcgi_pass / include snippet...
}
注意:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']仅控制开发/调试工具(例如管理面板和调试输出)的访问范围,不会限制或验证安装工具的身份。除了设置强密码installToolPassword外,还应在 Web 服务器上(如上所述)锁定安装工具。
5. 后端用户安全
强密码策略(TYPO3 v14)
<?php
// ext_localconf.php of site extension
$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordPolicy'] = 'default'; // policy *name* only
$GLOBALS['TYPO3_CONF_VARS']['SYS']['passwordPolicies']['default'] = [
'validators' => [
\TYPO3\CMS\Core\PasswordPolicy\Validator\CorePasswordValidator::class => [
'options' => [
'minimumLength' => 12,
'upperCaseCharacterRequired' => true,
'lowerCaseCharacterRequired' => true,
'digitCharacterRequired' => true,
'specialCharacterRequired' => true,
],
],
\TYPO3\CMS\Core\PasswordPolicy\Validator\NotCurrentPasswordValidator::class => [],
],
];
多因素身份验证(TYPO3 v14)
TYPO3 v14 内置了 MFA。用户可在以下位置进行配置: 用户设置 > 账户安全
支持的提供方:
- TOTP(基于时间的一次性密码)
- 恢复代码
在 config/system/settings.php 中通过 $GLOBALS['TYPO3_CONF_VARS']['BE']['requireMfa'] 配置 MFA 强制策略:0 表示禁用,1 表示所有用户,2 表示非管理员,3 表示仅管理员,4 表示仅系统维护人员(请根据所用小版本在 Core 文档中确认具体含义);也可通过 用户 TSconfig auth.mfa.required 按用户/用户组配置:
# User or group TSconfig — require MFA for those accounts (overrides global when set)
auth.mfa.required = 1
参见多因素身份验证。
后端访问日志
// Log all backend logins
$GLOBALS['TYPO3_CONF_VARS']['LOG']['TYPO3']['CMS']['Backend']['Authentication']['writerConfiguration'] = [
\Psr\Log\LogLevel::INFO => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => [
'logFile' => 'var/log/backend-auth.log',
],
],
];
6. 内容安全策略(CSP)
内置 CSP(TYPO3 v14)
TYPO3 v14 内置了 CSP 支持。启用方法:
通过 config/system/settings.php/安装工具启用 CSP。前端开关(名称可能会变更,请根据所用小版本在 Core 中确认)通常包括:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.enforceContentSecurityPolicy'] 和 security.frontend.reportContentSecurityPolicy。自 v13 起,后端 CSP 默认强制启用——后端没有与前端类似的开关。
通过事件配置 CSP(TYPO3 v14)
<?php
declare(strict_types=1);
namespace Vendor\Extension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Directive;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Event\PolicyMutatedEvent;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue;
#[AsEventListener(identifier: 'vendor-extension/csp-modification')]
final class ContentSecurityPolicyListener
{
public function __invoke(PolicyMutatedEvent $event): void
{
if (!$event->scope->type->isFrontend()) {
return;
}
$policy = $event->getCurrentPolicy()
->extend(Directive::ScriptSrc, new UriValue('https://cdn.example.com'))
->extend(Directive::StyleSrc, new UriValue('https://fonts.googleapis.com'));
$event->setCurrentPolicy($policy);
}
}
TypoScript CSP 标头(替代方案)
config.additionalHeaders {
10.header = Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; frame-ancestors 'self';
}
7. 防止 SQL 注入
始终使用 QueryBuilder
<?php
declare(strict_types=1);
// ❌ VULNERABLE - Never do this
$result = $connection->executeQuery(
"SELECT * FROM pages WHERE uid = " . $_GET['id']
);
// ✅ SECURE - Use QueryBuilder with prepared statements
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
$result = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->createNamedParameter($id, \TYPO3\CMS\Core\Database\Connection::PARAM_INT)
)
)
->executeQuery();
Extbase Repository 安全性
<?php
declare(strict_types=1);
// Extbase automatically escapes parameters
$query = $this->createQuery();
$query->matching(
$query->equals('uid', $id) // Safe - auto-escaped
);
8. 防止 XSS
Fluid 模板
{variable}
{variable -> f:format.raw()}
{variable -> f:format.htmlspecialchars()}
<f:format.html>{bodytext}</f:format.html>
后端表单
TCA 会自动处理转义。对于自定义字段:
'config' => [
'type' => 'input',
'max' => 255,
// Input is automatically escaped
],
9. CSRF 保护
后端请求(TYPO3 v14)
TYPO3 后端会自动包含 CSRF 令牌。对于自定义 AJAX 请求:
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
final class MyController
{
public function __construct(
private readonly FormProtectionFactory $formProtectionFactory,
) {}
public function generateToken(): string
{
$formProtection = $this->formProtectionFactory->createFromRequest($this->request);
return $formProtection->generateToken('myFormIdentifier');
}
public function validateToken(string $token): bool
{
$formProtection = $this->formProtectionFactory->createFromRequest($this->request);
return $formProtection->validateToken($token, 'myFormIdentifier');
}
}
前端表单(Extbase)
<f:form action="submit" controller="Contact" method="post">
<f:form.hidden name="__trustedProperties" value="{trustedProperties}" />
</f:form>
附录
有关 TYPO3 v14 专属的安全加固说明和相关技能链接,请参阅 references/v14-notes.md。有关上线检查清单、速率限制以及其余 TYPO3 v14 安全说明,请参阅 references/checklists.md。