[PATCH] Backport fix of CVE-2009-3300 for OpenSAML2

Ferenc Wagner wferi at niif.hu
Mon Nov 23 19:36:41 UTC 2009


Use a static function instead of bumping the soname of the XMLTooling
and OpenSAML libraries as the original upstream fix did.  This also entails
hardwiring the newly introduced allowedSchemes configuration option to HTTP and
HTTPS only.
---
 debian/changelog                                 |    6 +++++
 saml/SAMLConfig.cpp                              |   26 ++++++++++++++++++++++
 saml/internal.h                                  |    1 +
 saml/saml1/binding/impl/SAML1POSTEncoder.cpp     |    8 +++---
 saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp |    5 ++-
 saml/saml2/binding/impl/SAML2POSTEncoder.cpp     |    8 +++---
 6 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index c7721eb..0093168 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+opensaml2 (2.0-2+lenny2) stable-security; urgency=high
+
+  * SECURITY: Backport fix for CVE-2009-3300
+
+ -- Ferenc Wagner <wferi at niif.hu>  Mon, 23 Nov 2009 20:41:32 +0100
+
 opensaml2 (2.0-2+lenny1) stable-security; urgency=high
 
   * SECURITY: Correctly honor the "use" attribute of <KeyDescriptor> SAML
diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp
index f5082b8..02abf13 100644
--- a/saml/SAMLConfig.cpp
+++ b/saml/SAMLConfig.cpp
@@ -304,3 +304,29 @@ void opensaml::annotateException(XMLToolingException* e, const RoleDescriptor* r
     if (rethrow)
         e->raise();
 }
+
+// Instead of http://svn.middleware.georgetown.edu/view/cpp-xmltooling?view=rev&revision=676
+void __attribute__ ((visibility ("hidden")))
+opensaml::HTTPResponse_sanitizeURL(const char* url)
+{
+    const char* ch;
+    const char* allowedSchemes[] = { "http", "https", NULL };
+    const char** sch = allowedSchemes;
+
+    for (ch=url; *ch; ++ch) {
+        if (iscntrl(*ch))
+            throw IOException("URL contained a control character.");
+    }
+
+    ch = strchr(url, ':');
+    if (!ch)
+        throw IOException("URL is malformed.");
+    std::string s(url, ch - url);
+
+    while (*sch) {
+        if (!strcasecmp(s.c_str(), *sch++))
+            return;
+    }
+
+    throw IOException("URL contains invalid scheme ($1).", params(1, s.c_str()));
+}
diff --git a/saml/internal.h b/saml/internal.h
index e4d5bcc..829c28c 100644
--- a/saml/internal.h
+++ b/saml/internal.h
@@ -102,6 +102,7 @@ namespace opensaml {
     };
     /// @endcond
 
+    void __attribute__ ((visibility ("hidden"))) HTTPResponse_sanitizeURL(const char* url);
 };
 
 #endif /* __saml_internal_h__ */
diff --git a/saml/saml1/binding/impl/SAML1POSTEncoder.cpp b/saml/saml1/binding/impl/SAML1POSTEncoder.cpp
index 2b0107b..89d49df 100644
--- a/saml/saml1/binding/impl/SAML1POSTEncoder.cpp
+++ b/saml/saml1/binding/impl/SAML1POSTEncoder.cpp
@@ -104,12 +104,12 @@ long SAML1POSTEncoder::encode(
     xmltooling::NDC ndc("encode");
 #endif
     Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML1POST");
+    log.debug("validating input");
 
     TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine();
-    if (!engine)
-        throw BindingException("Encoding response using POST requires a TemplateEngine instance.");
-    
-    log.debug("validating input");
+    if (!engine || !destination)
+        throw BindingException("Encoding response using POST requires a TemplateEngine instance and a destination.");
+    HTTPResponse_sanitizeURL(destination);
     if (xmlObject->getParent())
         throw BindingException("Cannot encode XML content with parent.");
     Response* response = dynamic_cast<Response*>(xmlObject);
diff --git a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp
index a4dd248..beb362d 100644
--- a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp
+++ b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp
@@ -111,14 +111,14 @@ long SAML2ArtifactEncoder::encode(
     xmltooling::NDC ndc("encode");
 #endif
     Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2Artifact");
-
     log.debug("validating input");
+    if (!destination)
+        throw BindingException("Encoding response requires a destination.");
     HTTPResponse* httpResponse=dynamic_cast<HTTPResponse*>(&genericResponse);
     if (!httpResponse)
         throw BindingException("Unable to cast response interface to HTTPResponse type.");
     if (relayState && strlen(relayState)>80)
         throw BindingException("RelayState cannot exceed 80 bytes in length.");
-    
     if (xmlObject->getParent())
         throw BindingException("Cannot encode XML content with parent.");
 
@@ -190,6 +190,7 @@ long SAML2ArtifactEncoder::encode(
         TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine();
         if (!engine)
             throw BindingException("Encoding artifact using POST requires a TemplateEngine instance.");
+        HTTPResponse_sanitizeURL(destination);
         ifstream infile(m_template.c_str());
         if (!infile)
             throw BindingException("Failed to open HTML template for POST response ($1).", params(1,m_template.c_str()));
diff --git a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp
index 8f122e0..1aa09ec 100644
--- a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp
+++ b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp
@@ -109,12 +109,12 @@ long SAML2POSTEncoder::encode(
     xmltooling::NDC ndc("encode");
 #endif
     Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2POST");
+    log.debug("validating input");
 
     TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine();
-    if (!engine)
-        throw BindingException("Encoding message using POST requires a TemplateEngine instance.");
-    
-    log.debug("validating input");
+    if (!engine || !destination)
+        throw BindingException("Encoding message using POST requires a TemplateEngine instance and a destination.");
+    HTTPResponse_sanitizeURL(destination);
     if (xmlObject->getParent())
         throw BindingException("Cannot encode XML content with parent.");
     
-- 
1.5.6.5


--=-=-=
Content-Type: text/x-diff
Content-Disposition: inline;
 filename=0001-Backport-fix-of-CVE-2009-3300-for-SP.patch
Content-Transfer-Encoding: 8bit



More information about the Pkg-shibboleth-devel mailing list