Do not escape WHOIS output

Both WhoisAction and WhoisHttpAction set the HTTP response content type to "text/plain". There is no need to defensively escape the content. In fact, by escaping the content, it creates more problems down the line.

When used in a website, the response should be written into a DOM node by setting the textContent of the node, which automatically escapes the content.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=196743398
This commit is contained in:
jianglai 2018-05-15 15:51:31 -07:00
parent f1219120ea
commit 7388958df7
14 changed files with 26 additions and 55 deletions

View file

@ -17,7 +17,6 @@ package google.registry.whois;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.html.HtmlEscapers.htmlEscaper;
import com.google.common.base.Joiner;
import google.registry.model.eppcommon.Address;
@ -187,16 +186,9 @@ abstract class WhoisResponseImpl implements WhoisResponse {
return emitNewline();
}
/**
* Remove potentially dangerous stuff from WHOIS output fields.
*
* <ul>
* <li>Remove ASCII control characters like {@code \n} which could be used to forge output.
* <li>Escape HTML entities, just in case this gets injected poorly into a webpage.
* </ul>
*/
/** Remove ASCII control characters like {@code \n} which could be used to forge output. */
private String cleanse(String value) {
return htmlEscaper().escape(value).replaceAll("[\\x00-\\x1f]", " ");
return value.replaceAll("[\\x00-\\x1f]", " ");
}
@Override

View file

@ -117,7 +117,7 @@ public class DomainWhoisResponseTest {
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName("EXAMPLE REGISTRANT")
.setOrg("EXAMPLE ORGANIZATION")
.setOrg("Tom & Jerry Corp.")
.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 EXAMPLE STREET"))
.setCity("ANYTOWN")

View file

@ -52,7 +52,7 @@ public class NameserverWhoisResponseTest {
@Before
public void setUp() {
persistNewRegistrar("example", "Example Registrar, Inc.", Registrar.Type.REAL, 8L);
persistNewRegistrar("example", "Hänsel & Gretel Registrar, Inc.", Registrar.Type.REAL, 8L);
persistResource(loadRegistrar("example").asBuilder().setUrl("http://my.fake.url").build());
createTld("tld");

View file

@ -103,7 +103,7 @@ public class RegistrarWhoisResponseTest {
.build(),
new RegistrarContact.Builder()
.setParent(registrar)
.setName("John Geek")
.setName("Bonnie & Clyde")
.setEmailAddress("johngeek@example-registrar.tld")
.setPhoneNumber("+1.3105551215")
.setFaxNumber("+1.3105551216")

View file

@ -115,7 +115,7 @@ public class WhoisActionTest {
@Test
public void testRun_domainQuery_works() {
Registrar registrar =
persistResource(makeRegistrar("evilregistrar", "Yes Virginia <script>", ACTIVE));
persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource(
makeDomainResource(
"cat.lol",
@ -134,7 +134,7 @@ public class WhoisActionTest {
@Test
public void testRun_domainQuery_usesCache() {
Registrar registrar =
persistResource(makeRegistrar("evilregistrar", "Yes Virginia <script>", ACTIVE));
persistResource(makeRegistrar("evilregistrar", "Yes Virginia", ACTIVE));
persistResource(
makeDomainResource(
"cat.lol",
@ -170,7 +170,7 @@ public class WhoisActionTest {
@Test
public void testRun_idnDomain_works() throws Exception {
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", ACTIVE));
"evilregistrar", "Yes Virginia", ACTIVE));
persistResource(makeDomainResource(
"cat.みんな",
persistResource(makeContactResource("5372808-ERL", "(◕‿◕)", "lol@cat.みんな")),
@ -188,7 +188,7 @@ public class WhoisActionTest {
@Test
public void testRun_punycodeDomain_works() throws Exception {
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", ACTIVE));
"evilregistrar", "Yes Virginia", ACTIVE));
persistResource(makeDomainResource(
"cat.みんな",
persistResource(makeContactResource("5372808-ERL", "(◕‿◕)", "lol@cat.みんな")),
@ -227,7 +227,7 @@ public class WhoisActionTest {
public void testRun_domainInTestTld_isConsideredNotFound() throws Exception {
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", ACTIVE));
"evilregistrar", "Yes Virginia", ACTIVE));
persistResource(makeDomainResource(
"cat.lol",
persistResource(makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")),

View file

@ -49,7 +49,6 @@ import java.io.IOException;
import java.io.Reader;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@ -92,12 +91,6 @@ public class WhoisHttpActionTest {
inject.setStaticField(Ofy.class, "clock", clock);
}
@After
public void after() throws Exception {
// Extra precaution to ensure HTML escaping is working securely.
assertThat(response.getPayload()).doesNotContain("<script>");
}
@Test
public void testRun_emptyQuery_returns400BadRequestWithPlainTextOutput() throws Exception {
newWhoisHttpAction("").run();
@ -128,7 +121,7 @@ public class WhoisHttpActionTest {
public void testRun_domainInTestTld_isConsideredNotFound() throws Exception {
persistResource(Registry.get("lol").asBuilder().setTldType(Registry.TldType.TEST).build());
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
"evilregistrar", "Yes Virginia", Registrar.State.ACTIVE));
persistResource(makeDomainResource(
"cat.lol",
persistResource(makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")),
@ -147,7 +140,7 @@ public class WhoisHttpActionTest {
@Test
public void testRun_domainQueryIdn_works() throws Exception {
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
"evilregistrar", "Yes Virginia", Registrar.State.ACTIVE));
persistResource(makeDomainResource(
"cat.みんな",
persistResource(makeContactResource("5372808-ERL", "(◕‿◕)", "lol@cat.みんな")),
@ -200,20 +193,6 @@ public class WhoisHttpActionTest {
assertThat(response.getPayload()).contains("Domain Name: cat.みんな\r\n");
}
@Test
public void testRun_maliciousHtmlInDatastore_getsPurged() throws Exception {
persistResource(makeDomainResource("cat.みんな",
persistResource(makeContactResource("5372808-ERL", "(◕‿◕)", "lol@cat.みんな")),
persistResource(makeContactResource("5372808-IRL", "Operator", "BOFH@cat.みんな")),
persistResource(
makeContactResource("5372808-TRL", "<script>alert('lol');</script>", "bog@cat.みんな")),
persistResource(makeHostResource("ns1.cat.みんな", "1.2.3.4")),
persistResource(makeHostResource("ns2.cat.みんな", "bad:f00d:cafe::15:beef")),
persistResource(makeRegistrar("example", "Example Registrar", Registrar.State.ACTIVE))));
newWhoisHttpAction("cat.みんな").run();
assertThat(response.getPayload()).doesNotContain("<script>");
}
@Test
public void testRun_hostnameOnly_works() throws Exception {
persistResource(makeHostResource("ns1.cat.みんな", "1.2.3.4"));
@ -224,7 +203,7 @@ public class WhoisHttpActionTest {
@Test
public void testRun_domainQueryPunycode_works() throws Exception {
Registrar registrar = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
"evilregistrar", "Yes Virginia", Registrar.State.ACTIVE));
persistResource(makeDomainResource(
"cat.みんな",
persistResource(makeContactResource("5372808-ERL", "(◕‿◕)", "lol@cat.みんな")),

View file

@ -5,7 +5,7 @@ Registrar URL: http://my.fake.url
Updated Date: 2009-05-29T20:13:00Z
Creation Date: 2000-10-08T00:45:00Z
Registry Expiry Date: 2110-10-08T00:44:59Z
Registrar: Yes Virginia &lt;script&gt;
Registrar: Yes Virginia
Registrar IANA ID: 1
Registrar Abuse Contact Email: jakedoe@example.com
Registrar Abuse Contact Phone: +1.2125551216
@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Organization: GOOGLE INCORPORATED <script>
Registrant State/Province: BM
Registrant Country: US
Name Server: ns1.cat.lol

View file

@ -5,7 +5,7 @@ Registrar URL: http://my.fake.url
Updated Date: 2009-05-29T20:13:00Z
Creation Date: 2000-10-08T00:45:00Z
Registry Expiry Date: 2110-10-08T00:44:59Z
Registrar: Yes Virginia &lt;script&gt;
Registrar: Yes Virginia
Registrar IANA ID: 1
Registrar Abuse Contact Email: jakedoe@example.com
Registrar Abuse Contact Phone: +1.2125551216
@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Organization: GOOGLE INCORPORATED <script>
Registrant State/Province: BM
Registrant Country: US
Name Server: ns1.cat.xn--q9jyb4c

View file

@ -5,7 +5,7 @@ Registrar URL: http://my.fake.url
Updated Date: 2009-05-29T20:13:00Z
Creation Date: 2000-10-08T00:45:00Z
Registry Expiry Date: 2110-10-08T00:44:59Z
Registrar: Yes Virginia &lt;script&gt;
Registrar: Yes Virginia
Registrar IANA ID: 1
Registrar Abuse Contact Email: jakedoe@example.com
Registrar Abuse Contact Phone: +1.2125551216
@ -13,7 +13,7 @@ Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibit
Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registrant Organization: GOOGLE INCORPORATED &lt;script&gt;
Registrant Organization: GOOGLE INCORPORATED <script>
Registrant State/Province: BM
Registrant Country: US
Name Server: ns1.cat.みんな

View file

@ -1,6 +1,6 @@
Registrar: Example Registrar, Inc.
Street: 123 Example Boulevard &lt;script&gt;
City: Williamsburg &lt;script&gt;
Street: 123 Example Boulevard <script>
City: Williamsburg <script>
State/Province: NY
Postal Code: 11211
Country: US

View file

@ -15,7 +15,7 @@ Domain Status: clientRenewProhibited https://icann.org/epp#clientRenewProhibited
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Domain Status: transferPeriod https://icann.org/epp#transferPeriod
Registrant Organization: EXAMPLE ORGANIZATION
Registrant Organization: Tom & Jerry Corp.
Registrant State/Province: AP
Registrant Country: EX
Name Server: ns01.exampleregistrar.tld

View file

@ -1,14 +1,14 @@
Server Name: ns1.example.tld
IP Address: 192.0.2.123
IP Address: 2001:db8::1
Registrar: Example Registrar, Inc.
Registrar: Hänsel & Gretel Registrar, Inc.
Registrar WHOIS Server: whois.nic.fakewhois.example
Registrar URL: http://my.fake.url
Server Name: ns2.example.tld
IP Address: 192.0.2.123
IP Address: 2001:db8::1
Registrar: Example Registrar, Inc.
Registrar: Hänsel & Gretel Registrar, Inc.
Registrar WHOIS Server: whois.nic.fakewhois.example
Registrar URL: http://my.fake.url
>>> Last update of WHOIS database: 2009-05-29T20:15:00Z <<<

View file

@ -1,7 +1,7 @@
Server Name: ns1.example.tld
IP Address: 192.0.2.123
IP Address: 2001:db8::1
Registrar: Example Registrar, Inc.
Registrar: Hänsel & Gretel Registrar, Inc.
Registrar WHOIS Server: whois.nic.fakewhois.example
Registrar URL: http://my.fake.url
>>> Last update of WHOIS database: 2009-05-29T20:15:00Z <<<

View file

@ -17,7 +17,7 @@ Admin Contact: Joe Registrar
Phone Number: +1.3105551213
Fax Number: +1.3105551213
Email: joeregistrar@example-registrar.tld
Technical Contact: John Geek
Technical Contact: Bonnie & Clyde
Phone Number: +1.3105551215
Fax Number: +1.3105551216
Email: johngeek@example-registrar.tld