ClickjackingHealthCheck.java
6.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* org.apache.felix.scr.annotations.Activate
* org.apache.felix.scr.annotations.Component
* org.apache.felix.scr.annotations.Properties
* org.apache.felix.scr.annotations.Property
* org.apache.felix.scr.annotations.PropertyUnbounded
* org.apache.felix.scr.annotations.Service
* org.apache.http.Header
* org.apache.http.HeaderIterator
* org.apache.http.client.methods.CloseableHttpResponse
* org.apache.http.client.methods.HttpGet
* org.apache.http.client.methods.HttpUriRequest
* org.apache.http.impl.client.CloseableHttpClient
* org.apache.http.impl.client.HttpClients
* org.apache.sling.commons.osgi.PropertiesUtil
* org.apache.sling.hc.api.HealthCheck
* org.apache.sling.hc.api.Result
* org.apache.sling.hc.api.ResultLog
* org.apache.sling.hc.util.FormattingResultLog
* org.osgi.service.component.ComponentContext
*/
package com.adobe.cq.security.hc.webserver.impl;
import java.io.IOException;
import java.util.Dictionary;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Service;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.hc.api.HealthCheck;
import org.apache.sling.hc.api.Result;
import org.apache.sling.hc.api.ResultLog;
import org.apache.sling.hc.util.FormattingResultLog;
import org.osgi.service.component.ComponentContext;
@Component(metatype=1, label="Web Server Configuration Health Check", description="This checks if the web server sets the X-FRAME-OPTIONS HTTP header to SAMEORIGIN or DENY.")
@Properties(value={@Property(name="hc.name", value={"Web Server Configuration"}, label="Name", description="Name of the health check."), @Property(name="hc.tags", unbounded=PropertyUnbounded.ARRAY, value={"webserver", "production", "security", "clickjacking"}, label="Tags", description="Tags for the health check."), @Property(name="hc.mbean.name", value={"webServerConfig"}, label="MBean Name", description="Name of the JMX mbean to register for this check.")})
@Service(value={HealthCheck.class})
public class ClickjackingHealthCheck
implements HealthCheck {
@Property(value={""}, label="Public Address", description="The public address for the site.")
private static final String WEBSERVER_URL = "webserver.address";
private String webserverUrl;
@Activate
protected void activate(ComponentContext ctx) {
this.webserverUrl = PropertiesUtil.toString(ctx.getProperties().get("webserver.address"), (String)"");
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public Result execute() {
FormattingResultLog resultLog;
resultLog = new FormattingResultLog();
boolean success = true;
boolean found = false;
if (this.webserverUrl.trim().equals("")) {
resultLog.warn("The URL of the website served by the server is not configured.", new Object[0]);
resultLog.debug("[You can configure the website URL via the Public Address property of this health check.]( )", new Object[0]);
return new Result((ResultLog)resultLog);
}
HttpGet httpget = new HttpGet(this.webserverUrl);
CloseableHttpClient client = null;
CloseableHttpResponse httpResponse = null;
try {
client = HttpClients.createDefault();
httpResponse = client.execute((HttpUriRequest)httpget);
resultLog.debug("[In order to prevent clickjacking, it is recommended to set the web server X-FRAME-OPTIONS HTTP response header to SAMEORIGIN or DENY.]( )", new Object[0]);
if (httpResponse != null) {
HeaderIterator headerIter = httpResponse.headerIterator();
while (headerIter.hasNext()) {
Header header = headerIter.nextHeader();
if (!"X-FRAME-OPTIONS".equals(header.getName().toUpperCase())) continue;
found = true;
String headerValue = header.getValue().toUpperCase();
if ("SAMEORIGIN".equals(headerValue)) {
resultLog.debug("The X-FRAME-OPTIONS HTTP response header is set to SAMEORIGIN.", new Object[0]);
continue;
}
if ("DENY".equals(headerValue)) {
resultLog.debug("The X-FRAME-OPTIONS HTTP response header is set to DENY.", new Object[0]);
continue;
}
resultLog.warn("The X-FRAME-OPTIONS HTTP response header is set to {}. It is recommended to set it to SAMEORIGIN or DENY.", new Object[]{headerValue});
success = false;
}
}
if (!success || !found) {
resultLog.debug("[Check the 'Clickjacking' section of the security guidelines.](https://www.adobe.com/go/aem6_2_docs_security_click_en)", new Object[0]);
}
}
catch (Exception e) {
resultLog.warn("Could not check the HTTP headers returned by the web server. Please check the website URL.", new Object[0]);
resultLog.debug("[You can configure the website URL via the Public Address property of this health check.]( )", new Object[0]);
}
finally {
if (httpResponse != null) {
try {
httpResponse.close();
}
catch (IOException e) {
resultLog.warn("Could not close the HTTP response due to an IOException.", new Object[0]);
}
}
if (client != null) {
try {
client.close();
}
catch (IOException e) {
resultLog.warn("Could not close the HTTP client due to an IOException", new Object[0]);
}
}
}
return new Result((ResultLog)resultLog);
}
}