1616#define NGX_HTTP_FO_HEADER_SAME 1
1717#define NGX_HTTP_FO_HEADER_DENY 2
1818
19+ /* The Referrer Policy header */
20+ #define NGX_HTTP_RP_HEADER_NO 1
21+ #define NGX_HTTP_RP_HEADER_DOWNGRADE 2
22+ #define NGX_HTTP_RP_HEADER_SAME_ORIGIN 3
23+ #define NGX_HTTP_RP_HEADER_ORIGIN 4
24+ #define NGX_HTTP_RP_HEADER_STRICT_ORIGIN 5
25+ #define NGX_HTTP_RP_HEADER_ORIGIN_WHEN_CROSS 6
26+ #define NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS 7
27+ #define NGX_HTTP_RP_HEADER_UNSAFE_URL 8
28+
29+
1930
2031typedef struct {
2132 ngx_flag_t enable ;
2233 ngx_flag_t hide_server_tokens ;
2334
2435 ngx_uint_t xss ;
2536 ngx_uint_t fo ;
37+ ngx_uint_t rp ;
2638
2739 ngx_hash_t nosniff_types ;
2840 ngx_array_t * types_keys ;
@@ -44,6 +56,34 @@ static ngx_conf_enum_t ngx_http_frame_options[] = {
4456 { ngx_null_string , 0 }
4557};
4658
59+ static ngx_conf_enum_t ngx_http_referrer_policy [] = {
60+ { ngx_string ("no-referrer" ),
61+ NGX_HTTP_RP_HEADER_NO },
62+
63+ { ngx_string ("no-referrer-when-downgrade" ),
64+ NGX_HTTP_RP_HEADER_DOWNGRADE },
65+
66+ { ngx_string ("same-origin" ),
67+ NGX_HTTP_RP_HEADER_SAME_ORIGIN },
68+
69+ { ngx_string ("origin" ),
70+ NGX_HTTP_RP_HEADER_ORIGIN },
71+
72+ { ngx_string ("strict-origin" ),
73+ NGX_HTTP_RP_HEADER_STRICT_ORIGIN },
74+
75+ { ngx_string ("origin-when-cross-origin" ),
76+ NGX_HTTP_RP_HEADER_ORIGIN_WHEN_CROSS },
77+
78+ { ngx_string ("unsafe-url" ),
79+ NGX_HTTP_RP_HEADER_UNSAFE_URL },
80+
81+ { ngx_string ("omit" ),
82+ NGX_HTTP_SECURITY_HEADER_OMIT },
83+
84+ { ngx_null_string , 0 }
85+ };
86+
4787static ngx_int_t ngx_http_security_headers_filter (ngx_http_request_t * r );
4888static void * ngx_http_security_headers_create_loc_conf (ngx_conf_t * cf );
4989static char * ngx_http_security_headers_merge_loc_conf (ngx_conf_t * cf ,
@@ -96,6 +136,13 @@ static ngx_command_t ngx_http_security_headers_commands[] = {
96136 offsetof(ngx_http_security_headers_loc_conf_t , fo ),
97137 ngx_http_frame_options },
98138
139+ { ngx_string ("security_headers_referrer_policy" ),
140+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
141+ ngx_conf_set_enum_slot ,
142+ NGX_HTTP_LOC_CONF_OFFSET ,
143+ offsetof(ngx_http_security_headers_loc_conf_t , rp ),
144+ ngx_http_referrer_policy },
145+
99146 ngx_null_command
100147};
101148
@@ -220,9 +267,27 @@ ngx_http_security_headers_filter(ngx_http_request_t *r)
220267 }
221268
222269 /* Referrer-Policy: no-referrer-when-downgrade */
223- if (r -> headers_out .status != NGX_HTTP_NOT_MODIFIED ) {
224- ngx_str_set (& key , "Referrer-Policy" );
225- ngx_str_set (& val , "no-referrer-when-downgrade" );
270+ if (r -> headers_out .status != NGX_HTTP_NOT_MODIFIED
271+ && NGX_HTTP_SECURITY_HEADER_OMIT != slcf -> rp ) {
272+ ngx_str_set (& key , "Referrer-Policy" );
273+
274+ if (NGX_HTTP_RP_HEADER_NO == slcf -> rp ) {
275+ ngx_str_set (& val , "no-referrer" );
276+ } else if (NGX_HTTP_RP_HEADER_DOWNGRADE == slcf -> rp ) {
277+ ngx_str_set (& val , "no-referrer-when-downgrade" );
278+ } else if (NGX_HTTP_RP_HEADER_SAME_ORIGIN == slcf -> rp ) {
279+ ngx_str_set (& val , "same-origin" );
280+ } else if (NGX_HTTP_RP_HEADER_ORIGIN == slcf -> rp ) {
281+ ngx_str_set (& val , "origin" );
282+ } else if (NGX_HTTP_RP_HEADER_STRICT_ORIGIN == slcf -> rp ) {
283+ ngx_str_set (& val , "strict-origin" );
284+ } else if (NGX_HTTP_RP_HEADER_ORIGIN_WHEN_CROSS == slcf -> rp ) {
285+ ngx_str_set (& val , "origin-when-cross-origin" );
286+ } else if (NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS == slcf -> rp ) {
287+ ngx_str_set (& val , "strict-origin-when-cross-origin" );
288+ } else if (NGX_HTTP_RP_HEADER_UNSAFE_URL == slcf -> rp ) {
289+ ngx_str_set (& val , "unsafe-url" );
290+ }
226291 ngx_set_headers_out_by_search (r , & key , & val );
227292 }
228293
@@ -245,6 +310,7 @@ ngx_http_security_headers_create_loc_conf(ngx_conf_t *cf)
245310
246311 conf -> xss = NGX_CONF_UNSET_UINT ;
247312 conf -> fo = NGX_CONF_UNSET_UINT ;
313+ conf -> rp = NGX_CONF_UNSET_UINT ;
248314 conf -> enable = NGX_CONF_UNSET ;
249315 conf -> hide_server_tokens = NGX_CONF_UNSET_UINT ;
250316
@@ -275,6 +341,8 @@ ngx_http_security_headers_merge_loc_conf(ngx_conf_t *cf, void *parent,
275341 NGX_HTTP_XSS_HEADER_BLOCK );
276342 ngx_conf_merge_uint_value (conf -> fo , prev -> fo ,
277343 NGX_HTTP_FO_HEADER_SAME );
344+ ngx_conf_merge_uint_value (conf -> rp , prev -> rp ,
345+ NGX_HTTP_RP_HEADER_STRICT_ORIG_WHEN_CROSS );
278346
279347 return NGX_CONF_OK ;
280348}
0 commit comments