参考链接:https://github.com/azkaban/azkaban/pull/2044/commits/c7395bee157f7436cfa89936cb2281a1a22a46a4
修改:azkaban-web-server/src/main/java/azkaban/webapp/WebServerProvider.java
增加 disableHttpMethods 方法
/**
* Disable HTTP methods defined in jetty.disable.http-methods property
* <p>
* Multiple methods can be separated by coma eg. TRACE,OPTION
*
* @param server - jetty server instance
*/
private void disableHttpMethods(Server server) {
String toDisable = props.getString("jetty.disable.http-methods","");
if (!toDisable.trim().isEmpty()) {
Constraint c = new Constraint();
c.setAuthenticate(true);
ArrayList<ConstraintMapping> mappings = new ArrayList<>();
for(String methodToDisable : toDisable.split(",")) {
ConstraintMapping cmt = new ConstraintMapping();
cmt.setConstraint(c);
cmt.setMethod(methodToDisable);
cmt.setPathSpec("/*");
mappings.add(cmt);
}
SecurityHandler sh = new SecurityHandler();
sh.setConstraintMappings(mappings.toArray(new ConstraintMapping[]{}));
server.addHandler(sh);
}
}
在 get 方法中执行新增加的 disableHttpMethods 方法
@Override
public Server get() {
requireNonNull(this.props);
final int maxThreads = this.props
.getInt("jetty.maxThreads", Constants.DEFAULT_JETTY_MAX_THREAD_COUNT);
final boolean useSsl = this.props.getBoolean("jetty.use.ssl", true);
final int port;
final Server server = new Server();
if (useSsl) {
final int sslPortNumber = this.props
.getInt("jetty.ssl.port", Constants.DEFAULT_SSL_PORT_NUMBER);
port = sslPortNumber;
server.addConnector(getSslSocketConnector(sslPortNumber));
} else {
port = this.props.getInt("jetty.port", Constants.DEFAULT_PORT_NUMBER);
server.addConnector(getSocketConnector(port));
}
// setting stats configuration for connectors
setStatsOnConnectors(server);
disableHttpMethods(server);
logger.info(String.format(
"Starting %sserver on port: %d # Max threads: %d", useSsl ? "SSL " : "", port, maxThreads));
return server;
}
在 azkaban.properties 配置文件中添加 jetty.disable.http-methods=
#需要禁用的多个方法以逗号分隔
jetty.disable.http-methods=trace
测试 trace 漏洞是否修复
[hadoop@node1 ~]$ curl -v -X TRACE -I localhost:8081
* About to connect() to localhost port 8081 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8081 (#0)
> TRACE / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8081
> Accept: */*
>
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Cache-Control: must-revalidate,no-cache,no-store
Cache-Control: must-revalidate,no-cache,no-store
< Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=iso-8859-1
< Content-Length: 1268
Content-Length: 1268
< Server: Jetty(6.1.26)
Server: Jetty(6.1.26)
<
* Excess found in a non pipelined read: excess = 1268 url = / (zero-length body)
* Connection #0 to host localhost left intact
修改前
[hadoop@node1 azkaban-web]$ curl -v -X TRACE -I localhost:8081
* About to connect() to localhost port 8081 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8081 (#0)
> TRACE / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8081
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: message/http
Content-Type: message/http
< Content-Length: 78
Content-Length: 78
< Server: Jetty(6.1.26)
Server: Jetty(6.1.26)
<
* Excess found in a non pipelined read: excess = 78 url = / (zero-length body)
* Connection #0 to host localhost left intact