Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Adopt AsURLStringValidator
iay committed Jul 8, 2024
1 parent 2f01d30 commit 443cfa3
Showing 4 changed files with 148 additions and 143 deletions.
98 changes: 0 additions & 98 deletions mdx/_rules/check_mdui.xsl
@@ -18,7 +18,6 @@
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
xmlns:mdxURL="xalan://uk.ac.sdss.xalan.md.URLchecker"
xmlns:set="http://exslt.org/sets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
@@ -131,103 +130,6 @@
</xsl:if>
</xsl:template>


<!--
Section 2.1.5 Element <mdui:Logo>
-->
<xsl:template match="mdui:Logo">
<!--
Logos must never include un-encoded line breaks. This makes them invalid
URLs, but also causes problems with the Shibboleth CDS.
-->
<xsl:if test="contains(., '&#10;')">
<xsl:call-template name="error">
<xsl:with-param name="m">mdui:Logo contains line break</xsl:with-param>
</xsl:call-template>
</xsl:if>

<xsl:if test="contains(., '&#xA0;')">
<xsl:call-template name="error">
<xsl:with-param name="m">mdui:Logo contains non-breaking space</xsl:with-param>
</xsl:call-template>
</xsl:if>

<!--
Require that the URL starts with https://
This is a SHOULD in the specification; we treat it as a MUST here.
Exception: allow data: URIs as well. The spec is currently
ambiguous about this, clarification ticket is here:
https://tools.oasis-open.org/issues/browse/SECURITY-24
-->
<xsl:if test="not(starts-with(., 'https://'))">
<xsl:if test="not(starts-with(., 'data:'))">
<xsl:call-template name="error">
<xsl:with-param name="m">mdui:Logo URL does not start with https://</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:if>

<!--
Check for <mdui:Logo> elements that aren't valid URLs.
Again, explicitly permit anything starting with 'data:', so that the
only validity test we're performing on data: URLs is the "no newline" rule.
-->
<xsl:if test="mdxURL:invalidURL(.)">
<xsl:if test="not(starts-with(., 'data:'))">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:text>mdui:</xsl:text>
<xsl:value-of select='local-name()'/>
<xsl:text> '</xsl:text>
<xsl:value-of select="."/>
<xsl:text>' is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(.)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>

<!--
Section 2.1.6 Element <mdui:InformationURL>
Require that the URL is valid.
-->
<xsl:template match="mdui:InformationURL[mdxURL:invalidURL(.)]">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:text>mdui:</xsl:text>
<xsl:value-of select='local-name()'/>
<xsl:text> '</xsl:text>
<xsl:value-of select="."/>
<xsl:text>' is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(.)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>

<!--
Section 2.1.7 Element <mdui:PrivacyStatementURL>
Require that the URL is valid.
-->
<xsl:template match="mdui:PrivacyStatementURL[mdxURL:invalidURL(.)]">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:text>mdui:</xsl:text>
<xsl:value-of select='local-name()'/>
<xsl:text> '</xsl:text>
<xsl:value-of select="."/>
<xsl:text>' is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(.)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>

<!--
Section 2.2
45 changes: 0 additions & 45 deletions mdx/_rules/check_saml2meta.xsl
@@ -11,7 +11,6 @@
-->
<xsl:stylesheet version="1.0"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:mdxURL="xalan://uk.ac.sdss.xalan.md.URLchecker"
xmlns:set="http://exslt.org/sets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
@@ -66,48 +65,4 @@
<xsl:apply-templates/>
</xsl:template>


<!--
Check for Location attributes that aren't valid URLs.
-->
<xsl:template match="md:*[@Location and mdxURL:invalidURL(@Location)]">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:value-of select='local-name()'/>
<xsl:text> Location is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(@Location)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>


<!--
Check for ResponseLocation attributes that aren't valid URLs.
-->
<xsl:template match="md:*[@ResponseLocation and mdxURL:invalidURL(@ResponseLocation)]">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:value-of select='local-name()'/>
<xsl:text> ResponseLocation is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(@ResponseLocation)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>


<!--
Check for OrganizationURLs that aren't valid URLs.
-->
<xsl:template match="md:OrganizationURL[mdxURL:invalidURL(.)]">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:text>OrganizationURL '</xsl:text>
<xsl:value-of select="."/>
<xsl:text>' is not a valid URL: </xsl:text>
<xsl:value-of select="mdxURL:whyInvalid(.)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>


</xsl:stylesheet>
10 changes: 10 additions & 0 deletions mdx/common-beans.xml
@@ -714,16 +714,26 @@
QNames for SAML metadata elements.
-->
<bean id="md-AdditionalMetadataLocation" parent="QName" c:_0-ref="md_namespace" c:_1="AdditionalMetadataLocation"/>
<bean id="md-ArtifactResolutionService" parent="QName" c:_0-ref="md_namespace" c:_1="ArtifactResolutionService"/>
<bean id="md-AssertionConsumerService" parent="QName" c:_0-ref="md_namespace" c:_1="AssertionConsumerService"/>
<bean id="md-AssertionIDRequestService" parent="QName" c:_0-ref="md_namespace" c:_1="AssertionIDRequestService"/>
<bean id="md-AttributeProfile" parent="QName" c:_0-ref="md_namespace" c:_1="AttributeProfile"/>
<bean id="md-AttributeService" parent="QName" c:_0-ref="md_namespace" c:_1="AttributeService"/>
<bean id="md-AuthnQueryService" parent="QName" c:_0-ref="md_namespace" c:_1="AuthnQueryService"/>
<bean id="md-AuthzService" parent="QName" c:_0-ref="md_namespace" c:_1="AuthzService"/>
<bean id="md-Company" parent="QName" c:_0-ref="md_namespace" c:_1="Company"/>
<bean id="md-EmailAddress" parent="QName" c:_0-ref="md_namespace" c:_1="EmailAddress"/>
<bean id="md-GivenName" parent="QName" c:_0-ref="md_namespace" c:_1="GivenName"/>
<bean id="md-ManageNameIDService" parent="QName" c:_0-ref="md_namespace" c:_1="ManageNameIDService"/>
<bean id="md-NameIDFormat" parent="QName" c:_0-ref="md_namespace" c:_1="NameIDFormat"/>
<bean id="md-NameIDMappingService" parent="QName" c:_0-ref="md_namespace" c:_1="NameIDMappingService"/>
<bean id="md-OrganizationDisplayName" parent="QName" c:_0-ref="md_namespace" c:_1="OrganizationDisplayName"/>
<bean id="md-OrganizationName" parent="QName" c:_0-ref="md_namespace" c:_1="OrganizationName"/>
<bean id="md-OrganizationURL" parent="QName" c:_0-ref="md_namespace" c:_1="OrganizationURL"/>
<bean id="md-ServiceDescription" parent="QName" c:_0-ref="md_namespace" c:_1="ServiceDescription"/>
<bean id="md-ServiceName" parent="QName" c:_0-ref="md_namespace" c:_1="ServiceName"/>
<bean id="md-SingleLogoutService" parent="QName" c:_0-ref="md_namespace" c:_1="SingleLogoutService"/>
<bean id="md-SingleSignOnService" parent="QName" c:_0-ref="md_namespace" c:_1="SingleSignOnService"/>
<bean id="md-SurName" parent="QName" c:_0-ref="md_namespace" c:_1="SurName"/>
<bean id="md-TelephoneNumber" parent="QName" c:_0-ref="md_namespace" c:_1="TelephoneNumber"/>

138 changes: 138 additions & 0 deletions mdx/validation-beans.xml
@@ -12,6 +12,63 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<!--
***************************************
*** ***
*** U R L V A L I D A T I O N ***
*** ***
***************************************
-->

<!--
Shared validator beans.
The beans in this section have both "id" values by which they can
be referenced in Spring configuration, but also simpler "p:id"
values to simplify their contributions to error messages
composed from a series of component ID values.
-->

<!-- Reject "https://host:/xxx" because libxml2 has issues with that. -->
<bean id="validate_url_port" p:id="port" parent="mda.EmptyPortURLValidator"/>

<!-- Reject "https:///xxx" because it lacks an authority entirely. -->
<bean id="validate_url_host" p:id="host" parent="mda.MissingHostURLValidator"/>

<!-- Reject URLs which don't have an https:// protocol. -->
<bean id="validate_url_https" p:id="https" parent="mda.HTTPSProtocolURLValidator"/>

<!--
validate_url
Validate a string as a URL. Includes checking for port and host
issues.
-->
<bean id="validate_url" p:id="url" parent="mda.AsURLStringValidator">
<property name="validators">
<list>
<ref bean="validate_url_port"/>
<ref bean="validate_url_host"/>
</list>
</property>
</bean>

<!--
validate_https_url
Validate a string as a https:// URL. Includes checking for port and host
issues.
-->
<bean id="validate_https_url" p:id="url" parent="mda.AsURLStringValidator">
<property name="validators">
<list>
<ref bean="validate_url_https"/>
<ref bean="validate_url_port"/>
<ref bean="validate_url_host"/>
</list>
</property>
</bean>

<!--
***********************************
*** ***
@@ -220,6 +277,29 @@
<bean id="check_mdui_xslt" parent="mda.XSLValidationStage"
p:XSLResource="classpath:_rules/check_mdui.xsl"/>

<!--
check_mdui_logo_url
Section 2.1.5: Check the URL value of mdui:Logo elements.
-->
<bean id="check_mdui_logo_url" parent="mda.StringElementValidationStage">
<property name="elementName" ref="mdui-Logo"/>
<property name="validators">
<list>
<bean p:id="newline" parent="mda.RejectStringRegexValidator"
p:regex=".*\n.*"
p:message="mdui:Logo contains line break" />
<bean p:id="nbs" parent="mda.RejectStringRegexValidator"
p:regex=".*\u00a0.*"
p:message="mdui:Logo contains non-breaking space" />
<!-- Accept data: URLs with no further scrutiny. -->
<bean parent="mda.AcceptStringRegexValidator"
p:regex="data:.*"/>
<ref bean="validate_https_url"/>
</list>
</property>
</bean>

<!--
check_mdui_logo_length
@@ -235,6 +315,21 @@
</property>
</bean>

<!--
check_mdui_urls
Check URL values of mdui:* elements other than mdui:Logo.
-->
<bean id="check_mdui_urls" parent="mda.StringElementValidationStage"
p:validators-ref="validate_url">
<property name="elementNames">
<set>
<ref bean="mdui-InformationURL"/>
<ref bean="mdui-PrivacyStatementURL"/>
</set>
</property>
</bean>

<!--
check_mdui
@@ -246,6 +341,8 @@
<ref bean="check_mdui_iphint"/>
<ref bean="check_mdui_xslt"/>
<ref bean="check_mdui_logo_length"/>
<ref bean="check_mdui_logo_url"/>
<ref bean="check_mdui_urls"/>
</list>
</property>
</bean>
@@ -630,6 +727,45 @@
<bean id="check_saml2meta" parent="mda.XSLValidationStage"
p:XSLResource="classpath:_rules/check_saml2meta.xsl"/>

<!--
check_saml2meta_urlattrs
Check URL values of various attributes on md:* elements.
-->
<bean id="check_saml2meta_urlattrs" parent="mda.StringAttributeValidationStage"
p:id="saml2meta" p:validators-ref="validate_url">
<property name="elementNames">
<set>
<ref bean="md-AdditionalMetadataLocation"/>
<ref bean="md-AssertionConsumerService"/>
<ref bean="md-AssertionIDRequestService"/>
<ref bean="md-ArtifactResolutionService"/>
<ref bean="md-AttributeService"/>
<ref bean="md-AuthnQueryService"/>
<ref bean="md-AuthzService"/>
<ref bean="md-ManageNameIDService"/>
<ref bean="md-NameIDMappingService"/>
<ref bean="md-SingleLogoutService"/>
<ref bean="md-SingleSignOnService"/>
</set>
</property>
<property name="attributeNames">
<set>
<bean parent="QName" c:_0="Location"/>
<bean parent="QName" c:_0="ResponseLocation"/>
</set>
</property>
</bean>

<!--
check_saml2meta_urls
Check URL values of md:* elements.
-->
<bean id="check_saml2meta_urls" parent="mda.StringElementValidationStage"
p:id="saml2meta" p:validators-ref="validate_url"
p:elementName-ref="md-OrganizationURL"/>

<!--
check_saml_strings
-->
@@ -719,6 +855,8 @@
<ref bean="check_saml2_lang"/>
<ref bean="check_saml2int"/>
<ref bean="check_saml2meta"/>
<ref bean="check_saml2meta_urlattrs"/>
<ref bean="check_saml2meta_urls"/>
<ref bean="check_saml_strings"/>
<ref bean="check_shib_noregscope"/>
<ref bean="check_shibboleth"/>

0 comments on commit 443cfa3

Please sign in to comment.