为WSO2 APIM(4.1.0)的 /service和 /services端点添加HTTP安全头
我已将HTTP安全响应头添加到WSO2 API Manager网关配置的main与 fault序列中,因此这些头部现在出现在根端点(/)并在所有已部署的API响应中可用。
然而,我们公司的一次安全扫描发现 /service和 /services端点没有相同的安全响应头。
是否有办法将这些安全头添加到默认的 /service和 /services端点的响应中?或者我们可以完全禁用它们?
解决方案
WSO2 API Manager的 /service 与 /services 端点由底层Axis2引擎处理,而不是Synapse调解引擎——这也是为何向主序列/故障序列添加头部不会影响它们。
你有两种选择:
Option 1 — Disable the /services endpoint entirely (recommended)
如果你的API不使用SOAP/Axis2服务,最简单的解决方案是完全禁用这些端点,让它们在安全扫描中不再出现。
在
[transport.http]
disable_wsdl_endpoint = true
这可以阻止 /services 端点对公众公开访问。
Option 2 — Add security headers via Axis2 handlers
如果你需要保持端点处于激活状态,可以添加一个自定义Axis2处理程序,在来自 /service 与 /services 的响应中注入安全头部。
创建一个继承自 AbstractHandler 的自定义处理程序:
public class SecurityHeaderHandler extends AbstractHandler {
public InvocationResponse invoke(MessageContext msgContext)
throws AxisFault {
HttpServletResponse response = (HttpServletResponse)
msgContext.getProperty(
HTTPConstants.MC_HTTP_SERVLETRESPONSE);
if (response != null) {
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("Strict-Transport-Security",
"max-age=31536000; includeSubDomains");
response.setHeader("Content-Security-Policy",
"default-src 'none'");
}
return InvocationResponse.CONTINUE;
}
}
然后在 <APIM_HOME>/repository/conf/axis2/axis2.xml 的 <phaseOrder type="OutFlow"> 部分注册它。
Option 3 — Block at the load balancer/reverse proxy
如果你在WSO2 APIM前面有Nginx或 Apache反向代理,最简单的做法是在代理层完全阻止 /service 和 /services 路径,并在这里添加安全头部:
location ~* ^/(service|services) {
deny all;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
}
选项1 对于大多数生产环境来说是最干净的,前提是不需要SOAP端点。
备选方案
为什么会这样
头部缺失的原因是因为 /services(以及 /service)端点并不会经过Synapse调解引擎(你的 main 与 fault 序列就在那里)。相反,这些端点属于底层的WSO2 Carbon架构,用于暴露Axis2/SOAP Web服务(如默认管理员服务、Echo、和 Version)。
因为它们绕过Synapse,任何通过APIM调解序列添加的头部都不会应用于它们。
要解决这个问题,取决于你的安全需求,你有两种选项:
Option 1: Add Security Headers globally via Tomcat (Recommended if you need the endpoint)
由于WSO2运行在Apache Tomcat上,你可以在Web服务器层全局添加安全头部。这确保所有响应,包括来自 /services,都包含所需头部。
你可以通过在全局 web.xml 中配置Tomcat的内置 HttpHeaderSecurityFilter 来实现。
- 打开文件
<APIM_HOME>/repository/conf/tomcat/web.xml。 - 在闭合的
</web-app>标签前添加以下<filter>与<filter-mapping>配置。
XML
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>DENY</param-value>
</init-param>
<init-param>
<param-name>xssProtectionEnabled</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 重启WSO2 API Manager服务器。
注:你可以自定义 init-param 标签,以包含安全团队要求的准确头部。有关完整参数列表,请参考Tomcat HttpHeaderSecurityFilter文档。
Option 2: Block the endpoints entirely (Recommended for Production)
在生产环境中,外部消费者通常不应访问 /services 端点,因为它主要用于内部的WSO2 SOAP管理服务。
与其对端点进行安全控制,标准的WSO2最佳实践是完全阻止对它的外部访问。
Method A: At the Reverse Proxy / Load Balancer (Best Practice)
如果你在NGINX等反向代理后运行WSO2,简单地拒绝对 /services 与 /service 的请求即可。
NGINX示例:
Nginx
location ^~ /services/ {
deny all;
return 403;
}
location ^~ /service/ {
deny all;
return 403;
}
Method B: At the Tomcat Level (If no Reverse Proxy is used)
如果你直接暴露WSO2,可以通过Tomcat的 RemoteIpValve 或在 <APIM_HOME>/repository/conf/tomcat/web.xml 中添加自定义安全约束来阻止对这些路径的访问:
XML
<security-constraint>
<web-resource-collection>
<web-resource-name>Block Services</web-resource-name>
<url-pattern>/services/*</url-pattern>
<url-pattern>/service/*</url-pattern>
</web-resource-collection>
<auth-constraint /> </security-constraint>
重新启动服务器,对 /services 的任何请求将返回 403 Forbidden 状态,满足安全扫描器的要求。