Skip to content

Commit 389cdd1

Browse files
authored
Merge pull request #296 from onelogin/deprecate_algo
Support deprecation of sign and digest algorithms
2 parents 6e34b69 + 171a89e commit 389cdd1

File tree

12 files changed

+115
-8
lines changed

12 files changed

+115
-8
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ This version supports Python3. There is a separate version that only support Pyt
1414

1515
#### Warning ####
1616

17+
Version 1.13.0 sets sha256 and rsa-sha256 as default algorithms
18+
1719
Version 1.8.0 sets strict mode active by default
1820

1921
Update ``python3-saml`` to ``1.5.0``, this version includes security improvements for preventing XEE and Xpath Injections.
@@ -485,7 +487,12 @@ In addition to the required settings data (idp, sp), extra settings can be defin
485487

486488
// Specify if you want the SP to view assertions with duplicated Name or FriendlyName attributes to be valid
487489
// Defaults to false if not specified
488-
'allowRepeatAttributeName': false
490+
'allowRepeatAttributeName': false,
491+
492+
// If the toolkit receive a message signed with a
493+
// deprecated algoritm (defined at the constant class)
494+
// will raise an error and reject the message
495+
"rejectDeprecatedAlgorithm": true
489496
},
490497

491498
// Contact information template, it is recommended to suply a

demo-django/saml/advanced_settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"wantAssertionsEncrypted": false,
1313
"allowSingleLabelDomains": false,
1414
"signatureAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
15-
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
15+
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256",
16+
"rejectDeprecatedAlgorithm": true
1617
},
1718
"contactPerson": {
1819
"technical": {

demo-flask/saml/advanced_settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"wantAssertionsEncrypted": false,
1313
"allowSingleLabelDomains": false,
1414
"signatureAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
15-
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
15+
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256",
16+
"rejectDeprecatedAlgorithm": true
1617
},
1718
"contactPerson": {
1819
"technical": {

demo-tornado/saml/advanced_settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"wantAssertionsEncrypted": false,
1313
"allowSingleLabelDomains": false,
1414
"signatureAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
15-
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
15+
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256",
16+
"rejectDeprecatedAlgorithm": true
1617
},
1718
"contactPerson": {
1819
"technical": {

demo_pyramid/demo_pyramid/saml/advanced_settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"wantAssertionsEncrypted": false,
1313
"allowSingleLabelDomains": false,
1414
"signatureAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
15-
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
15+
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256",
16+
"rejectDeprecatedAlgorithm": true
1617
},
1718
"contactPerson": {
1819
"technical": {

src/onelogin/saml2/auth.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ def process_slo(self, keep_local_session=False, request_id=None, delete_session_
167167
self._errors.append('Signature validation failed. Logout Response rejected')
168168
elif not logout_response.is_valid(self._request_data, request_id):
169169
self._errors.append('invalid_logout_response')
170-
self._error_reason = logout_response.get_error()
171170
elif logout_response.get_status() != OneLogin_Saml2_Constants.STATUS_SUCCESS:
172171
self._errors.append('logout_not_success')
173172
else:
@@ -183,7 +182,6 @@ def process_slo(self, keep_local_session=False, request_id=None, delete_session_
183182
self._errors.append('Signature validation failed. Logout Request rejected')
184183
elif not logout_request.is_valid(self._request_data):
185184
self._errors.append('invalid_logout_request')
186-
self._error_reason = logout_request.get_error()
187185
else:
188186
if not keep_local_session:
189187
OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)
@@ -694,6 +692,15 @@ def _validate_signature(self, data, saml_type, raise_exceptions=False):
694692
if isinstance(sign_alg, bytes):
695693
sign_alg = sign_alg.decode('utf8')
696694

695+
security = self._settings.get_security_data()
696+
reject_deprecated_alg = security.get('rejectDeprecatedAlgorithm', False)
697+
if reject_deprecated_alg:
698+
if sign_alg in OneLogin_Saml2_Constants.DEPRECATED_ALGORITHMS:
699+
raise OneLogin_Saml2_ValidationError(
700+
'Deprecated signature algorithm found: %s' % sign_alg,
701+
OneLogin_Saml2_ValidationError.DEPRECATED_SIGNATURE_METHOD
702+
)
703+
697704
query_string = self._request_data.get('query_string')
698705
if query_string and self._request_data.get('validate_signature_from_qs'):
699706
signed_query = self._build_sign_query_from_qs(query_string, saml_type)

src/onelogin/saml2/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,6 @@ class OneLogin_Saml2_Constants(object):
114114
AES256_CBC = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'
115115
RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5'
116116
RSA_OAEP_MGF1P = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p'
117+
118+
# Define here the deprecated algorithms
119+
DEPRECATED_ALGORITHMS = [DSA_SHA1, RSA_SHA1, SHA1]

src/onelogin/saml2/errors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class OneLogin_Saml2_ValidationError(Exception):
110110
WRONG_NUMBER_OF_SIGNATURES = 43
111111
RESPONSE_EXPIRED = 44
112112
AUTHN_CONTEXT_MISMATCH = 45
113+
DEPRECATED_SIGNATURE_METHOD = 46
114+
DEPRECATED_DIGEST_METHOD = 47
113115

114116
def __init__(self, message, code=0, errors=None):
115117
"""

src/onelogin/saml2/response.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ def process_signed_elements(self):
653653
response_tag = '{%s}Response' % OneLogin_Saml2_Constants.NS_SAMLP
654654
assertion_tag = '{%s}Assertion' % OneLogin_Saml2_Constants.NS_SAML
655655

656+
security = self._settings.get_security_data()
657+
reject_deprecated_alg = security.get('rejectDeprecatedAlgorithm', False)
658+
656659
for sign_node in sign_nodes:
657660
signed_element = sign_node.getparent().tag
658661
if signed_element != response_tag and signed_element != assertion_tag:
@@ -695,6 +698,26 @@ def process_signed_elements(self):
695698
)
696699
verified_seis.append(sei)
697700

701+
# Check the signature and digest algorithm
702+
if reject_deprecated_alg:
703+
sig_method_node = OneLogin_Saml2_XML.query(sign_node, './/ds:SignatureMethod')
704+
if sig_method_node:
705+
sig_method = sig_method_node[0].get("Algorithm")
706+
if sig_method in OneLogin_Saml2_Constants.DEPRECATED_ALGORITHMS:
707+
raise OneLogin_Saml2_ValidationError(
708+
'Deprecated signature algorithm found: %s' % sig_method,
709+
OneLogin_Saml2_ValidationError.DEPRECATED_SIGNATURE_METHOD
710+
)
711+
712+
dig_method_node = OneLogin_Saml2_XML.query(sign_node, './/ds:DigestMethod')
713+
if dig_method_node:
714+
dig_method = dig_method_node[0].get("Algorithm")
715+
if dig_method in OneLogin_Saml2_Constants.DEPRECATED_ALGORITHMS:
716+
raise OneLogin_Saml2_ValidationError(
717+
'Deprecated digest algorithm found: %s' % dig_method,
718+
OneLogin_Saml2_ValidationError.DEPRECATED_DIGEST_METHOD
719+
)
720+
698721
signed_elements.append(signed_element)
699722

700723
if signed_elements:

src/onelogin/saml2/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ def _add_default_values(self):
312312
# Digest Algorithm
313313
self._security.setdefault('digestAlgorithm', OneLogin_Saml2_Constants.SHA256)
314314

315+
# Reject Deprecated Algorithms
316+
self._security.setdefault('rejectDeprecatedAlgorithm', False)
317+
315318
# AttributeStatement required by default
316319
self._security.setdefault('wantAttributeStatement', True)
317320

0 commit comments

Comments
 (0)