1010use Laminas \Http \Header \HeaderInterface ;
1111use Laminas \Loader \PluginClassLoader ;
1212use Magento \Csp \Api \Data \PolicyInterface ;
13- use Magento \Csp \Model \Policy \ Renderer \ SimplePolicyHeaderRenderer ;
13+ use Magento \Csp \Model \CspRenderer ;
1414use Magento \Framework \App \Response \HttpInterface as HttpResponse ;
1515use Psr \Log \LoggerInterface ;
1616
@@ -37,26 +37,28 @@ public function __construct(
3737 * @param null $result
3838 */
3939 public function afterRender (
40- SimplePolicyHeaderRenderer $ subject ,
40+ CspRenderer $ subject ,
4141 $ result ,
42- PolicyInterface $ policy ,
4342 HttpResponse $ response
4443 ): void {
4544 $ headerName = $ this ->getHeaderName ($ response );
46- /** @var HeaderInterface $header */
4745 $ header = $ response ->getHeader ($ headerName );
48- $ policyValue = $ header ->getFieldValue ();
46+ if (!$ header instanceof HeaderInterface) {
47+ return ;
48+ }
49+
50+ $ headerValue = $ header ->getFieldValue ();
4951 $ isHeaderSplittingEnabled = $ this ->config ->isHeaderSplittingEnabled ();
5052
5153 $ maxHeaderSize = $ this ->config ->getMaxHeaderSize ();
52- $ currentHeaderSize = strlen ($ policyValue );
54+ $ currentHeaderSize = strlen ($ headerValue );
5355
5456 if ($ isHeaderSplittingEnabled ) {
5557 $ this ->registerCspHeaderPlugins ($ response );
56- $ this ->splitUpCspHeaders ($ response , $ policyValue );
58+ $ this ->splitUpCspHeaders ($ response , $ headerName , $ headerValue );
5759 } else {
5860 if ($ maxHeaderSize >= $ currentHeaderSize ) {
59- $ response ->setHeader ($ headerName , $ policyValue , true );
61+ $ response ->setHeader ($ headerName , $ headerValue , true );
6062 } else {
6163 $ this ->logger ->error (
6264 sprintf (
@@ -87,33 +89,41 @@ private function registerCspHeaderPlugins(HttpResponse $response): void
8789 /**
8890 * Make sure that the CSP headers are handled as several headers ("multi-header")
8991 */
90- private function splitUpCspHeaders (HttpResponse $ response , string $ policyValue ): void
92+ private function splitUpCspHeaders (HttpResponse $ response , string $ headerName , string $ headerValue ): void
9193 {
92- $ headerName = $ this ->getHeaderName ( $ response );
94+ $ maxHeaderSize = $ this ->config -> getMaxHeaderSize ( );
9395
94- if (!$ headerName ) {
95- return ;
96- }
96+ $ headerParts [$ i = 0 ] = '' ;
9797
98- $ maxHeaderSize = $ this ->config ->getMaxHeaderSize ();
99- $ newHeaderSize = strlen ($ policyValue );
98+ $ policyValues = explode ('; ' , $ headerValue );
99+ foreach ($ policyValues as $ policyValue ) {
100+ $ policyValue = trim ($ policyValue ) . '; ' ;
101+ $ newHeaderSize = strlen ($ headerParts [$ i ]) + strlen ($ policyValue );
100102
101- if ($ newHeaderSize <= $ maxHeaderSize ) {
102- $ this ->contentHeaders [] = $ policyValue ;
103- } else {
104- $ this ->logger ->error (
105- sprintf (
106- 'Unable to set the CSP header. The header size of %d bytes exceeds the ' .
107- 'maximum size of %d bytes. ' ,
108- $ newHeaderSize ,
109- $ maxHeaderSize
110- )
111- );
103+ if ($ newHeaderSize <= $ maxHeaderSize ) {
104+ $ headerParts [$ i ] .= $ policyValue ;
105+
106+ continue ;
107+ }
108+
109+ $ headerParts [++$ i ] = $ policyValue ;
110+ $ headerSize = strlen ($ policyValue );
111+ if ($ headerSize > $ maxHeaderSize ) {
112+ $ this ->logger ->error (
113+ sprintf (
114+ 'Unable to set the CSP header. The header size of %d bytes exceeds the ' .
115+ 'maximum size of %d bytes. ' ,
116+ $ headerSize ,
117+ $ maxHeaderSize
118+ )
119+ );
120+
121+ return ;
122+ }
112123 }
113124
114- foreach ($ this ->contentHeaders as $ i => $ headerPart ) {
115- $ isFirstEntry = ($ i === 0 );
116- $ response ->setHeader ($ headerName , $ headerPart .'; ' , $ isFirstEntry );
125+ foreach ($ headerParts as $ i => $ headerPart ) {
126+ $ response ->setHeader ($ headerName , $ headerPart .'; ' , $ i === 0 );
117127 }
118128 }
119129
0 commit comments