This is an automated email from the ASF dual-hosted git repository. schultz pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/8.5.x by this push: new 02805df258 Properly-escape role and group information when writing MemoryUserDatabase to an XML file. 02805df258 is described below commit 02805df258843ad6506231091d937b04186941d0 Author: Christopher Schultz <ch...@christopherschultz.net> AuthorDate: Wed Aug 3 13:18:51 2022 -0400 Properly-escape role and group information when writing MemoryUserDatabase to an XML file. --- java/org/apache/catalina/users/MemoryGroup.java | 10 +++--- java/org/apache/catalina/users/MemoryRole.java | 6 ++-- .../catalina/users/MemoryUserDatabaseTests.java | 40 ++++++++++++++++++++++ webapps/docs/changelog.xml | 4 +++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/java/org/apache/catalina/users/MemoryGroup.java b/java/org/apache/catalina/users/MemoryGroup.java index eafeb80968..4b5d74f400 100644 --- a/java/org/apache/catalina/users/MemoryGroup.java +++ b/java/org/apache/catalina/users/MemoryGroup.java @@ -27,7 +27,7 @@ import org.apache.catalina.User; import org.apache.catalina.UserDatabase; import org.apache.tomcat.util.buf.StringUtils; import org.apache.tomcat.util.buf.StringUtils.Function; - +import org.apache.tomcat.util.security.Escape; /** * <p>Concrete implementation of {@link org.apache.catalina.Group} for the @@ -165,16 +165,18 @@ public class MemoryGroup extends AbstractGroup { @Override public String toString() { StringBuilder sb = new StringBuilder("<group groupname=\""); - sb.append(groupname); + sb.append(Escape.xml(groupname)); sb.append("\""); if (description != null) { sb.append(" description=\""); - sb.append(description); + sb.append(Escape.xml(description)); sb.append("\""); } sb.append(" roles=\""); + StringBuilder rsb = new StringBuilder(); StringUtils.join(roles, ',', new Function<Role>(){ - @Override public String apply(Role t) { return t.getRolename(); }}, sb); + @Override public String apply(Role t) { return Escape.xml(t.getRolename()); }}, rsb); + sb.append(rsb); sb.append("\""); sb.append("/>"); return sb.toString(); diff --git a/java/org/apache/catalina/users/MemoryRole.java b/java/org/apache/catalina/users/MemoryRole.java index b8f49702c2..af18d2b26e 100644 --- a/java/org/apache/catalina/users/MemoryRole.java +++ b/java/org/apache/catalina/users/MemoryRole.java @@ -18,7 +18,7 @@ package org.apache.catalina.users; import org.apache.catalina.UserDatabase; - +import org.apache.tomcat.util.security.Escape; /** * <p>Concrete implementation of {@link org.apache.catalina.Role} for the @@ -82,11 +82,11 @@ public class MemoryRole extends AbstractRole { @Override public String toString() { StringBuilder sb = new StringBuilder("<role rolename=\""); - sb.append(rolename); + sb.append(Escape.xml(rolename)); sb.append("\""); if (description != null) { sb.append(" description=\""); - sb.append(description); + sb.append(Escape.xml(description)); sb.append("\""); } sb.append("/>"); diff --git a/test/org/apache/catalina/users/MemoryUserDatabaseTests.java b/test/org/apache/catalina/users/MemoryUserDatabaseTests.java index 5724ac7829..fa97f93e6b 100644 --- a/test/org/apache/catalina/users/MemoryUserDatabaseTests.java +++ b/test/org/apache/catalina/users/MemoryUserDatabaseTests.java @@ -33,6 +33,8 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import org.apache.catalina.Group; +import org.apache.catalina.Role; import org.apache.catalina.User; import org.apache.catalina.realm.GenericPrincipal; import org.apache.catalina.realm.UserDatabaseRealm; @@ -216,4 +218,42 @@ public class MemoryUserDatabaseTests { Assert.assertEquals(expectedNames.length, j); } + + @Test + public void testDataEscaping() throws Exception { + File file = File.createTempFile("tomcat-users", ".xml"); + file.deleteOnExit(); + + MemoryUserDatabase mud = new MemoryUserDatabase(); + Role role = mud.createRole("role\"name", "descr&iption"); + Group group = mud.createGroup("grou<p", null); + group.addRole(role); + Role role2 = mud.createRole("role2", null); + group.addRole(role2); + User user = mud.createUser("xml<breaker", "\"bobby", "tab'les"); + user.addRole(role); + user.addRole(role2); + user.addGroup(group); + mud.setPathname(file.getAbsolutePath()); + mud.setReadonly(false); + mud.save(); + + String xml; + try(java.io.FileReader in = new java.io.FileReader(file)) { + StringBuilder sb = new StringBuilder((int)file.length()); + char[] buffer = new char[4096]; + int c; + while(-1 != (c = in.read(buffer))) { + sb.append(buffer, 0, c); + } + xml = sb.toString(); + } + + Assert.assertTrue("Role is not properly-escaped", + xml.contains("<role rolename=\"role"name\" description=\"descr&iption\"")); + Assert.assertTrue("Group is not escaped properly", + xml.contains("<group groupname=\"grou<p\" roles=\"role"name,role2\"")); + Assert.assertTrue("User is not properly-escaped", + xml.contains("<user username=\"xml<breaker\" password=\""bobby\" fullName=\"tab'les\" groups=\"grou<p\" roles=\"role"name,role2\"")); + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 9e06fcaa00..b7e7f49cad 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -115,6 +115,10 @@ Implement the clarification in RFC 9110 that the units in HTTP range specifiers are case insensitive. (markt) </fix> + <fix> + Propertly-escape role and group information when writing + MemoryUserDatabase to an XML file. (schultz) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org