2727#define NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS 7
2828#define NGX_HTTP_RP_HEADER_UNSAFE_URL 8
2929
30-
31-
3230typedef struct {
3331 ngx_flag_t enable ;
3432 ngx_flag_t hide_server_tokens ;
@@ -43,6 +41,35 @@ typedef struct {
4341
4442} ngx_http_security_headers_loc_conf_t ;
4543
44+ static ngx_str_t empty_val = ngx_string ("" );
45+
46+ static ngx_str_t hide_headers [] = {
47+ ngx_string ("x-powered-by" ),
48+ ngx_string ("x-cf-powered-by" ),
49+ ngx_string ("via" ),
50+ ngx_string ("x-amz-cf-id" ),
51+ ngx_string ("x-amz-cf-pop" ),
52+ ngx_string ("x-page-speed" ),
53+ ngx_string ("x-varnish" ),
54+ ngx_string ("x-cache" ),
55+ ngx_string ("x-cache-hits" ),
56+ ngx_string ("x-cache-status" ),
57+ ngx_string ("x-application-version" ),
58+ ngx_string ("x-hudson" ),
59+ ngx_string ("x-hudson-theme" ),
60+ ngx_string ("x-instance-identity" ),
61+ ngx_string ("x-jenkins" ),
62+ ngx_string ("x-jenkins-session" ),
63+ ngx_string ("x-envoy-upstream-service-time" ),
64+ ngx_string ("x-drupal-cache" ),
65+ ngx_string ("x-generator" ),
66+ ngx_string ("x-backend-server" ),
67+ ngx_string ("x-wix-request-id" ),
68+ ngx_string ("x-request-id" ),
69+ ngx_string ("x-sucuri-id" ),
70+ ngx_string ("x-hacker" )
71+ };
72+
4673static ngx_conf_enum_t ngx_http_xss_protection [] = {
4774 { ngx_string ("off" ), NGX_HTTP_XSS_HEADER_OFF },
4875 { ngx_string ("on" ), NGX_HTTP_XSS_HEADER_ON },
@@ -224,25 +251,11 @@ ngx_http_security_headers_filter(ngx_http_request_t *r)
224251 }
225252 h_server -> hash = 0 ;
226253
227- /* Hide X-Powered-By header */
228- ngx_str_set (& key , "x-powered-by" );
229- ngx_str_set (& val , "" );
230- ngx_set_headers_out_by_search (r , & key , & val );
231-
232- /* Hide X-Page-Speed header */
233- ngx_str_set (& key , "x-page-speed" );
234- ngx_str_set (& val , "" );
235- ngx_set_headers_out_by_search (r , & key , & val );
236-
237- /* Hide X-Varnish */
238- ngx_str_set (& key , "x-varnish" );
239- ngx_str_set (& val , "" );
240- ngx_set_headers_out_by_search (r , & key , & val );
254+ size_t hide_headers_count = sizeof (hide_headers ) / sizeof (hide_headers [0 ]);
241255
242- /* Hide X-Application-Version */
243- ngx_str_set (& key , "x-application-version" );
244- ngx_str_set (& val , "" );
245- ngx_set_headers_out_by_search (r , & key , & val );
256+ for (size_t i = 0 ; i < hide_headers_count ; ++ i ) {
257+ ngx_set_headers_out_by_search (r , & hide_headers [i ], & empty_val );
258+ }
246259 }
247260
248261 if (1 != slcf -> enable ) {
@@ -262,15 +275,26 @@ ngx_http_security_headers_filter(ngx_http_request_t *r)
262275 && NGX_HTTP_SECURITY_HEADER_OMIT != slcf -> xss
263276 && ngx_http_test_content_type (r , & slcf -> text_types ) != NULL )
264277 {
265- ngx_str_set (& key , "X-XSS-Protection" );
266- if (NGX_HTTP_XSS_HEADER_ON == slcf -> xss ) {
267- ngx_str_set (& val , "1" );
268- } else if (NGX_HTTP_XSS_HEADER_BLOCK == slcf -> xss ) {
269- ngx_str_set (& val , "1; mode=block" );
270- } else if (NGX_HTTP_XSS_HEADER_OFF == slcf -> xss ) {
271- ngx_str_set (& val , "0" );
278+
279+ switch (slcf -> xss ) {
280+ case NGX_HTTP_XSS_HEADER_ON :
281+ ngx_str_set (& val , "1" );
282+ break ;
283+ case NGX_HTTP_XSS_HEADER_BLOCK :
284+ ngx_str_set (& val , "1; mode=block" );
285+ break ;
286+ case NGX_HTTP_XSS_HEADER_OFF :
287+ ngx_str_set (& val , "0" );
288+ break ;
289+ default :
290+ val .len = 0 ;
291+ val .data = NULL ;
292+ }
293+
294+ if (val .data ) {
295+ ngx_str_set (& key , "X-XSS-Protection" );
296+ ngx_set_headers_out_by_search (r , & key , & val );
272297 }
273- ngx_set_headers_out_by_search (r , & key , & val );
274298 }
275299
276300 scheme_value = ngx_http_get_variable (r , & scheme , scheme_hash_key );
@@ -290,38 +314,62 @@ ngx_http_security_headers_filter(ngx_http_request_t *r)
290314 && NGX_HTTP_SECURITY_HEADER_OMIT != slcf -> fo
291315 && ngx_http_test_content_type (r , & slcf -> text_types ) != NULL )
292316 {
293- ngx_str_set (& key , "X-Frame-Options" );
294- if (NGX_HTTP_FO_HEADER_SAME == slcf -> fo ) {
295- ngx_str_set (& val , "SAMEORIGIN" );
296- } else if (NGX_HTTP_FO_HEADER_DENY == slcf -> fo ) {
297- ngx_str_set (& val , "DENY" );
317+
318+ switch (slcf -> fo ) {
319+ case NGX_HTTP_FO_HEADER_SAME :
320+ ngx_str_set (& val , "SAMEORIGIN" );
321+ break ;
322+ case NGX_HTTP_FO_HEADER_DENY :
323+ ngx_str_set (& val , "DENY" );
324+ break ;
325+ default :
326+ val .len = 0 ;
327+ val .data = NULL ;
328+ }
329+
330+ if (val .data ) {
331+ ngx_str_set (& key , "X-Frame-Options" );
332+ ngx_set_headers_out_by_search (r , & key , & val );
298333 }
299- ngx_set_headers_out_by_search (r , & key , & val );
300334 }
301335
302336 /* Referrer-Policy: no-referrer-when-downgrade */
303337 if (r -> headers_out .status != NGX_HTTP_NOT_MODIFIED
304338 && NGX_HTTP_SECURITY_HEADER_OMIT != slcf -> rp ) {
305- ngx_str_set (& key , "Referrer-Policy" );
306339
307- if (NGX_HTTP_RP_HEADER_NO == slcf -> rp ) {
308- ngx_str_set (& val , "no-referrer" );
309- } else if (NGX_HTTP_RP_HEADER_DOWNGRADE == slcf -> rp ) {
310- ngx_str_set (& val , "no-referrer-when-downgrade" );
311- } else if (NGX_HTTP_RP_HEADER_SAME_ORIGIN == slcf -> rp ) {
312- ngx_str_set (& val , "same-origin" );
313- } else if (NGX_HTTP_RP_HEADER_ORIGIN == slcf -> rp ) {
314- ngx_str_set (& val , "origin" );
315- } else if (NGX_HTTP_RP_HEADER_STRICT_ORIGIN == slcf -> rp ) {
316- ngx_str_set (& val , "strict-origin" );
317- } else if (NGX_HTTP_RP_HEADER_ORIGIN_WHEN_CROSS == slcf -> rp ) {
318- ngx_str_set (& val , "origin-when-cross-origin" );
319- } else if (NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS == slcf -> rp ) {
320- ngx_str_set (& val , "strict-origin-when-cross-origin" );
321- } else if (NGX_HTTP_RP_HEADER_UNSAFE_URL == slcf -> rp ) {
322- ngx_str_set (& val , "unsafe-url" );
340+ switch (slcf -> rp ) {
341+ case NGX_HTTP_RP_HEADER_NO :
342+ ngx_str_set (& val , "no-referrer" );
343+ break ;
344+ case NGX_HTTP_RP_HEADER_DOWNGRADE :
345+ ngx_str_set (& val , "no-referrer-when-downgrade" );
346+ break ;
347+ case NGX_HTTP_RP_HEADER_SAME_ORIGIN :
348+ ngx_str_set (& val , "same-origin" );
349+ break ;
350+ case NGX_HTTP_RP_HEADER_ORIGIN :
351+ ngx_str_set (& val , "origin" );
352+ break ;
353+ case NGX_HTTP_RP_HEADER_STRICT_ORIGIN :
354+ ngx_str_set (& val , "strict-origin" );
355+ break ;
356+ case NGX_HTTP_RP_HEADER_ORIGIN_WHEN_CROSS :
357+ ngx_str_set (& val , "origin-when-cross-origin" );
358+ break ;
359+ case NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS :
360+ ngx_str_set (& val , "strict-origin-when-cross-origin" );
361+ break ;
362+ case NGX_HTTP_RP_HEADER_UNSAFE_URL :
363+ ngx_str_set (& val , "unsafe-url" );
364+ break ;
365+ default :
366+ val .len = 0 ;
367+ val .data = NULL ;
323368 }
324- ngx_set_headers_out_by_search (r , & key , & val );
369+ if (val .data ) {
370+ ngx_str_set (& key , "Referrer-Policy" );
371+ ngx_set_headers_out_by_search (r , & key , & val );
372+ }
325373 }
326374
327375
0 commit comments