diff options
author | James Moger <james.moger@gitblit.com> | 2014-09-06 11:25:42 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-09-07 11:42:40 -0400 |
commit | fc3a39d464b1303f0b7d01d0160f81cbbb80a98b (patch) | |
tree | 9a45d2f99aa1393198e8610221eb51e982e0d5af /src/main/java/com | |
parent | 90eb5a08ddd6a3a246e8b73da9524c304838928a (diff) | |
download | gitblit-fc3a39d464b1303f0b7d01d0160f81cbbb80a98b.tar.gz gitblit-fc3a39d464b1303f0b7d01d0160f81cbbb80a98b.zip |
Create infrastructure for XSS sanitization
Diffstat (limited to 'src/main/java/com')
-rw-r--r-- | src/main/java/com/gitblit/DaggerModule.java | 11 | ||||
-rw-r--r-- | src/main/java/com/gitblit/FederationClient.java | 5 | ||||
-rw-r--r-- | src/main/java/com/gitblit/MigrateTickets.java | 5 | ||||
-rw-r--r-- | src/main/java/com/gitblit/ReindexTickets.java | 5 | ||||
-rw-r--r-- | src/main/java/com/gitblit/manager/GitblitManager.java | 6 | ||||
-rw-r--r-- | src/main/java/com/gitblit/manager/IRuntimeManager.java | 8 | ||||
-rw-r--r-- | src/main/java/com/gitblit/manager/RuntimeManager.java | 21 | ||||
-rw-r--r-- | src/main/java/com/gitblit/utils/JSoupXssFilter.java | 87 | ||||
-rw-r--r-- | src/main/java/com/gitblit/utils/XssFilter.java | 64 | ||||
-rw-r--r-- | src/main/java/com/gitblit/wicket/GitBlitWebApp.java | 12 | ||||
-rw-r--r-- | src/main/java/com/gitblit/wicket/GitblitWicketApp.java | 3 |
11 files changed, 219 insertions, 8 deletions
diff --git a/src/main/java/com/gitblit/DaggerModule.java b/src/main/java/com/gitblit/DaggerModule.java index 6ad3fe63..dd7e1b2b 100644 --- a/src/main/java/com/gitblit/DaggerModule.java +++ b/src/main/java/com/gitblit/DaggerModule.java @@ -38,7 +38,9 @@ import com.gitblit.transport.ssh.FileKeyManager; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.MemoryKeyManager; import com.gitblit.transport.ssh.NullKeyManager; +import com.gitblit.utils.JSoupXssFilter; import com.gitblit.utils.StringUtils; +import com.gitblit.utils.XssFilter; import com.gitblit.wicket.GitBlitWebApp; import dagger.Module; @@ -54,6 +56,7 @@ import dagger.Provides; library = true, injects = { IStoredSettings.class, + XssFilter.class, // core managers IRuntimeManager.class, @@ -79,8 +82,12 @@ public class DaggerModule { return new FileSettings(); } - @Provides @Singleton IRuntimeManager provideRuntimeManager(IStoredSettings settings) { - return new RuntimeManager(settings); + @Provides @Singleton XssFilter provideXssFilter() { + return new JSoupXssFilter(); + } + + @Provides @Singleton IRuntimeManager provideRuntimeManager(IStoredSettings settings, XssFilter xssFilter) { + return new RuntimeManager(settings, xssFilter); } @Provides @Singleton IPluginManager providePluginManager(IRuntimeManager runtimeManager) { diff --git a/src/main/java/com/gitblit/FederationClient.java b/src/main/java/com/gitblit/FederationClient.java index 29cdefe6..079355ef 100644 --- a/src/main/java/com/gitblit/FederationClient.java +++ b/src/main/java/com/gitblit/FederationClient.java @@ -36,6 +36,8 @@ import com.gitblit.models.Mailing; import com.gitblit.service.FederationPullService;
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.StringUtils;
+import com.gitblit.utils.XssFilter;
+import com.gitblit.utils.XssFilter.AllowXssFilter;
/**
* Command-line client to pull federated Gitblit repositories.
@@ -92,7 +94,8 @@ public class FederationClient { }
// configure the Gitblit singleton for minimal, non-server operation
- RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();
+ XssFilter xssFilter = new AllowXssFilter();
+ RuntimeManager runtime = new RuntimeManager(settings, xssFilter, baseFolder).start();
NoopNotificationManager notifications = new NoopNotificationManager().start();
UserManager users = new UserManager(runtime, null).start();
RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();
diff --git a/src/main/java/com/gitblit/MigrateTickets.java b/src/main/java/com/gitblit/MigrateTickets.java index ad1c63ea..94284ee2 100644 --- a/src/main/java/com/gitblit/MigrateTickets.java +++ b/src/main/java/com/gitblit/MigrateTickets.java @@ -39,6 +39,8 @@ import com.gitblit.tickets.FileTicketService; import com.gitblit.tickets.ITicketService; import com.gitblit.tickets.RedisTicketService; import com.gitblit.utils.StringUtils; +import com.gitblit.utils.XssFilter; +import com.gitblit.utils.XssFilter.AllowXssFilter; /** * A command-line tool to move all tickets from one ticket service to another. @@ -134,7 +136,8 @@ public class MigrateTickets { settings.overrideSetting(Keys.web.activityCacheDays, 0); settings.overrideSetting(ITicketService.SETTING_UPDATE_DIFFSTATS, false); - IRuntimeManager runtimeManager = new RuntimeManager(settings, baseFolder).start(); + XssFilter xssFilter = new AllowXssFilter(); + IRuntimeManager runtimeManager = new RuntimeManager(settings, xssFilter, baseFolder).start(); IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, null, null).start(); String inputServiceName = settings.getString(Keys.tickets.service, BranchTicketService.class.getSimpleName()); diff --git a/src/main/java/com/gitblit/ReindexTickets.java b/src/main/java/com/gitblit/ReindexTickets.java index 5a614481..858436af 100644 --- a/src/main/java/com/gitblit/ReindexTickets.java +++ b/src/main/java/com/gitblit/ReindexTickets.java @@ -33,6 +33,8 @@ import com.gitblit.tickets.FileTicketService; import com.gitblit.tickets.ITicketService; import com.gitblit.tickets.RedisTicketService; import com.gitblit.utils.StringUtils; +import com.gitblit.utils.XssFilter; +import com.gitblit.utils.XssFilter.AllowXssFilter; /** * A command-line tool to reindex all tickets in all repositories when the @@ -126,7 +128,8 @@ public class ReindexTickets { settings.overrideSetting(Keys.git.enableMirroring, false); settings.overrideSetting(Keys.web.activityCacheDays, 0); - IRuntimeManager runtimeManager = new RuntimeManager(settings, baseFolder).start(); + XssFilter xssFilter = new AllowXssFilter(); + IRuntimeManager runtimeManager = new RuntimeManager(settings, xssFilter, baseFolder).start(); IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, null, null).start(); String serviceName = settings.getString(Keys.tickets.service, BranchTicketService.class.getSimpleName()); diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index b9ae122f..2ed52d67 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -79,6 +79,7 @@ import com.gitblit.tickets.ITicketService; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.SshKey; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.XssFilter; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.JsonUtils; import com.gitblit.utils.ObjectCache; @@ -663,6 +664,11 @@ public class GitblitManager implements IGitblit { return runtimeManager.getStatus(); } + @Override + public XssFilter getXssFilter() { + return runtimeManager.getXssFilter(); + } + /* * NOTIFICATION MANAGER */ diff --git a/src/main/java/com/gitblit/manager/IRuntimeManager.java b/src/main/java/com/gitblit/manager/IRuntimeManager.java index b2d7a2b3..132534c3 100644 --- a/src/main/java/com/gitblit/manager/IRuntimeManager.java +++ b/src/main/java/com/gitblit/manager/IRuntimeManager.java @@ -24,6 +24,7 @@ import java.util.TimeZone; import com.gitblit.IStoredSettings; import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; +import com.gitblit.utils.XssFilter; public interface IRuntimeManager extends IManager { @@ -151,4 +152,11 @@ public interface IRuntimeManager extends IManager { * @since 1.4.0 */ boolean updateSettings(Map<String, String> updatedSettings); + + /** + * Returns the HTML sanitizer used to clean user content. + * + * @return the HTML sanitizer + */ + XssFilter getXssFilter(); }
\ No newline at end of file diff --git a/src/main/java/com/gitblit/manager/RuntimeManager.java b/src/main/java/com/gitblit/manager/RuntimeManager.java index 9cdc64eb..219bf801 100644 --- a/src/main/java/com/gitblit/manager/RuntimeManager.java +++ b/src/main/java/com/gitblit/manager/RuntimeManager.java @@ -32,6 +32,7 @@ import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; import com.gitblit.models.SettingModel; import com.gitblit.utils.StringUtils; +import com.gitblit.utils.XssFilter; public class RuntimeManager implements IRuntimeManager { @@ -39,6 +40,8 @@ public class RuntimeManager implements IRuntimeManager { private final IStoredSettings settings; + private final XssFilter xssFilter; + private final ServerStatus serverStatus; private final ServerSettings settingsModel; @@ -47,14 +50,15 @@ public class RuntimeManager implements IRuntimeManager { private TimeZone timezone; - public RuntimeManager(IStoredSettings settings) { - this(settings, null); + public RuntimeManager(IStoredSettings settings, XssFilter xssFilter) { + this(settings, xssFilter, null); } - public RuntimeManager(IStoredSettings settings, File baseFolder) { + public RuntimeManager(IStoredSettings settings, XssFilter xssFilter, File baseFolder) { this.settings = settings; this.settingsModel = new ServerSettings(); this.serverStatus = new ServerStatus(); + this.xssFilter = xssFilter; this.baseFolder = baseFolder == null ? new File("") : baseFolder; } @@ -262,4 +266,15 @@ public class RuntimeManager implements IRuntimeManager { serverStatus.heapFree = Runtime.getRuntime().freeMemory(); return serverStatus; } + + /** + * Returns the XSS filter. + * + * @return the XSS filter + */ + @Override + public XssFilter getXssFilter() { + return xssFilter; + } + } diff --git a/src/main/java/com/gitblit/utils/JSoupXssFilter.java b/src/main/java/com/gitblit/utils/JSoupXssFilter.java new file mode 100644 index 00000000..b07bcb9d --- /dev/null +++ b/src/main/java/com/gitblit/utils/JSoupXssFilter.java @@ -0,0 +1,87 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.utils; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.safety.Cleaner; +import org.jsoup.safety.Whitelist; + +/** + * Implementation of an XSS filter based on JSoup. + * + * @author James Moger + * + */ +public class JSoupXssFilter implements XssFilter { + + private final Cleaner none; + + private final Cleaner relaxed; + + public JSoupXssFilter() { + none = new Cleaner(Whitelist.none()); + relaxed = new Cleaner(getRelaxedWhiteList()); + } + + @Override + public String none(String input) { + return clean(input, none); + } + + @Override + public String relaxed(String input) { + return clean(input, relaxed); + } + + protected String clean(String input, Cleaner cleaner) { + Document unsafe = Jsoup.parse(input); + Document safe = cleaner.clean(unsafe); + return safe.body().html(); + } + + /** + * Builds & returns a loose HTML whitelist similar to Github. + * + * https://github.com/github/markup/tree/master#html-sanitization + * @return a loose HTML whitelist + */ + protected Whitelist getRelaxedWhiteList() { + return new Whitelist() + .addTags( + "a", "b", "blockquote", "br", "caption", "cite", "code", "col", + "colgroup", "dd", "del", "div", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", + "i", "img", "ins", "kbd", "li", "ol", "p", "pre", "q", "samp", "small", "strike", "strong", + "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "tt", "u", + "ul", "var") + + .addAttributes("a", "href", "title") + .addAttributes("blockquote", "cite") + .addAttributes("col", "span", "width") + .addAttributes("colgroup", "span", "width") + .addAttributes("img", "align", "alt", "height", "src", "title", "width") + .addAttributes("ol", "start", "type") + .addAttributes("q", "cite") + .addAttributes("table", "summary", "width") + .addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width") + .addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope", "width") + .addAttributes("ul", "type") + + .addEnforcedAttribute("a", "rel", "nofollow") + ; + } + +} diff --git a/src/main/java/com/gitblit/utils/XssFilter.java b/src/main/java/com/gitblit/utils/XssFilter.java new file mode 100644 index 00000000..20b51057 --- /dev/null +++ b/src/main/java/com/gitblit/utils/XssFilter.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.utils; + +/** + * Defines the contract for an XSS filter implementation. + * + * @author James Moger + * + */ +public interface XssFilter { + + /** + * Returns a filtered version of the input value that contains no html + * elements. + * + * @param input + * @return a plain text value + */ + String none(String input); + + /** + * Returns a filtered version of the input that contains structural html + * elements. + * + * @param input + * @return a filtered html value + */ + String relaxed(String input); + + /** + * A NOOP XSS filter. + * + * @author James Moger + * + */ + public class AllowXssFilter implements XssFilter { + + @Override + public String none(String input) { + return input; + } + + @Override + public String relaxed(String input) { + return input; + } + + } + +} diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java index f63ff3d9..6cf5f582 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java @@ -46,6 +46,7 @@ import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; import com.gitblit.tickets.ITicketService; import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.utils.XssFilter; import com.gitblit.wicket.pages.ActivityPage; import com.gitblit.wicket.pages.BlamePage; import com.gitblit.wicket.pages.BlobDiffPage; @@ -100,6 +101,8 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp { private final IStoredSettings settings; + private final XssFilter xssFilter; + private final IRuntimeManager runtimeManager; private final IPluginManager pluginManager; @@ -134,6 +137,7 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp { super(); this.settings = runtimeManager.getSettings(); + this.xssFilter = runtimeManager.getXssFilter(); this.runtimeManager = runtimeManager; this.pluginManager = pluginManager; this.notificationManager = notificationManager; @@ -308,6 +312,14 @@ public class GitBlitWebApp extends WebApplication implements GitblitWicketApp { } /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#xssFilter() + */ + @Override + public XssFilter xssFilter() { + return xssFilter; + } + + /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#isDebugMode() */ @Override diff --git a/src/main/java/com/gitblit/wicket/GitblitWicketApp.java b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java index a56e6996..8d3d598d 100644 --- a/src/main/java/com/gitblit/wicket/GitblitWicketApp.java +++ b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java @@ -17,6 +17,7 @@ import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; import com.gitblit.tickets.ITicketService; import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.utils.XssFilter; public interface GitblitWicketApp { @@ -30,6 +31,8 @@ public interface GitblitWicketApp { public abstract IStoredSettings settings(); + public abstract XssFilter xssFilter(); + /** * Is Gitblit running in debug mode? * |