skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
March 1, 2024

GHSL-2023-121: SAML authentication bypass vulnerability in RobotsAndPencils/go-saml - CVE-2023-48703

Peter Stöckli

Coordinated Disclosure Timeline

Summary

A SAML authentication bypass vulnerability was found in the archived go-saml library from Robots and Pencils. This issue may lead to authentication bypasses in applications using go-saml for the signature verification of SAML assertions.

Note: The RobotsAndPencils/go-saml library is marked as archived and as such unmaintained. Projects still using it should move to another SAML library or alternatively remove support for SAML from their projects. Also see: “Workaround” for a temporary measure.

Product

RobotsAndPencils/go-saml (archived)

Tested Version

master

Details

Authentication bypass (GHSL-2023-121)

A SAML authentication bypass was found in the RobotsAndPencils/go-saml library. This is due to how the xmlsec1 command line tool is called internally to verify the signature of SAML assertions. When xmlsec1 is used without defining the enabled key data, the origin of the public key for the signature verification is, unfortunately, not restricted. That means an attacker can sign the SAML assertions themselves and provide the required public key (e.g. an RSA key) directly embedded in the SAML token.

A library using go-saml as seen in the sample code of the README to verify SAML tokens would call Validate on the SAML response. The Validate method itself calls VerifyResponseSignature, which itself calls the verify function inside of xmlsec.go. Under the hood the verify-function uses the xmlsec1 command line tool for verifying XML signatures:

func verify(xml string, publicCertPath string, id string) error {
	// snip
	_, err = exec.Command("xmlsec1", "--verify", "--pubkey-cert-pem", publicCertPath, "--id-attr:ID", id, samlXmlsecInput.Name()).CombinedOutput()
	if err != nil {
		return errors.New("error verifing signature: " + err.Error())
	}
	return nil
}

The xmlsec1 tool is called without parameters that define which public keys should be used for the verification of the signatures. This means xmlsec1 also considers public keys embedded into the XML file itself. In the case of a SAML token that means an attacker can self-sign their tokens and embed their own public key.

Workaround

Projects still using RobotsAndPencils/go-saml should move to another SAML library or alternatively remove support for SAML from their projects.

Should a project still use the RobotsAndPencils/go-saml library, it’s likely vulnerable if it uses go-saml to verify the signature of a SAML assertion. This specifically means if they have a code path that leads to a call of the private verify function. E.g. that means from VerifyResponseSignature or via Validate inside of authnresponse.go. Or from VerifyRequestSignature or via Validate inside of authnrequest.go.

The vulnerability can likely temporarily be fixed by forking the go-saml project and adding the command line argument --enabled-key-data and specifying a value such as x509 or raw-x509-cert when calling the xmlsec1 binary in the verify function. Compare how pysaml2 calls xmlsec1 or see example C code from xmlsec1. Please note that this workaround must be carefully tested before it can be used. Moving away from the go-saml library is still strongly recommended as it is unmaintained.

Sidenote regarding xmlsec1

The version 1.3.3 of xmlsec1 released in January 2024 disables KeyValue and DEREncodedKeyValue XML nodes by default. However, most Linux distributions ship older versions of xmlsec1 and specifying the enabled-key-data is recommended in any case.

Impact

This issue may lead to authentication bypasses in applications using go-saml for authentication purposes.

CVE

Credit

This issue was discovered and reported by GHSL team member @p- (Peter Stöckli).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-121 in any communication regarding this issue.