fix: keep empty and valueless SAML attributes in profile.attributes#413
fix: keep empty and valueless SAML attributes in profile.attributes#413arpitjain099 wants to merge 1 commit into
Conversation
An attribute with no AttributeValue child (e.g. <Attribute Name="x"/>) was dropped from profile.attributes entirely, and an attribute with an empty AttributeValue (e.g. <AttributeValue/> for an xs:string) was returned as undefined. Both lose information: a consumer cannot tell a valueless attribute apart from one the IdP never sent. Per SAML Core section 1219 an attribute that exists with no values keeps the attribute and is now represented as null. Per section 1246 an empty AttributeValue is the empty string and is now represented as "" instead of undefined. Populated and multi-valued attributes are unchanged. Fixes node-saml#227 Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR refines SAML attribute parsing to distinguish between missing attributes and attributes that exist but lack values. Empty AttributeValue nodes now map to empty strings, and Attribute elements without AttributeValue children now record null values instead of being skipped entirely. ChangesSAML Attribute Value Representation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Fixes #227
Problem
When a SAML assertion carries an attribute that exists but has no real value, node-saml currently loses that information in
profile.attributes:AttributeValuechild at all, for example<saml2:Attribute Name="employee_id"/>, is dropped fromprofile.attributesentirely. Google Workspace emits these in the wild.AttributeValueis present but empty, for example<AttributeValue/>withxsi:type="xs:string", comes back asundefined.In both cases a consumer cannot tell a valueless attribute apart from one the IdP never sent:
{}and{ employee_id: null }should not collapse to the same thing.The SAML 2.0 Core spec is explicit about both shapes:
<AttributeStatement>, if the SAML attribute exists but has no values, the<AttributeValue>element MUST be omitted. The attribute itself still exists.<AttributeValue>element MUST be empty (serialized as<AttributeValue/>).Fix
src/saml.tsattribute extraction now keeps these attributes instead of discarding them:AttributeValuechild is represented asnull(the attribute exists, no value).AttributeValueis represented as the empty string""rather thanundefined, matching thexs:stringempty-value semantics from section 1246.Populated single-value, object-valued (nested
NameID), and multi-valued attributes are parsed exactly as before. The single-value-versus-array branch is untouched.Before / after
For
<saml2:Attribute Name="employee_id"/>:profile.attributesdoes not containemployee_idprofile.attributes.employee_id === nullFor
<saml2:Attribute Name="x"><AttributeValue/></saml2:Attribute>:profile.attributes.x === undefinedprofile.attributes.x === ""Tests
Added two tests under the
validatePostResponse xml signature checkssuite, including the exact null-attribute case from the issue:Both fail on
master(the first throwsexpected {} to have property 'attributeName', the secondexpected undefined to equal '') and pass with this change. I also updated the two existing tests that asserted the old drop/undefined behavior, since the issue calls that behavior out as incorrect:accept response with an attributeStatement element without attributeValuenow expectsevilcorp.rolesto be present asnull.An undefined value given with an object should still be undefinedis renamed toAn empty AttributeValue should be an empty stringand asserts"".Full suite is green (273 passing), and lint and prettier pass on the changed files.
Compatibility note
This is a behavior change for consumers that relied on valueless attributes being absent or
undefined, so it fits a semver-major release. That lines up with the breaking-change release discussed in the issue thread.Summary by CodeRabbit
Bug Fixes
nullvalues instead of omitting them.AttributeValuenodes.Tests