Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] RHPAM-4723: Creating a branch via BC UI can lead to XSS #1400

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
RHPAM-4917: Expand escaping to RepositoryService
Refactors unit tests to use same methods as in main classes
Add some unit tests
  • Loading branch information
domhanak authored and paulovmr committed Jul 12, 2023
commit 04536b380c249b17f66039e31d675f6ac4c93e48
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,19 @@ private OrganizationalUnit createDeletedOrganizationalUnit(ConfigGroup configGro
private Collection<Contributor> escapeContributorsNames(Collection<Contributor> contributors) {
Collection<Contributor> escapedContributors = new ArrayList<>();
contributors.forEach((contributor -> {
String escapedName = StringEscapeUtils.escapeHtml4(contributor.getUsername());
escapedName = escapedName.replace("'", "");
String escapedName = escapeHtmlInput(contributor.getUsername());
escapedContributors.add(new Contributor(escapedName, contributor.getType()));
}));
return escapedContributors;
}

String escapeHtmlInput(String input) {
if (input != null) {
String escapedInput = StringEscapeUtils.escapeHtml4(input);
escapedInput = escapedInput.replace("'", "");
return escapedInput;
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.text.StringEscapeUtils;
import org.guvnor.common.services.backend.exceptions.ExceptionUtilities;
import org.guvnor.common.services.project.events.RepositoryContributorsUpdatedEvent;
import org.guvnor.structure.backend.backcompat.BackwardCompatibleUtil;
Expand Down Expand Up @@ -539,7 +540,7 @@ public void updateContributors(final Repository repository,

thisRepositoryConfig.ifPresent(config -> {
config.getConfiguration().add("contributors",
contributors);
escapeContributorsNames(contributors));
this.saveRepositoryConfig(repository.getSpace().getName(),
config);
repositoryContributorsUpdatedEvent.fire(new RepositoryContributorsUpdatedEvent(getRepositoryFromSpace(repository.getSpace(),
Expand Down Expand Up @@ -619,6 +620,25 @@ private void addConfiguration(final RepositoryConfiguration repositoryConfigurat
}
}

public Collection<Contributor> escapeContributorsNames(Collection<Contributor> contributors) {
Collection<Contributor> escapedContributors = new ArrayList<>();
contributors.forEach((contributor -> {
String escapedName = escapeHtmlInput(contributor.getUsername());
escapedContributors.add(new Contributor(escapedName, contributor.getType()));
}));
return escapedContributors;
}

String escapeHtmlInput(String input) {
if (input != null) {
String escapedInput = StringEscapeUtils.escapeHtml4(input);
escapedInput = escapedInput.replace("'", "");
return escapedInput;
} else {
return null;
}
}

public class NoActiveSpaceInTheContext extends RuntimeException {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import javax.enterprise.event.Event;

import org.apache.commons.text.StringEscapeUtils;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Condition;
import org.guvnor.structure.backend.organizationalunit.config.SpaceConfigStorageRegistryImpl;
Expand Down Expand Up @@ -271,14 +270,14 @@ public void createValidOrganizationalUnitTest() {
assertEquals(contributors, ou.getContributors());
Assertions.assertThat(ou.getContributors()).hasSize(1);
Assertions.assertThat(ou.getContributors()).hasOnlyOneElementSatisfying((contributor) -> {
contributor.getUsername().equals(StringEscapeUtils.escapeHtml4(ADMIN));
contributor.getUsername().equals(organizationalUnitService.escapeHtmlInput(ADMIN));
});
}

@Test
public void createOrganizationalUnitWithPersistentXssInContributorTest() {
final String persistentXssContributor = "<img/src/onerror=alert(\"XSS\")>";
final String escapedPersistentXssContributor = StringEscapeUtils.escapeHtml4(persistentXssContributor);
final String escapedPersistentXssContributor = organizationalUnitService.escapeHtmlInput(persistentXssContributor);

List<Contributor> contributors = new ArrayList<>();
contributors.add(new Contributor(persistentXssContributor,
Expand Down Expand Up @@ -307,9 +306,10 @@ public void createOrganizationalUnitWithPersistentXssInContributorTest() {
@Test
public void createOrganizationalUnitWithPersistentXssAndValidContributorTest() {
final String persistentXssContributor = "<img/src/onerror=alert(\"XSS\")>";
final String escapedPersistentXssContributor = StringEscapeUtils.escapeHtml4(persistentXssContributor);
final String escapedAdminContributor = StringEscapeUtils.escapeHtml4(ADMIN);
final String escapedPersistentXssContributor = organizationalUnitService.escapeHtmlInput(persistentXssContributor);
final String escapedAdminContributor = organizationalUnitService.escapeHtmlInput(ADMIN);
final String regularContributor = "head_technician_junior-intern";
final String escapedRegularContributor = organizationalUnitService.escapeHtmlInput(regularContributor);

List<Contributor> contributors = new ArrayList<>();
contributors.add(new Contributor(persistentXssContributor,
Expand Down Expand Up @@ -338,7 +338,7 @@ public void createOrganizationalUnitWithPersistentXssAndValidContributorTest() {
ContributorType.CONTRIBUTOR),
new Contributor(escapedAdminContributor,
ContributorType.ADMIN),
new Contributor(StringEscapeUtils.escapeHtml4(regularContributor),
new Contributor(escapedRegularContributor,
ContributorType.OWNER));
}

Expand Down Expand Up @@ -401,7 +401,7 @@ public void testUpdateOrganizationalUnit() {
@Test
public void testContributorsPersistentXssOnUpdateOrganizationalUnit() {
final String persistentXssContributor = "<img/src/onerror=alert(\"XSS\")>";
final String escapedPersistentXssContributor = StringEscapeUtils.escapeHtml4(persistentXssContributor);
final String escapedPersistentXssContributor = organizationalUnitService.escapeHtmlInput(persistentXssContributor);

OrganizationalUnit organizationalUnit =
organizationalUnitService.updateOrganizationalUnit(SPACE_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,53 @@ public void updateContributorsTest() {
verify(spaceConfigStorage).endBatch();
}

@Test
public void updateContributorsWithXSSNameTest() {

final Space space = new Space("space");
doReturn(space).when(repository).getSpace();
doReturn("alias").when(repository).getAlias();

doReturn(repository).when(configuredRepositories).getRepositoryByRepositoryAlias(any(),
any());

final SpaceConfigStorage spaceConfigStorage = mock(SpaceConfigStorage.class);
doReturn(new SpaceInfo("space",
"Test space",
"defaultGroupId",
Collections.emptyList(),
new ArrayList<>(Arrays.asList(new RepositoryInfo("alias",
false,
new RepositoryConfiguration()))),
Collections.emptyList())).when(spaceConfigStorage).loadSpaceInfo();

when(registry.get(anyString())).thenReturn(spaceConfigStorage);
when(registry.getBatch(anyString())).thenReturn(new SpaceConfigStorageRegistryImpl.SpaceStorageBatchImpl(spaceConfigStorage));

final String xssName = "<img/src/onerror=alert(\"XSS\")>";
final String escapedXssName = repositoryService.escapeHtmlInput(xssName);
repositoryService.updateContributors(repository,
Collections.singletonList(new Contributor(xssName,
ContributorType.OWNER)));

verify(updatedEvent).fire(captor.capture());
assertEquals("alias",
captor.getValue().getRepository().getAlias());
assertEquals("space",
captor.getValue().getRepository().getSpace().getName());
verify(repositoryService).saveRepositoryConfig(eq("space"),
configCaptor.capture());

assertEquals(escapedXssName,
configCaptor.getValue().getContributors().get(0).getUsername());
assertEquals(ContributorType.OWNER,
configCaptor.getValue().getContributors().get(0).getType());

verify(spaceConfigStorage).startBatch();
verify(spaceConfigStorage).saveSpaceInfo(any());
verify(spaceConfigStorage).endBatch();
}

@Test
public void testDoRemoveInOrder() {

Expand Down