-
-
Notifications
You must be signed in to change notification settings - Fork 1
Security tests
Каталог: tests/Security/. 17 тестов в двух классах:
| Класс | Тестов | Фокус |
|---|---|---|
ContainerSecurityTest |
7 | id, сообщения, registry, alias, freeze |
ContainerSecurityResolveTest |
10 | кэш при сбоях, autowiring, теги |
Команда: composer test:security (входит в composer ci).
Контейнер — composition root: ошибки кэширования, autowiring и тексты исключений могут привести к «битым» singleton, неполной инициализации или утечке путей. Security-тесты фиксируют безопасное поведение при сбоях resolve — не полный penetration-тест приложения.
| # | Тест | Класс | Риск | Ожидание |
|---|---|---|---|---|
| 1 | testMissingServiceDoesNotRegisterResolvedState |
Security | фантомный has()
|
has / hasDefinition = false |
| 2 | testFactoryExceptionDoesNotCachePartialInstance |
Security | кэш после throw в фабрике | фабрика вызывается снова |
| 3 | testServiceIdentifierIsTreatedAsOpaqueString |
Security | SQL-подобный id | id — непрозрачная строка |
| 4 | testNotFoundMessageContainsOnlyRequestedIdentifier |
Security | утечка путей | только id в сообщении |
| 5 | testContainerRegistryExceptionDoesNotExposeInternalPaths |
Security | утечка в registry | фиксированный текст |
| 6 | testMissingAliasTargetDoesNotRegisterResolvedState |
Security | alias на missing | NotFound, target не в has()
|
| 7 | testAfterResolvingExceptionDoesNotCacheSingleton |
Resolve | hook throw + кэш | фабрика и hook ×2 |
| 8 | testDecoratorExceptionDoesNotCacheSingleton |
Resolve | decorator throw | фабрика ×2 |
| 9 | testAutowiringDisabledRejectsArbitraryClassName |
Resolve | autowire по FQCN без регистрации | NotFound |
| 10 | testAbstractClassCannotBeRegisteredViaAutowire |
Resolve | abstract через autowire | ContainerException |
| 11 | testInterfaceIsNotResolvedViaGlobalAutowiring |
Resolve | interface как сервис | NotFound |
| 12 | testCyclicDependencyMessageContainsOnlyServiceIdentifier |
Resolve | утечка в цикле | только FQCN в тексте |
| 13 | testAliasCycleRegistrationIsRejectedWithoutCorruptingPriorAlias |
Resolve | битый alias graph | рабочий alias сохраняется |
| 14 | testTaggedLocatorNotFoundMessageIsScopedToIdAndTag |
Resolve | утечка в tagged API | id + tag только |
| 15 | testNullByteInServiceIdentifierIsOpaque |
Resolve | null-byte в id | opaque string |
| 16 | testSetAfterFailedFactoryAllowsRecovery |
Resolve | recovery после сбоя |
set() заменяет definition |
-
NotFound не оставляет следов в
has()/hasDefinition(). -
Фабрика с throw — singleton не кэшируется, повторный
get()снова вызывает фабрику. -
SQL-подобный id —
set/getбез интерпретации строки. -
NotFound message — только
Сервис "<id>" не зарегистрирован., безvendor.
До set() вызов ContainerRegistry::get() бросает ContainerException с фиксированным текстом про ContainerRegistry::set() — без путей vendor / tests.
alias('missing.target', 'nowhere') → get('missing.target') бросает NotFound для конечного id nowhere; has('nowhere') остаётся false.
Шаги: фабрика + hook, бросающий RuntimeException; дважды get().
Проверка: фабрика и hook вызваны по 2 раза.
Поведение контейнера: при throw в hook singleton снимается из кэша (Container::resolveService), чтобы не отдавать частично инициализированный сервис.
Декоратор бросает исключение до записи в $resolved — фабрика вызывается при каждом get().
Без enableAutowiring() вызов get(stdClass::class) → NotFoundException, has() = false. Нельзя «достать» класс только по имени.
-
autowire(AbstractWorker::class)→ContainerException(не instantiable). - С глобальным autowiring
get(LoggerInterface::class)→NotFound(интерфейс не class).
get(CircularA::class) → ContainerException с FQCN CircularA, без подстрок vendor / tests.
alias('entry', 'target') + попытка alias('target', 'entry') → исключение; get('entry') по-прежнему работает.
Сообщение: Сервис "<id>" не найден в теге "<tag>". — без путей файловой системы.
id с \0 обрабатывается как обычная строка-ключ (opaque).
После failed get() повторный set('recoverable', $instance) и успешный get() — без лишних вызовов старой фабрики.
composer test:security
composer ciPHP 8.3–8.5 в .github/workflows/quality.yml.
- Whitelist id из пользовательского ввода.
- Не включайте глобальный autowiring для произвольных FQCN из запроса.
- Не полагайтесь на side effects в
afterResolvingбез обработки исключений в bootstrap.
CloudCastle DI · Репозиторий · Packagist · Releases · Discussions · Issues
Исходники Wiki — wiki/ в репозитории (синхронизация через Actions).
- Архитектура
- Быстрый старт
- Сравнение с PHP-DI, Symfony, Pimple — пошагово
- Примеры bootstrap
- Autowiring
- Конфигурация из файлов
- Сканирование классов
- Глобальный реестр
- Теги и декораторы
- call(), bind(), afterResolving
- Прототипы, alias и lazy
- Справочник API
- Фабрики и singleton
- Тестирование
- Тесты безопасности
- Нагрузка и производительность
- Анти-паттерны