mcpField
T
typo3-security

typo3-security

github.com/dirnbauer安全3377 次安装13 周前更新
代码仓库

关于 typo3-security

面向 TYPO3 v14 项目的安全加固技能,提供配置、文件系统、用户访问及常见 Web 漏洞防护指导。适用于负责部署和维护 TYPO3 网站的开发者与管理员。

主要功能

  1. 01TYPO3 v14 安全配置指导
  2. 02主机名与文件访问限制
  3. 03安装工具和后台账号加固
  4. 04CSP、SQL 注入与 XSS 防护
  5. 05CSRF 防护实践

适用场景

  1. 01检查 TYPO3 上线前的安全设置
  2. 02限制安装工具的网络访问
  3. 03为后台账号配置 MFA
  4. 04审查扩展中的查询和模板

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-security

安装后在 Claude Code 中输入/typo3-security确认已加载。

附带文件references/checklists.mdreferences/v14-notes.md

详细介绍

TYPO3 安全加固

来源:https://github.com/dirnbauer/webconsulting-skills

兼容性: 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。


致谢与归属

来源:https://github.com/dirnbauer/webconsulting-skills

评论

支持 Markdown