Add S3/MinIO storage, nelmio security and CSP config
- Flysystem S3 adapter configured for MinIO - Vich uploader switched to Flysystem S3 storage - Liip imagine loader/resolver on S3 - S3 client service with path style endpoint for MinIO - Nelmio security: CSP, clickjacking, permissions policy, external redirects - CSP dev: allow Vite HMR (localhost:5173) - CSP prod: nonce scripts, restricted form-action and connect-src - composer: flysystem-bundle, flysystem-aws-s3-v3, nelmio/security-bundle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1581,6 +1581,207 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* db_driver?: scalar|Param|null, // Default: null
|
||||
* }>,
|
||||
* }
|
||||
* @psalm-type FlysystemConfig = array{
|
||||
* storages?: array<string, array{ // Default: []
|
||||
* adapter: scalar|Param|null,
|
||||
* options?: list<mixed>,
|
||||
* visibility?: scalar|Param|null, // Default: null
|
||||
* directory_visibility?: scalar|Param|null, // Default: null
|
||||
* retain_visibility?: bool|Param|null, // Default: null
|
||||
* case_sensitive?: bool|Param, // Default: true
|
||||
* disable_asserts?: bool|Param, // Default: false
|
||||
* public_url?: list<scalar|Param|null>,
|
||||
* path_normalizer?: scalar|Param|null, // Default: null
|
||||
* public_url_generator?: scalar|Param|null, // Default: null
|
||||
* temporary_url_generator?: scalar|Param|null, // Default: null
|
||||
* read_only?: bool|Param, // Default: false
|
||||
* }>,
|
||||
* }
|
||||
* @psalm-type NelmioSecurityConfig = array{
|
||||
* signed_cookie?: array{
|
||||
* names?: list<scalar|Param|null>,
|
||||
* secret?: scalar|Param|null, // Default: "%kernel.secret%"
|
||||
* hash_algo?: scalar|Param|null,
|
||||
* legacy_hash_algo?: scalar|Param|null, // Fallback algorithm to allow for frictionless hash algorithm upgrades. Use with caution and as a temporary measure as it allows for downgrade attacks. // Default: null
|
||||
* separator?: scalar|Param|null, // Default: "."
|
||||
* },
|
||||
* clickjacking?: array{
|
||||
* hosts?: list<scalar|Param|null>,
|
||||
* paths?: array<string, array{ // Default: {"^/.*":{"header":"DENY"}}
|
||||
* header?: scalar|Param|null, // Default: "DENY"
|
||||
* }>,
|
||||
* content_types?: list<scalar|Param|null>,
|
||||
* },
|
||||
* external_redirects?: array{
|
||||
* abort?: bool|Param, // Default: false
|
||||
* override?: scalar|Param|null, // Default: null
|
||||
* forward_as?: scalar|Param|null, // Default: null
|
||||
* log?: bool|Param, // Default: false
|
||||
* allow_list?: list<scalar|Param|null>,
|
||||
* },
|
||||
* flexible_ssl?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* cookie_name?: scalar|Param|null, // Default: "auth"
|
||||
* unsecured_logout?: bool|Param, // Default: false
|
||||
* },
|
||||
* forced_ssl?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* hsts_max_age?: scalar|Param|null, // Default: null
|
||||
* hsts_subdomains?: bool|Param, // Default: false
|
||||
* hsts_preload?: bool|Param, // Default: false
|
||||
* allow_list?: list<scalar|Param|null>,
|
||||
* hosts?: list<scalar|Param|null>,
|
||||
* redirect_status_code?: scalar|Param|null, // Default: 302
|
||||
* },
|
||||
* content_type?: array{
|
||||
* nosniff?: bool|Param, // Default: false
|
||||
* },
|
||||
* xss_protection?: array{ // Deprecated: The "xss_protection" option is deprecated, use Content Security Policy without allowing "unsafe-inline" scripts instead.
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* mode_block?: bool|Param, // Default: false
|
||||
* report_uri?: scalar|Param|null, // Default: null
|
||||
* },
|
||||
* csp?: bool|array{
|
||||
* enabled?: bool|Param, // Default: true
|
||||
* request_matcher?: scalar|Param|null, // Default: null
|
||||
* hosts?: list<scalar|Param|null>,
|
||||
* content_types?: list<scalar|Param|null>,
|
||||
* report_endpoint?: array{
|
||||
* log_channel?: scalar|Param|null, // Default: null
|
||||
* log_formatter?: scalar|Param|null, // Default: "nelmio_security.csp_report.log_formatter"
|
||||
* log_level?: "alert"|"critical"|"debug"|"emergency"|"error"|"info"|"notice"|"warning"|Param, // Default: "notice"
|
||||
* filters?: array{
|
||||
* domains?: bool|Param, // Default: true
|
||||
* schemes?: bool|Param, // Default: true
|
||||
* browser_bugs?: bool|Param, // Default: true
|
||||
* injected_scripts?: bool|Param, // Default: true
|
||||
* },
|
||||
* dismiss?: list<list<"default-src"|"base-uri"|"block-all-mixed-content"|"child-src"|"connect-src"|"font-src"|"form-action"|"frame-ancestors"|"frame-src"|"img-src"|"manifest-src"|"media-src"|"object-src"|"plugin-types"|"script-src"|"style-src"|"upgrade-insecure-requests"|"report-uri"|"worker-src"|"prefetch-src"|"report-to"|"*"|Param>>,
|
||||
* },
|
||||
* compat_headers?: bool|Param, // Default: true
|
||||
* report_logger_service?: scalar|Param|null, // Default: "logger"
|
||||
* hash?: array{
|
||||
* algorithm?: "sha256"|"sha384"|"sha512"|Param, // The algorithm to use for hashes // Default: "sha256"
|
||||
* },
|
||||
* report?: array{
|
||||
* level1_fallback?: bool|Param, // Provides CSP Level 1 fallback when using hash or nonce (CSP level 2) by adding 'unsafe-inline' source. See https://www.w3.org/TR/CSP2/#directive-script-src and https://www.w3.org/TR/CSP2/#directive-style-src // Default: true
|
||||
* browser_adaptive?: bool|array{ // Do not send directives that browser do not support
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* parser?: scalar|Param|null, // Default: "nelmio_security.ua_parser.ua_php"
|
||||
* },
|
||||
* default-src?: list<scalar|Param|null>,
|
||||
* base-uri?: list<scalar|Param|null>,
|
||||
* block-all-mixed-content?: bool|Param, // Default: false
|
||||
* child-src?: list<scalar|Param|null>,
|
||||
* connect-src?: list<scalar|Param|null>,
|
||||
* font-src?: list<scalar|Param|null>,
|
||||
* form-action?: list<scalar|Param|null>,
|
||||
* frame-ancestors?: list<scalar|Param|null>,
|
||||
* frame-src?: list<scalar|Param|null>,
|
||||
* img-src?: list<scalar|Param|null>,
|
||||
* manifest-src?: list<scalar|Param|null>,
|
||||
* media-src?: list<scalar|Param|null>,
|
||||
* object-src?: list<scalar|Param|null>,
|
||||
* plugin-types?: list<scalar|Param|null>,
|
||||
* script-src?: list<scalar|Param|null>,
|
||||
* style-src?: list<scalar|Param|null>,
|
||||
* upgrade-insecure-requests?: bool|Param, // Default: false
|
||||
* report-uri?: list<scalar|Param|null>,
|
||||
* worker-src?: list<scalar|Param|null>,
|
||||
* prefetch-src?: list<scalar|Param|null>,
|
||||
* report-to?: scalar|Param|null,
|
||||
* },
|
||||
* enforce?: array{
|
||||
* level1_fallback?: bool|Param, // Provides CSP Level 1 fallback when using hash or nonce (CSP level 2) by adding 'unsafe-inline' source. See https://www.w3.org/TR/CSP2/#directive-script-src and https://www.w3.org/TR/CSP2/#directive-style-src // Default: true
|
||||
* browser_adaptive?: bool|array{ // Do not send directives that browser do not support
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* parser?: scalar|Param|null, // Default: "nelmio_security.ua_parser.ua_php"
|
||||
* },
|
||||
* default-src?: list<scalar|Param|null>,
|
||||
* base-uri?: list<scalar|Param|null>,
|
||||
* block-all-mixed-content?: bool|Param, // Default: false
|
||||
* child-src?: list<scalar|Param|null>,
|
||||
* connect-src?: list<scalar|Param|null>,
|
||||
* font-src?: list<scalar|Param|null>,
|
||||
* form-action?: list<scalar|Param|null>,
|
||||
* frame-ancestors?: list<scalar|Param|null>,
|
||||
* frame-src?: list<scalar|Param|null>,
|
||||
* img-src?: list<scalar|Param|null>,
|
||||
* manifest-src?: list<scalar|Param|null>,
|
||||
* media-src?: list<scalar|Param|null>,
|
||||
* object-src?: list<scalar|Param|null>,
|
||||
* plugin-types?: list<scalar|Param|null>,
|
||||
* script-src?: list<scalar|Param|null>,
|
||||
* style-src?: list<scalar|Param|null>,
|
||||
* upgrade-insecure-requests?: bool|Param, // Default: false
|
||||
* report-uri?: list<scalar|Param|null>,
|
||||
* worker-src?: list<scalar|Param|null>,
|
||||
* prefetch-src?: list<scalar|Param|null>,
|
||||
* report-to?: scalar|Param|null,
|
||||
* },
|
||||
* },
|
||||
* referrer_policy?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* policies?: list<scalar|Param|null>,
|
||||
* },
|
||||
* permissions_policy?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* policies?: array{
|
||||
* accelerometer?: mixed, // Default: null
|
||||
* ambient_light_sensor?: mixed, // Default: null
|
||||
* attribution_reporting?: mixed, // Default: null
|
||||
* autoplay?: mixed, // Default: null
|
||||
* bluetooth?: mixed, // Default: null
|
||||
* browsing_topics?: mixed, // Default: null
|
||||
* camera?: mixed, // Default: null
|
||||
* captured_surface_control?: mixed, // Default: null
|
||||
* compute_pressure?: mixed, // Default: null
|
||||
* cross_origin_isolated?: mixed, // Default: null
|
||||
* deferred_fetch?: mixed, // Default: null
|
||||
* deferred_fetch_minimal?: mixed, // Default: null
|
||||
* display_capture?: mixed, // Default: null
|
||||
* encrypted_media?: mixed, // Default: null
|
||||
* fullscreen?: mixed, // Default: null
|
||||
* gamepad?: mixed, // Default: null
|
||||
* geolocation?: mixed, // Default: null
|
||||
* gyroscope?: mixed, // Default: null
|
||||
* hid?: mixed, // Default: null
|
||||
* identity_credentials_get?: mixed, // Default: null
|
||||
* idle_detection?: mixed, // Default: null
|
||||
* interest_cohort?: mixed, // Default: null
|
||||
* language_detector?: mixed, // Default: null
|
||||
* local_fonts?: mixed, // Default: null
|
||||
* magnetometer?: mixed, // Default: null
|
||||
* microphone?: mixed, // Default: null
|
||||
* midi?: mixed, // Default: null
|
||||
* otp_credentials?: mixed, // Default: null
|
||||
* payment?: mixed, // Default: null
|
||||
* picture_in_picture?: mixed, // Default: null
|
||||
* publickey_credentials_create?: mixed, // Default: null
|
||||
* publickey_credentials_get?: mixed, // Default: null
|
||||
* screen_wake_lock?: mixed, // Default: null
|
||||
* serial?: mixed, // Default: null
|
||||
* speaker_selection?: mixed, // Default: null
|
||||
* storage_access?: mixed, // Default: null
|
||||
* summarizer?: mixed, // Default: null
|
||||
* translator?: mixed, // Default: null
|
||||
* usb?: mixed, // Default: null
|
||||
* web_share?: mixed, // Default: null
|
||||
* window_management?: mixed, // Default: null
|
||||
* xr_spatial_tracking?: mixed, // Default: null
|
||||
* },
|
||||
* },
|
||||
* cross_origin_isolation?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* paths?: array<string, array{ // Default: []
|
||||
* coep?: "unsafe-none"|"require-corp"|"credentialless"|Param, // Cross-Origin-Embedder-Policy (COEP) header value
|
||||
* coop?: "unsafe-none"|"same-origin-allow-popups"|"same-origin"|"noopener-allow-popups"|Param, // Cross-Origin-Opener-Policy (COOP) header value
|
||||
* corp?: "same-site"|"same-origin"|"cross-origin"|Param, // Cross-Origin-Resource-Policy (CORP) header value
|
||||
* report_only?: bool|Param, // Use Report-Only headers instead of enforcing (applies to COEP and COOP only) // Default: false
|
||||
* report_to?: scalar|Param|null, // Reporting endpoint name for violations (requires Reporting API configuration, applies to COEP and COOP only) // Default: null
|
||||
* }>,
|
||||
* },
|
||||
* }
|
||||
* @psalm-type ConfigType = array{
|
||||
* imports?: ImportsConfig,
|
||||
* parameters?: ParametersConfig,
|
||||
@@ -1595,6 +1796,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* endroid_qr_code?: EndroidQrCodeConfig,
|
||||
* liip_imagine?: LiipImagineConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* flysystem?: FlysystemConfig,
|
||||
* nelmio_security?: NelmioSecurityConfig,
|
||||
* "when@dev"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
* parameters?: ParametersConfig,
|
||||
@@ -1612,6 +1815,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* endroid_qr_code?: EndroidQrCodeConfig,
|
||||
* liip_imagine?: LiipImagineConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* flysystem?: FlysystemConfig,
|
||||
* nelmio_security?: NelmioSecurityConfig,
|
||||
* },
|
||||
* "when@prod"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
@@ -1627,6 +1832,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* endroid_qr_code?: EndroidQrCodeConfig,
|
||||
* liip_imagine?: LiipImagineConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* flysystem?: FlysystemConfig,
|
||||
* nelmio_security?: NelmioSecurityConfig,
|
||||
* },
|
||||
* "when@test"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
@@ -1643,6 +1850,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* endroid_qr_code?: EndroidQrCodeConfig,
|
||||
* liip_imagine?: LiipImagineConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* flysystem?: FlysystemConfig,
|
||||
* nelmio_security?: NelmioSecurityConfig,
|
||||
* },
|
||||
* ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias
|
||||
* imports?: ImportsConfig,
|
||||
|
||||
Reference in New Issue
Block a user