providers/saml: disallow idp-initiated SSO by default and validate Request ID

This commit is contained in:
Jens Langhammer
2020-09-12 00:53:38 +02:00
parent c2ebaa7f64
commit ca0ba85023
10 changed files with 138 additions and 47 deletions

View File

@ -18,6 +18,7 @@ from passbook.lib.utils.urls import redirect_with_qs
from passbook.policies.utils import delete_none_keys
from passbook.providers.saml.utils.encoding import decode_base64_and_inflate
from passbook.sources.saml.exceptions import (
MismatchedRequestID,
MissingSAMLResponse,
UnsupportedNameIDFormat,
)
@ -29,6 +30,7 @@ from passbook.sources.saml.processors.constants import (
SAML_NAME_ID_FORMAT_WINDOWS,
SAML_NAME_ID_FORMAT_X509,
)
from passbook.sources.saml.processors.request import SESSION_REQUEST_ID
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from passbook.stages.prompt.stage import PLAN_CONTEXT_PROMPT
@ -59,8 +61,9 @@ class ResponseProcessor:
# Check if response is compressed, b64 decode it
self._root_xml = decode_base64_and_inflate(raw_response)
self._root = ElementTree.fromstring(self._root_xml)
# Verify signed XML
self._verify_signed()
self._verify_request_id(request)
def _verify_signed(self):
"""Verify SAML Response's Signature"""
@ -70,6 +73,16 @@ class ResponseProcessor:
)
LOGGER.debug("Successfully verified signautre")
def _verify_request_id(self, request: HttpRequest):
if self._source.allow_idp_initiated:
return
if SESSION_REQUEST_ID not in request.session or "ID" not in self._root.attrib:
raise MismatchedRequestID(
"Missing request ID and IdP-initiated Logins are not allowed"
)
if request.session[SESSION_REQUEST_ID] != self._root.attrib["ID"]:
raise MismatchedRequestID("Mismatched request ID")
def _handle_name_id_transient(self, request: HttpRequest) -> HttpResponse:
"""Handle a NameID with the Format of Transient. This is a bit more complex than other
formats, as we need to create a temporary User that is used in the session. This