diff --git a/content/exsaml.xqm b/content/exsaml.xqm index 5ddc751..14b3cbc 100644 --- a/content/exsaml.xqm +++ b/content/exsaml.xqm @@ -313,8 +313,9 @@ declare function exsaml:process-saml-response-post($cid as xs:string) { declare %private function exsaml:validate-saml-response($cid as xs:string, $resp as element(samlp:Response)) as element(exsaml:funcret) { let $log := exsaml:log("info", $cid, "validate-saml-response") - let $as := $resp/saml:Assertion - let $sig := $resp/ds:Signature + let $as as element(saml:Assertion)? := $resp/saml:Assertion + let $sig as element(ds:Signature)? := $resp/ds:Signature + let $reqid as xs:string? := $resp/@InResponseTo ! xs:string(.) return (: check SAML response status. there are ~20 failure codes, check @@ -338,6 +339,11 @@ declare %private function exsaml:validate-saml-response($cid as xs:string, $resp (: else if (boolean($sig) and not(exsaml:verify-response-signature($cid, $sig))) then :) (: :) + (: verify Response/@InResponseTo is present in the SAML response :) + else if (fn:exists($reqid) and not(exsaml:check-authnreqid($reqid))) + then + + (: must contain at least one assertion :) else if (empty($as)) then @@ -365,10 +371,10 @@ declare %private function exsaml:validate-saml-assertion($cid as xs:string, $ass else let $log := exsaml:log("info", $cid, "validate-saml-assertion: " || fn:serialize($assertion)) - let $sig := $assertion/ds:Signature - let $subj-confirm-data := $assertion/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData - let $conds := $assertion/saml:Conditions - let $reqid := $subj-confirm-data/@InResponseTo + let $sig as element(ds:Signature)? := $assertion/ds:Signature + let $subj-confirm-data as element(saml:SubjectConfirmationData)? := $assertion/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData + let $conds as element(saml:Conditions)? := $assertion/saml:Conditions + let $reqid as xs:string? := $subj-confirm-data/@InResponseTo ! xs:string(.) return (: check that "Issuer" is the expected IDP. Not stricty required by @@ -388,12 +394,12 @@ declare %private function exsaml:validate-saml-assertion($cid as xs:string, $ass (: maybe verify SubjectConfirmation/@Method :) (: verify SubjectConfirmationData/@Recipient is SP URL ($sp-uri) :) - else if (not($subj-confirm-data/@Recipient = $exsaml:sp-uri)) + else if (fn:exists($subj-confirm-data/@Recipient) and not($subj-confirm-data/@Recipient = $exsaml:sp-uri)) then (: verify SubjectConfirmationData/@NotOnOrAfter is not later than now :) - else if (xs:dateTime(fn:current-dateTime()) ge xs:dateTime($subj-confirm-data/@NotOnOrAfter)) + else if (fn:exists($subj-confirm-data/@NotOnOrAfter) and xs:dateTime(fn:current-dateTime()) ge xs:dateTime($subj-confirm-data/@NotOnOrAfter)) then