[PATCH] Backport fix for CVE-2009-3300

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.  This way the security fix is more palatable for Debian.
---
 debian/changelog                                 |    6 ++++
 saml/internal.h                                  |   28 ++++++++++++++++++++++
 saml/saml1/binding/impl/SAML1POSTEncoder.cpp     |    8 +++---
 saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp |    5 ++-
 saml/saml2/binding/impl/SAML2POSTEncoder.cpp     |    8 +++---
 5 files changed, 45 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/internal.h b/saml/internal.h
index e4d5bcc..9eadb05 100644
--- a/saml/internal.h
+++ b/saml/internal.h
@@ -104,4 +104,32 @@ namespace opensaml {
 
 };
 
+// Instead of http://svn.middleware.georgetown.edu/view/cpp-xmltooling?view=rev&revision=676
+
+using namespace xmltooling;
+
+static void 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()));
+}
+
 #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


--=-=-=--



More information about the Pkg-shibboleth-devel mailing list