Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions api/src/org/labkey/api/security/AuthFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public class AuthFilter implements Filter
private static final Object FIRST_REQUEST_LOCK = new Object();

public static final String STRICT_TRANSPORT_SECURITY_HEADER_NAME = "Strict-Transport-Security";
public static final String X_FRAME_OPTIONS_HEADER_NAME = "X-Frame-Options";
public static final String X_CONTENT_TYPE_OPTIONS_HEADER_NAME = "X-Content-Type-Options";
public static final String REFERRER_POLICY_HEADER_NAME = "Referrer-Policy";
public static final String SERVER_HEADER_NAME = "Server";
Expand Down Expand Up @@ -87,8 +86,6 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha

if (ModuleLoader.getInstance().isStartupComplete())
{
if (!"ALLOW".equals(AppProps.getInstance().getXFrameOption()))
resp.setHeader(X_FRAME_OPTIONS_HEADER_NAME, AppProps.getInstance().getXFrameOption());
resp.setHeader(X_CONTENT_TYPE_OPTIONS_HEADER_NAME, "nosniff");
resp.setHeader(REFERRER_POLICY_HEADER_NAME, "origin-when-cross-origin" );

Expand Down
5 changes: 0 additions & 5 deletions api/src/org/labkey/api/settings/AppProps.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,6 @@ static WriteableAppProps getWriteableInstance()

// configurable http security settings

/**
* @return "SAMEORIGIN" or "DENY" or "ALLOW"
*/
String getXFrameOption();

String getStaticFilesPrefix();

boolean isWebfilesRootEnabled();
Expand Down
7 changes: 0 additions & 7 deletions api/src/org/labkey/api/settings/AppPropsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -554,13 +554,6 @@ public boolean isAllowSessionKeys()
return lookupBooleanValue(allowSessionKeys, false);
}

@Override
public String getXFrameOption()
{
return lookupStringValue(XFrameOption, "SAMEORIGIN");
}


private static final String not_init = "";
private String staticFilesPrefix = not_init;

Expand Down
8 changes: 0 additions & 8 deletions api/src/org/labkey/api/settings/SiteSettingsProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,6 @@ public void setValue(WriteableAppProps writeable, String value)
writeable.setAdminOnlyMessage(value);
}
},
XFrameOption("Controls whether or not a browser may render a server page in a <frame> , <iframe> or <object>. Valid values: [SAMEORIGIN, ALLOW]")
{
@Override
public void setValue(WriteableAppProps writeable, String value)
{
writeable.setXFrameOption(value);
}
},
navAccessOpen("Always include inaccessible parent folders in project menu when child folder is accessible")
{
@Override
Expand Down
5 changes: 0 additions & 5 deletions api/src/org/labkey/api/settings/WriteableAppProps.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,6 @@ public void setAllowSessionKeys(boolean b)
storeBooleanValue(allowSessionKeys, b);
}

public void setXFrameOption(String option)
{
storeStringValue(XFrameOption, option);
}

public void setExternalRedirectHosts(@NotNull Collection<String> externalRedirectHosts)
{
setAllowList(externalRedirectHostURLs, externalRedirectHosts);
Expand Down
2 changes: 0 additions & 2 deletions api/src/org/labkey/api/util/ExceptionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,6 @@ static ActionURL handleException(@NotNull HttpServletRequest request, @NotNull H
ContentSecurityPolicyFilter.ContentSecurityPolicyType.Enforce.getHeaderName(),
ContentSecurityPolicyFilter.ContentSecurityPolicyType.Report.getHeaderName(),
AuthFilter.STRICT_TRANSPORT_SECURITY_HEADER_NAME,
AuthFilter.X_FRAME_OPTIONS_HEADER_NAME,
AuthFilter.X_CONTENT_TYPE_OPTIONS_HEADER_NAME,
AuthFilter.REFERRER_POLICY_HEADER_NAME,
AuthFilter.SERVER_HEADER_NAME))
Expand Down Expand Up @@ -1106,7 +1105,6 @@ private static void renderErrorPage(Throwable ex, int responseStatus, String mes
else
{
pageConfig.setTemplate(originalConfig.getTemplate());
pageConfig.setFrameOption(originalConfig.getFrameOption());
}

HttpView<?> errorView = null;
Expand Down
16 changes: 0 additions & 16 deletions api/src/org/labkey/api/view/template/PageConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ public String getKey()
private TrueFalse _showHeader = TrueFalse.Default;
private List<NavTree> _navTrail;
private AppBar _appBar;
private FrameOption _frameOption = FrameOption.ALLOW;
private boolean _trackingScript = true;
private String _canonicalLink = null;
private boolean _includePostParameters = false;
Expand Down Expand Up @@ -505,21 +504,6 @@ public HtmlString getMetaTags(URLHelper url)
return sb.getHtmlString();
}

public enum FrameOption
{
ALLOW, SAMEORIGIN, DENY
}

public void setFrameOption(FrameOption option)
{
_frameOption = option;
}

public FrameOption getFrameOption()
{
return null==_frameOption?FrameOption.ALLOW:_frameOption;
}

public void setAllowTrackingScript(TrueFalse opt)
{
_trackingScript = opt != TrueFalse.False;
Expand Down
11 changes: 10 additions & 1 deletion api/src/org/labkey/filters/ContentSecurityPolicyFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ public class ContentSecurityPolicyFilter implements Filter
// This is effectively @NotNull since it's set to non-null values in init() and never changed
private String _stashedTemplate = null;

// We can't set this statically because the class is referenced before URLProviders are available
// We can't set this statically because this class is referenced before URLProviders are available
private final String _reportingEndpointsHeaderValue = "csp-report=\"" + PageFlowUtil.urlProvider(AdminUrls.class).getCspReportToURL().getLocalURIString() + "\"";

// Initialized on first request and reset when allowed sources change. Don't reference this directly; always use
// ensurePolicyExpression().
private volatile StringExpression _policyExpression;

// Initialized on first request and reset when allowed sources change
private volatile boolean _shouldSetXFrameOptionsHeader = false;

public enum ContentSecurityPolicyType
{
Report("Content-Security-Policy-Report-Only"), Enforce("Content-Security-Policy");
Expand Down Expand Up @@ -203,6 +206,8 @@ private void extractCspVersion(String s)
}
}

private static final String X_FRAME_OPTIONS_HEADER_NAME = "X-Frame-Options";

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
Expand All @@ -218,6 +223,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
}

resp.setHeader(getType().getHeaderName(), csp);
if (_shouldSetXFrameOptionsHeader)
resp.setHeader(X_FRAME_OPTIONS_HEADER_NAME,"SAMEORIGIN");
}
}
chain.doFilter(request, response);
Expand Down Expand Up @@ -274,6 +281,8 @@ private void clearPolicyExpression()
var substitutedPolicy = StringExpressionFactory.create(getStashedTemplate(), false, NullValueBehavior.KeepSubstitution)
.eval(SUBSTITUTION_MAP);
expression = _policyExpression = StringExpressionFactory.create(substitutedPolicy, false, NullValueBehavior.ReplaceNullAndMissingWithBlank);
// If frame-ancestors 'self' (no customization) is present in the CSP then we'll add X-Frame-Options: SAMEORIGIN for old browsers
_shouldSetXFrameOptionsHeader = getType() == ContentSecurityPolicyType.Enforce && substitutedPolicy.contains("frame-ancestors 'self' ;");
Comment thread
labkey-adam marked this conversation as resolved.
Outdated
}
}

Expand Down
2 changes: 0 additions & 2 deletions core/src/org/labkey/core/CoreModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -542,8 +542,6 @@ public QuerySchema createSchema(DefaultSchema schema, Module module)
"search to find the other select values.", false, true);
OptionalFeatureService.get().addFeatureFlag(new OptionalFeatureFlag(SQLFragment.FEATUREFLAG_DISABLE_STRICT_CHECKS, "Disable SQLFragment strict checks",
"Disables strict SQL generation safeguards in SQLFragment.appendIdentifier and QueryPivot value emission", false, true, FeatureType.Deprecated));
OptionalFeatureService.get().addExperimentalFeatureFlag(LoginController.FEATUREFLAG_DISABLE_LOGIN_XFRAME, "Disable Login X-FRAME-OPTIONS=DENY",
"By default LabKey disables all framing of login related actions. Disabling this feature will revert to using the standard site settings.", false, true);
OptionalFeatureService.get().addExperimentalFeatureFlag(PageTemplate.EXPERIMENTAL_SHORT_CIRCUIT_ROBOTS,
"Short-circuit robots",
"Save resources by not rendering pages marked as 'noindex' for robots. This is experimental as not all robots are search engines.",
Expand Down
18 changes: 0 additions & 18 deletions core/src/org/labkey/core/admin/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -1471,13 +1471,6 @@ public boolean handlePost(SiteSettingsForm form, BindException errors) throws Ex
}
}

String frameOption = StringUtils.trimToEmpty(form.getXFrameOption());
if (!frameOption.equals("DENY") && !frameOption.equals("SAMEORIGIN") && !frameOption.equals("ALLOW"))
{
errors.reject(ERROR_MSG, "XFrameOption must equal DENY, or SAMEORIGIN, or ALLOW");
return false;
}
props.setXFrameOption(frameOption);
props.setIncludeServerHttpHeader(form.isIncludeServerHttpHeader());

props.setTermsOfUseFrequencySeconds(form.getTermsOfUseFrequencySeconds());
Expand Down Expand Up @@ -2402,7 +2395,6 @@ public static class SiteSettingsForm
private boolean _allowSessionKeys;
private boolean _navAccessOpen;

private String _XFrameOption;
private boolean _includeServerHttpHeader;
private int _termsOfUseFrequencySeconds;

Expand Down Expand Up @@ -2616,16 +2608,6 @@ public void setAllowSessionKeys(boolean allowSessionKeys)
_allowSessionKeys = allowSessionKeys;
}

public String getXFrameOption()
{
return _XFrameOption;
}

public void setXFrameOption(String XFrameOption)
{
_XFrameOption = XFrameOption;
}

public boolean isIncludeServerHttpHeader()
{
return _includeServerHttpHeader;
Expand Down
9 changes: 0 additions & 9 deletions core/src/org/labkey/core/admin/customizeSite.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -463,15 +463,6 @@ Click the Save button at any time to accept the current settings and continue.</
<td colspan=2>HTTP security settings (<%=bean.getSiteSettingsHelpLink("http")%>)</td>
</tr>
<tr><td colspan=3 class=labkey-title-area-line></td></tr>
<tr>
<td class="labkey-form-label"><label for="<%=XFrameOption%>">X-Frame-Options</label></td>
<td><select name="<%=XFrameOption%>" id="<%=XFrameOption%>">
<% String option = appProps.getXFrameOption(); %>
<%-- BREAKS GWT <option value="DENY" <%=selectedEq("DENY",option)%>>DENY</option> --%>
<option value="SAMEORIGIN" <%=selectedEq("SAMEORIGIN",option)%>>SAMEORIGIN</option>
<option value="ALLOW" <%=selectedEq("ALLOW",option)%>>Allow</option></select></td>
</tr>
<tr><td colspan=3 class=labkey-title-area-line></td></tr>
<tr>
<td class="labkey-form-label"><label for="<%=includeServerHttpHeader%>">Include a <code>Server</code> HTTP header in responses</label></td>
<td><labkey:checkbox id="<%=includeServerHttpHeader.name()%>" name="<%=includeServerHttpHeader.name()%>" checked="<%=AppProps.getInstance().isIncludeServerHttpHeader()%>" value="true"/></td>
Expand Down
10 changes: 0 additions & 10 deletions core/src/org/labkey/core/login/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@

public class LoginController extends SpringActionController
{
public static final String FEATUREFLAG_DISABLE_LOGIN_XFRAME = "disable-login-xframe-options";
private static final Logger _log = LogHelper.getLogger(LoginController.class, "User registration and authentication failures");
private static final ActionResolver _actionResolver = new DefaultActionResolver(LoginController.class);

Expand All @@ -157,15 +156,6 @@ public LoginController()
setActionResolver(_actionResolver);
}

@Override
public PageConfig defaultPageConfig()
{
PageConfig ret = super.defaultPageConfig();
if (!AppProps.getInstance().isOptionalFeatureEnabled(FEATUREFLAG_DISABLE_LOGIN_XFRAME))
ret.setFrameOption(PageConfig.FrameOption.DENY);
return ret;
}

@Override
protected void beforeAction(Controller action)
{
Expand Down
9 changes: 0 additions & 9 deletions core/src/org/labkey/core/user/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,6 @@ public UserController()
setActionResolver(_actionResolver);
}

@Override
public PageConfig defaultPageConfig()
{
PageConfig ret = super.defaultPageConfig();
if (!AppProps.getInstance().isOptionalFeatureEnabled(LoginController.FEATUREFLAG_DISABLE_LOGIN_XFRAME))
ret.setFrameOption(PageConfig.FrameOption.DENY);
return ret;
}

public static class UserUrlsImpl implements UserUrls
{
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
ActionURL url = getActionURL();
ViewContext context = getViewContext();

if (model.getFrameOption() != PageConfig.FrameOption.ALLOW)
response.setHeader("X-FRAME-OPTIONS", model.getFrameOption().name());

boolean isExplicitNoIndex = null != url && "1".equals(url.getParameter(ActionURL.Param._noindex.name()));
if (isExplicitNoIndex)
model.setRobotsNone();
Expand Down