Web applications without security response headers are vulnerable to clickjacking, cross-site scripting (XSS), and content sniffing attacks. In Alibaba Cloud Service Mesh (ASM), you can deploy an EnvoyFilter at the ingress gateway to inject these headers into all responses automatically. This hardens your applications without modifying application code.
EnvoyFilter patches the Envoy proxy configuration directly. Incorrect configurations can destabilize the entire mesh. Always test in a non-production environment first, and review your EnvoyFilter definitions after each ASM or Istio version upgrade to replace deprecated fields.
Security headers reference
The following table lists the HTTP security response headers based on Open Web Application Security Project (OWASP) recommendations. The EnvoyFilter in this topic adds these headers to all responses that pass through the ingress gateway.
| Header | Default value | Purpose |
|---|---|---|
| Content-Security-Policy | frame-ancestors none; | Prevents clickjacking by blocking other sites from framing your pages |
| X-XSS-Protection | 1;mode=block | Activates the browser XSS filter and stops page rendering when an attack is detected |
| X-Content-Type-Options | nosniff | Prevents browsers from MIME-sniffing the content type |
| Referrer-Policy | no-referrer | Stops the browser from sending referrer information with requests |
| X-Download-Options | noopen | Prevents older versions of Internet Explorer from automatically running downloads |
| X-DNS-Prefetch-Control | off | Disables DNS prefetching for external links |
| Server | envoy | Automatically set by the Istio ingress gateway |
| X-Powered-By | N/A | Removed by the filter to hide application server details |
| Feature-Policy | camera 'none';microphone 'none';geolocation 'none';encrypted-media 'none';payment 'none';speaker 'none';usb 'none'; | Restricts browser features and APIs available to the page |
The Feature-Policy header is deprecated by the W3C in favor of Permissions-Policy. The EnvoyFilter in this topic uses Feature-Policy for backward compatibility with older browsers. To adopt Permissions-Policy, modify the Lua script accordingly.
Prerequisites
Before you begin, make sure that you have:
An ASM instance with an ACK cluster added. For more information, see Create an ASM instance and Add a cluster to an ASM instance
kubectl access to the ASM control plane. For more information, see Use kubectl on the control plane to access Istio resources
An application deployed in the ASM instance. For more information, see Deploy an application in an ASM instance
Istio resources such as VirtualService and DestinationRule configured for the application. For more information, see Use Istio resources to route traffic to different versions of a service
Check existing response headers
Before deploying the EnvoyFilter, check the headers your application currently returns. This example uses the Bookinfo sample application.
Run the following command. Replace <ingress-gateway-ip> with the IP address of your ingress gateway. To find this IP address, see Use Istio resources to route traffic to different versions of a service.
curl -I http://<ingress-gateway-ip>/productpageExpected output:
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 5183
server: istio-envoy
date: Tue, 28 Jan 2020 08:15:21 GMT
x-envoy-upstream-service-time: 28None of the security headers from the reference table appear in the response. The following sections show how to add them.
Deploy the EnvoyFilter
Choose one of the following methods based on your ASM instance version.
ASM 1.12.4.0 or later: use the ASM console
ASM 1.12.4.0 and later provide a built-in plug-in that creates the EnvoyFilter automatically.
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Plugin Extension Center > Market Place.
On the Market Place page, click Add HTTP response headers. On the Plugin Detail page, click Create Plug-in Instance.
In the Plugin Effective scope section, select Gateway Scope and click Add ASM Gateway to effective scope.
In the Add ASM Gateway to effective scope dialog box, select ingressgateway in the Select ASM Gateway section, click the add icon to move it to the selected section, and then click OK.
Noteingressgateway is the default ingress gateway. Select a different gateway if you want the security headers to apply to a different gateway.
In the Plugin Config section, clear all content from the YAML editor, turn on Plugin Switch, and wait for the plug-in to activate.
After the plug-in activates, the EnvoyFilter is created automatically.
Earlier than ASM 1.12.4.0: use kubectl
For ASM versions earlier than 1.12.4.0, deploy the EnvoyFilter by running the following kubectl command:
How the Lua script works: For each response at the ingress gateway, the script checks whether each security header exists. If a header is absent, the script adds it with the default value. For Content-Security-Policy, it checks that a frame-ancestors directive is not already present before appending one. The script removes X-Powered-By to prevent server information disclosure.
Adjust proxyVersion to match your Istio version. The proxyVersion field determines which Envoy proxies the filter applies to:
Istio 1.9 or later: Set
proxyVersionto your version, for example'^1\.17.*'. No other changes are required.Istio 1.8 or earlier: Set
proxyVersionto your version and make the following replacements:Original value Replacement envoy.filters.network.http_connection_managerenvoy.http_connection_managerenvoy.filters.http.routerenvoy.routertype.googleapis.com/envoy.extensions.filters.http.lua.v3.Luatype.googleapis.com/envoy.config.filter.http.lua.v2.Lua
Verify the security headers
After deploying the EnvoyFilter, confirm that the security headers appear in the response.
curl -I http://<ingress-gateway-ip>/productpageExpected output:
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 4183
server: istio-envoy
date: Tue, 28 Jan 2020 09:07:01 GMT
x-envoy-upstream-service-time: 17
content-security-policy: frame-ancestors none;
x-frame-options: deny
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
referrer-policy: no-referrer
x-download-options: noopen
x-dns-prefetch-control: off
feature-policy: camera 'none';microphone 'none';geolocation 'none';encrypted-media 'none';payment 'none';speaker 'none';usb 'none';All security headers from the reference table now appear in the response.
FAQ
Why can't I access my application when the URL contains special characters?
Envoy requires special characters in URLs to be percent-encoded per RFC 3986. If characters such as Á are Unicode-encoded rather than percent-encoded, Envoy cannot parse the URL. See Envoy cannot parse non-alphanumeric characters if not urlencoded for background.