WordPress — одна из самых популярных CMS, но ее безопасность часто страдает из-за ненадлежащего хранения секретов. Пароли от БД, ключи API, токены аутентификации и другие чувствительные данные обычно хранятся в файле wp-config.php или в базе данных. Это создает риски: при утечке файлов или SQL-инъекции злоумышленник получает полный доступ к секретам. Кроме того, стандартные методы шифрования не защищают от атак, если ключ шифрования хранится рядом с данными.
Решение — использование изолированных криптографических контейнеров, которые зашифрованы с помощью аппаратного ключа. Такой подход гарантирует, что даже при компрометации сервера секреты останутся недоступными без физического устройства.
Аппаратные ключи (например, YubiKey, SafeNet eToken) — это устройства, которые хранят криптографические ключи и выполняют операции шифрования/дешифрования внутри защищенного чипа. Основные преимущества:
Для WordPress аппаратные ключи могут использоваться для шифрования контейнеров с секретами. Например, можно зашифровать файл с секретами симметричным ключом, который генерируется и хранится на аппаратном устройстве.
Изолированный контейнер — это файл или раздел, который смонтирован только при необходимости. В WordPress мы можем реализовать следующую архитектуру:
Важно, чтобы доступ к контейнеру был возможен только при наличии ключа. Для этого можно использовать библиотеки PKCS#11 для взаимодействия с аппаратным ключом.
Рассмотрим пример интеграции с использованием YubiKey и библиотеки php-pkcs11.
Подключите YubiKey к серверу и установите необходимые драйверы и библиотеки. Убедитесь, что ключ доступен через PKCS#11.
Сгенерируйте случайный ключ AES-256 и используйте его для шифрования файла с секретами. Затем зашифруйте этот ключ публичным ключом, хранящимся на YubiKey, и сохраните в отдельном файле.
class SecretManager {
private $encryptedKeyFile = '/path/to/encrypted_key.bin';
private $containerFile = '/path/to/secrets.enc';
public function getSecret($name) {
$key = $this->decryptMasterKey();
$data = openssl_decrypt(file_get_contents($this->containerFile), 'AES-256-CBC', $key, 0, $iv);
$secrets = json_decode($data, true);
return $secrets[$name] ?? null;
}
private function decryptMasterKey() {
$pkcs11 = new Pkcs11('/usr/lib/libykcs11.so');
$session = $pkcs11->openSession(Pkcs11::CKF_RW_SESSION);
$session->login('', 'pin');
$key = $session->decrypt(file_get_contents($this->encryptedKeyFile));
$session->logout();
return $key;
}
}В любом месте кода WordPress можно вызвать SecretManager::getSecret('api_key') для получения секрета. При этом секреты не хранятся в базе данных или в открытом виде.
| Метод | Безопасность | Производительность | Сложность внедрения |
|---|---|---|---|
| Хранение в wp-config.php | Низкая | Высокая | Низкая |
| Хранение в БД | Низкая | Средняя | Низкая |
| Программное шифрование | Средняя | Средняя | Средняя |
| Аппаратный ключ + контейнер | Высокая | Средняя | Высокая |
Использование изолированных криптографических контейнеров на основе аппаратных ключей значительно повышает безопасность WordPress. Это защищает секреты даже при полной компрометации сервера. Несмотря на сложность внедрения, такое решение оправдано для проектов с высокими требованиями к безопасности. Рекомендуется комбинировать аппаратные ключи с другими методами защиты, такими как двухфакторная аутентификация и регулярные аудиты.







