Skip to content

Commit

Permalink
LPD-41486 Fix HTML injection in iframe client extension
Browse files Browse the repository at this point in the history
Changing " to %22 is enough to fix the HTML injection for the URL. For the
case of parameters we just need to replace " in the parameter name, which
is not encoded by HttpComponentsUtil. The value is already encoded by that
method so we are safe.
  • Loading branch information
izaera authored and brianchandotcom committed Nov 12, 2024
1 parent 828c178 commit 1880b4b
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
package com.liferay.client.extension.web.internal.portlet;

import com.liferay.client.extension.type.IFrameCET;
import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringBundler;
import com.liferay.portal.kernel.servlet.taglib.util.OutputData;
import com.liferay.portal.kernel.util.HashMapDictionaryBuilder;
import com.liferay.portal.kernel.util.HttpComponentsUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.WebKeys;

import java.io.IOException;
Expand Down Expand Up @@ -81,13 +83,18 @@ public void render(

printWriter.print("<iframe src=\"");

String iFrameURL = cet.getURL();
String iFrameURL = StringUtil.replace(
cet.getURL(), CharPool.QUOTE, _ENCODED_DOUBLE_QUOTE);

Properties properties = getProperties(renderRequest);

for (Map.Entry<Object, Object> entry : properties.entrySet()) {
iFrameURL = HttpComponentsUtil.addParameter(
iFrameURL, (String)entry.getKey(), (String)entry.getValue());
iFrameURL,
StringUtil.replace(
(String)entry.getKey(), CharPool.QUOTE,
_ENCODED_DOUBLE_QUOTE),
(String)entry.getValue());
}

printWriter.print(iFrameURL);
Expand All @@ -97,6 +104,8 @@ public void render(
printWriter.flush();
}

private static final String _ENCODED_DOUBLE_QUOTE = "%22";

private final Portal _portal;
private final String _portletId;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* SPDX-FileCopyrightText: (c) 2024 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/

package com.liferay.client.extension.web.internal.portlet;

import com.liferay.client.extension.type.IFrameCET;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.test.rule.LiferayUnitTestRule;
import com.liferay.portal.util.PortalImpl;
import com.liferay.portletmvc4spring.test.mock.web.portlet.MockPortletPreferences;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;

import java.util.Properties;

import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

import org.mockito.Mockito;

/**
* @author Iván Zaera Avellón
*/
public class IFrameCETPortletTest {

@ClassRule
@Rule
public static final LiferayUnitTestRule liferayUnitTestRule =
LiferayUnitTestRule.INSTANCE;

@Before
public void setUp() {
_portal = new PortalImpl();

new PortalUtil(
).setPortal(
_portal
);
}

@Test
public void testRenderWithQuotedProperties() throws IOException {
IFrameCET iFrameCET = Mockito.mock(IFrameCET.class);

Properties properties = new Properties();

properties.put("\"height", "399\"");

Mockito.when(
iFrameCET.getProperties()
).thenReturn(
properties
);

Mockito.when(
iFrameCET.getURL()
).thenReturn(
"https://example.com"
);

IFrameCETPortlet iFrameCETPortlet = new IFrameCETPortlet(
iFrameCET, "portletId", _portal);

RenderRequest renderRequest = Mockito.mock(RenderRequest.class);

Mockito.when(
renderRequest.getPreferences()
).thenReturn(
new MockPortletPreferences()
);

RenderResponse renderResponse = Mockito.mock(RenderResponse.class);

CharArrayWriter charArrayWriter = new CharArrayWriter();

PrintWriter printWriter = new PrintWriter(charArrayWriter);

Mockito.when(
renderResponse.getWriter()
).thenReturn(
printWriter
);

iFrameCETPortlet.render(renderRequest, renderResponse);

Assert.assertEquals(
"<iframe src=\"https://example.com?%22height=399%22\"></iframe>",
charArrayWriter.toString());
}

private Portal _portal;

}

0 comments on commit 1880b4b

Please sign in to comment.