Add more strict hostname validation on host:check flows (#2915)

We do most of these on host create already so we should also do them on
host checks. The only added change is the character validation (our
existing hostnames all match these).
This commit is contained in:
gbrodman
2025-12-30 16:41:56 +00:00
committed by GitHub
parent 6f0bc1ded9
commit 2562d582f3
9 changed files with 121 additions and 56 deletions
@@ -20,7 +20,9 @@ import static google.registry.testing.DatabaseHelper.persistDeletedHost;
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
import google.registry.flows.EppException;
import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
import google.registry.flows.FlowUtils.NotLoggedInException;
import google.registry.flows.ResourceCheckFlowTestCase;
import google.registry.flows.exceptions.TooManyResourceChecksException;
@@ -95,4 +97,36 @@ class HostCheckFlowTest extends ResourceCheckFlowTestCase<HostCheckFlow, Host> {
runFlow();
assertIcannReportingActivityFieldLogged("srs-host-check");
}
@Test
void testFailure_dotHost() throws Exception {
setEppInput("host_check_generic.xml", ImmutableMap.of("HOSTNAME", ".host"));
assertAboutEppExceptions()
.that(assertThrows(ParameterValueSyntaxErrorException.class, this::runFlow))
.marshalsToXml();
}
@Test
void testFailure_dashHost() {
setEppInput("host_check_generic.xml", ImmutableMap.of("HOSTNAME", "-host"));
assertAboutEppExceptions()
.that(assertThrows(ParameterValueSyntaxErrorException.class, this::runFlow))
.marshalsToXml();
}
@Test
void testFailure_underscoreHost() {
setEppInput("host_check_generic.xml", ImmutableMap.of("HOSTNAME", "_host"));
assertAboutEppExceptions()
.that(assertThrows(ParameterValueSyntaxErrorException.class, this::runFlow))
.marshalsToXml();
}
@Test
void testFailure_hostDash() {
setEppInput("host_check_generic.xml", ImmutableMap.of("HOSTNAME", "host-"));
assertAboutEppExceptions()
.that(assertThrows(ParameterValueSyntaxErrorException.class, this::runFlow))
.marshalsToXml();
}
}
@@ -39,12 +39,12 @@ import google.registry.flows.exceptions.ResourceAlreadyExistsForThisClientExcept
import google.registry.flows.exceptions.ResourceCreateContentionException;
import google.registry.flows.host.HostCreateFlow.SubordinateHostMustHaveIpException;
import google.registry.flows.host.HostCreateFlow.UnexpectedExternalHostIpException;
import google.registry.flows.host.HostFlowUtils.BadHostNameCharacterException;
import google.registry.flows.host.HostFlowUtils.HostNameNotLowerCaseException;
import google.registry.flows.host.HostFlowUtils.HostNameNotNormalizedException;
import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException;
import google.registry.flows.host.HostFlowUtils.HostNameTooLongException;
import google.registry.flows.host.HostFlowUtils.HostNameTooShallowException;
import google.registry.flows.host.HostFlowUtils.InvalidHostNameException;
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainDoesNotExistException;
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainInPendingDeleteException;
import google.registry.model.ForeignKeyUtils;
@@ -286,7 +286,7 @@ class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Host> {
@Test
void testFailure_badCharacter() {
doFailingHostNameTest("foo bar", InvalidHostNameException.class);
doFailingHostNameTest("foo bar", BadHostNameCharacterException.class);
}
@Test
@@ -54,13 +54,13 @@ import google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException;
import google.registry.flows.ResourceFlowUtils.StatusNotClientSettableException;
import google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException;
import google.registry.flows.exceptions.ResourceStatusProhibitsOperationException;
import google.registry.flows.host.HostFlowUtils.BadHostNameCharacterException;
import google.registry.flows.host.HostFlowUtils.HostDomainNotOwnedException;
import google.registry.flows.host.HostFlowUtils.HostNameNotLowerCaseException;
import google.registry.flows.host.HostFlowUtils.HostNameNotNormalizedException;
import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException;
import google.registry.flows.host.HostFlowUtils.HostNameTooLongException;
import google.registry.flows.host.HostFlowUtils.HostNameTooShallowException;
import google.registry.flows.host.HostFlowUtils.InvalidHostNameException;
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainDoesNotExistException;
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainInPendingDeleteException;
import google.registry.flows.host.HostUpdateFlow.CannotAddIpToExternalHostException;
@@ -1259,7 +1259,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Host> {
@Test
void testFailure_renameToBadCharacter() throws Exception {
doFailingHostNameTest("foo bar", InvalidHostNameException.class);
doFailingHostNameTest("foo bar", BadHostNameCharacterException.class);
}
@Test
@@ -74,7 +74,9 @@ class RdapNameserverActionTest extends RdapActionBaseTestCase<RdapNameserverActi
.that(generateActualJson("invalid/host/name"))
.isEqualTo(
generateExpectedJsonError(
"invalid/host/name is not a valid nameserver: Invalid host name", 400));
"invalid/host/name is not a valid nameserver: Host names can only contain a-z, 0-9,"
+ " '.', '_', and '-'",
400));
assertThat(response.getStatus()).isEqualTo(400);
}
@@ -3,56 +3,56 @@
<check>
<host:check
xmlns:host="urn:ietf:params:xml:ns:host-1.0">
<host:name>www1.tld</host:name>
<host:name>www2.tld</host:name>
<host:name>www3.tld</host:name>
<host:name>www4.tld</host:name>
<host:name>www5.tld</host:name>
<host:name>www6.tld</host:name>
<host:name>www7.tld</host:name>
<host:name>www8.tld</host:name>
<host:name>www9.tld</host:name>
<host:name>www10.tld</host:name>
<host:name>www11.tld</host:name>
<host:name>www12.tld</host:name>
<host:name>www13.tld</host:name>
<host:name>www14.tld</host:name>
<host:name>www15.tld</host:name>
<host:name>www16.tld</host:name>
<host:name>www17.tld</host:name>
<host:name>www18.tld</host:name>
<host:name>www19.tld</host:name>
<host:name>www20.tld</host:name>
<host:name>www21.tld</host:name>
<host:name>www22.tld</host:name>
<host:name>www23.tld</host:name>
<host:name>www24.tld</host:name>
<host:name>www25.tld</host:name>
<host:name>www26.tld</host:name>
<host:name>www27.tld</host:name>
<host:name>www28.tld</host:name>
<host:name>www29.tld</host:name>
<host:name>www30.tld</host:name>
<host:name>www31.tld</host:name>
<host:name>www32.tld</host:name>
<host:name>www33.tld</host:name>
<host:name>www34.tld</host:name>
<host:name>www35.tld</host:name>
<host:name>www36.tld</host:name>
<host:name>www37.tld</host:name>
<host:name>www38.tld</host:name>
<host:name>www39.tld</host:name>
<host:name>www40.tld</host:name>
<host:name>www41.tld</host:name>
<host:name>www42.tld</host:name>
<host:name>www43.tld</host:name>
<host:name>www44.tld</host:name>
<host:name>www45.tld</host:name>
<host:name>www46.tld</host:name>
<host:name>www47.tld</host:name>
<host:name>www48.tld</host:name>
<host:name>www49.tld</host:name>
<host:name>www50.tld</host:name>
<host:name>ns1.www1.tld</host:name>
<host:name>ns1.www2.tld</host:name>
<host:name>ns1.www3.tld</host:name>
<host:name>ns1.www4.tld</host:name>
<host:name>ns1.www5.tld</host:name>
<host:name>ns1.www6.tld</host:name>
<host:name>ns1.www7.tld</host:name>
<host:name>ns1.www8.tld</host:name>
<host:name>ns1.www9.tld</host:name>
<host:name>ns1.www10.tld</host:name>
<host:name>ns1.www11.tld</host:name>
<host:name>ns1.www12.tld</host:name>
<host:name>ns1.www13.tld</host:name>
<host:name>ns1.www14.tld</host:name>
<host:name>ns1.www15.tld</host:name>
<host:name>ns1.www16.tld</host:name>
<host:name>ns1.www17.tld</host:name>
<host:name>ns1.www18.tld</host:name>
<host:name>ns1.www19.tld</host:name>
<host:name>ns1.www20.tld</host:name>
<host:name>ns1.www21.tld</host:name>
<host:name>ns1.www22.tld</host:name>
<host:name>ns1.www23.tld</host:name>
<host:name>ns1.www24.tld</host:name>
<host:name>ns1.www25.tld</host:name>
<host:name>ns1.www26.tld</host:name>
<host:name>ns1.www27.tld</host:name>
<host:name>ns1.www28.tld</host:name>
<host:name>ns1.www29.tld</host:name>
<host:name>ns1.www30.tld</host:name>
<host:name>ns1.www31.tld</host:name>
<host:name>ns1.www32.tld</host:name>
<host:name>ns1.www33.tld</host:name>
<host:name>ns1.www34.tld</host:name>
<host:name>ns1.www35.tld</host:name>
<host:name>ns1.www36.tld</host:name>
<host:name>ns1.www37.tld</host:name>
<host:name>ns1.www38.tld</host:name>
<host:name>ns1.www39.tld</host:name>
<host:name>ns1.www40.tld</host:name>
<host:name>ns1.www41.tld</host:name>
<host:name>ns1.www42.tld</host:name>
<host:name>ns1.www43.tld</host:name>
<host:name>ns1.www44.tld</host:name>
<host:name>ns1.www45.tld</host:name>
<host:name>ns1.www46.tld</host:name>
<host:name>ns1.www47.tld</host:name>
<host:name>ns1.www48.tld</host:name>
<host:name>ns1.www49.tld</host:name>
<host:name>ns1.www50.tld</host:name>
</host:check>
</check>
<clTRID>ABC-12345</clTRID>
@@ -0,0 +1,11 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<host:check
xmlns:host="urn:ietf:params:xml:ns:host-1.0">
<host:name>%HOSTNAME%</host:name>
</host:check>
</check>
<clTRID>ABC-12345</clTRID>
</command>
</epp>