See how simplesamlphp compares to other vendors in security performance
Summary
SimpleSAMLphp's SAML SP ACS path does not enforce the IdP selected for an SP-initiated login. If a saved SP state contains ExpectedIssuer = IdP A, but the ACS receives a valid response from IdP B, the code logs a warning and continues processing instead of rejecting the response.
That behavior becomes security-relevant when combined with the response-processing rule that accepts an unsigned samlp:Response/@InResponseTo outside the signed assertion whenever the signed assertion's SubjectConfirmationData does not carry its own InResponseTo. A response issued by one trusted IdP can therefore be bound to SP state created for another IdP.
Impact
In a multi-IdP deployment, a lower-trust IdP can satisfy SP state created for a different expected IdP. This can bypass an SP flow that intentionally routes the user to a specific IdP, including deployments that set enableunsolicited to false to prevent IdP-initiated logins.
The impact is highest when the SP trusts multiple IdPs with different assurance levels, tenant boundaries, or attribute namespaces, and application authorization depends on the selected/expected IdP. In those deployments this is an authentication/authorization bypass candidate. Impact strongly depends on whether an attacker can obtain a signed IdP-initiated assertion from a lower-trust trusted IdP and whether the downstream application maps identifiers globally.
Summary There's a signature confusion attack in the HTTPRedirect binding. An attacker with any signed SAMLResponse via the HTTP-Redirect binding can cause the application to accept an unsigned message.
I believe that it exists for v4 only. I have not yet developed a PoC.
V5 is well designed and instead builds the signed query from the same message that will be consumed. Details
What is verified The data['SignedQuery'] is the string that will be verified by the public key.
It is defined here: https://github.com/simplesamlphp/saml2/blob/9545abd0d9d48388f2fa00469c5c1e0294f0303e/src/SAML2/HTTPRedirect.php#L178-L217
THe code will iterate through each parameter name. Notably, sigQuery is overridden each time when processing, making the last of SAMLRequest/SAMLResponse used for sigQuery.
For example, given:
SAMLRequest=a&SAMLResponse=idpsigned
SAMLResponse=idpsigned will be set as sigQuery, then later verified
What is actually processed
Processing uses SAMLRequest parameter value first, (if it exists) then SAMLResponse:
https://github.com/simplesamlphp/saml2/blob/9545abd0d9d48388f2fa00469c5c1e0294f0303e/src/SAML2/HTTPRedirect.php#L104-L113
Given this, the contents that are processed might not be the same as the data that is actually verified.
Exploiting Suppose an attacker has a signed HTTP Redirect binding from IdP, say a signed logout response. :
SAMLResponse=idpsigned&RelayState=...&SigAlg=...&Signature
Then an attacker can append SAMLRequest in front:
SAMLRequest=unverifieddata&SAMLResponse=idpsigned&RelayState=...&SigAlg=...&Signature=..
SimpleSAMLPhp will only verify the SAMLResponse, but will actually use the SAMLRequest contents. The impact here is increased because there's no checks that SAMLRequest actually contains a Request, it could instead contain an Response, which allows the attacker to effectively impersonate any user within the SP.
IdPs
Microsoft Azure AD/Entra (and likely ADFS) signs the LogoutResponse via this SimpleSign format in HTTP Redirect binding. If an attacker logs out of Entra, they will be able to extract a valid Signature.
Attached is an HTTP Request when an I initiated a SLO request from the service provider to the IdP (entra). Then IdP POSTed this SAMLResponse with HTTP Redirect binding signature, via the user browser to the SP. It should be possible to carry out the described attack with this.
https://webhook.site/c6038292-6ef5-46ac-973d-d7c25520ec48/logout?SAMLResponse=fVJNa%2bMwEP0rRndZtmw5tnAMy%2fYSaC9N6aGXIsmjVMTRGI9M%2bvObdeihsPQ4w7x5HzM9mcs060c84ZqegWaMBNnhYc%2fejS1UW1TAnVU7XldK8s7JkcvOd60Db3zTsewVFgoY90zmBcsORCscIiUT061VyJqXJS%2fbl7LRUmrZ5mXdvLHsASiFaNKG%2fEhpJi3EFewH4jmnkEC4pqha2UnegFe8bozj3a4a%2bbhzUilZgKtbMW2yb7TxW%2foL7lkM9hTC2XnEOPvZXjDECb2N1lh7mvBsp%2bnsErDs8zJF0lsEe7YuUaOhQDqaC5BOTh%2f%2fPD3qmzE9L5jQ4cSGfrO43KG%2fgwwRLP8ssuHbIiXKryGOeKU8QhLSVN7WteejV8Bru%2bt4WynFbwE3bdVV5ahG0Ys759Dfj3VMJq30s%2fqLI2SvZlrhd020Tevj6hwQMTH04udS8b%2bHGL4A&Signature=Z%2f7gIPv7Gkgvqtwo0bzgXyum9IjHMfP0zTYuNbl%2fBUGlQ%2fU%2bbOZGZJ6Rk9wLUyvNQ5XlZRxZrfESNA%2bn0CVyIedsg9GxQKTi7VqPTJFJqEIP1BZaEpYYP3%2f6sFfLxfTMKecJoQdxnDE5Malte1hMj2UujWnLXOnp0CgO%2f%2fU2K52SoGckIzNDRB%2fJ6%2fysTn%2bDjBrmgdro%2fgdTyby9%2f3vm8dzY8pUkRCgMjlimShrZxr5U33wQvwPLIXlDgActr91RUtWKE0k8sy%2brshrK9DKLPo8AdTLk7NYhjSWdF7OG7uqgEeEo470tacqQuA09E0qDh8CWS%2bycLJijiGYWVyQa4Q%3d%3d&SigAlg=http%3a%2f%2fwww.w3.org%2f2001%2f04%2fxmldsig-more%23rsa-sha256
Log injection in SimpleSAMLphp before version 1.18.4. The www/erroreport.php script, which receives error reports and sends them via email to the system administrator, did not properly sanitize the report identifier obtained from the request. This allows an attacker, under specific circumstances, to inject new log lines by manually crafting this report ID. When configured to use the file logging handler, SimpleSAMLphp will output all its logs by appending each log line to a given file. Since the reportID parameter received in a request sent to www/errorreport.php was not properly sanitized, it was possible to inject newline characters into it, effectively allowing a malicious user to inject new log lines with arbitrary content.
Cross-site scripting in SimpleSAMLphp before version 1.18.4. The www/erroreport.php script allows error reports to be submitted and sent to the system administrator. Starting with SimpleSAMLphp 1.18.0, a new SimpleSAML\Utils\EMail class was introduced to handle sending emails, implemented as a wrapper of an external dependency. This new wrapper allows us to use Twig templates in order to create the email sent with an error report. Since Twig provides automatic escaping of variables, manual escaping of the free-text field in www/errorreport.php was removed to avoid double escaping. However, for those not using the new user interface yet, an email template is hardcoded into the class itself in plain PHP. Since no escaping is provided in this template, it is then possible to inject HTML inside the template by manually crafting the contents of the free-text field.
HTTPRedirect.php in the saml2 library in SimpleSAMLphp before 1.15.4 has an incorrect check of return values in the signature validation utilities, allowing an attacker to get invalid signatures accepted as valid by forcing an error during validation. This occurs because of a dependency on PHP functionality that interprets a -1 error code as a true boolean value.
Incorrect signature validation
Open redirection protection bypass
The sqlauth module in SimpleSAMLphp before 1.15.2 relies on the MySQL utf8 charset, which truncates queries upon encountering four-byte characters. There might be a scenario in which this allows remote attackers to bypass intended access restrictions.
Denial of Service in timestamp validation function
Summary
The logout endpoint accepts a url query parameter to redirect to. casserver treats that url as trusted, and either (depending on configuration) redirects the browser there, or shows a "you've been logged out" page with a link to continue to that url.
There are a number of other things broken with logout in 7 (cas v3 uses a different query parameters, etc)
Details
https://github.com/simplesamlphp/simplesamlphp-module-casserver/blob/21418f7efbea8c4f078fd4a7d1b9eacf94dd4941/src/Controller/LogoutController.php#L104
Previous module checked the url against the valid service urls.
PoC
The docker instructions from the README.md run an image with a vulnerable config.
Accessing https://localhost/cas/logout?url=https://google.com will redirect to Google
Impact
Impacted configs have
php 'enablelogout' => true,
and are most impacted if they also have
'skiplogoutpage' -> true,
Information leakage issue in the sanitycheck module
Background An incorrect check of return values in the signature validation utilities allows an attacker to get invalid signatures accepted as valid by forcing an error during validation.
Description The SimpleSAMLXMLValidator class allows the verification of the XML digital signature of a SAML 1 message with a given key. In particular, the constructor of the class receives an XML node and a key to verify it and throws an exception in case there is an error, either caused by incorrect input or an invalid signature. This method uses the verify() method from the RobRichards\XMLSecDSig class to verify the signature with the given key, which in turn will end up calling opensslverify() depending on the signature algorithm used.
The opensslverify() function returns 1 when the signature was successfully verified, 0 if it failed to verify with the given key and -1 in case an error occurs. PHP allows translating numerical values to boolean implicitly, with the following correspondences:
- 0 equals false - Non-zero equals true
This means that an implicit conversion to boolean of the values returned by opensslverify() will convert an error state, signaled by the value -1, to successful verification of the signature (represented by the boolean true).
The aforementioned constructor was performing an implicit conversion to boolean of the values returned by the verify() method, which subsequently will return the same output as opensslverify() under most circumstances. This means an error during signature verification is treated as a successful verification by the method.
Affected versions All SimpleSAMLphp versions prior to 1.14.11.
Impact Upon successful exploitation, an invalid signature would be regarded as valid by an affected version of the software. This allows attackers to modify or manually craft SAML 1 response messages and, by triggering a signature validation error in the affected party, get those messages accepted as valid and coming from a trusted entity. In practice, this means full capabilities to impersonate any individual at a given service provider.
The issue can be exploited to get other invalid messages accepted as valid, though the security implications there are minor.
In order to exploit the issue, SAML 1.1 metadata must be registered by the vulnerable Service Provider for the Identity Provider targeted by the attacker (in metadata/shib13-idp-remote.php), and an incorrect context must be fed to the signature validation routines, or an exceptional error must be triggered. So far, the following cases have been identified:
- Using a DSA public key to validate an XML signature made with an RSA-related algorithm. - Using an RSA public key to validate an XML signature made with a DSA-related algorithm. - Exhausting available memory while verifying the signature.
SimpleSAMLphp does not support DSA signatures or keys. Therefore, it is not possible for an attacker to feed an incorrect context by sending a signature with an incorrect algorithm. Upon reception of a DSA-SHA1 signature, SimpleSAMLphp will refuse to perform the validation due to the algorithm not being supported. On the other hand, if an attacker manages to trick a service provider operator to change the public key associated to a certain IdP to a DSA key, signatures made with any combination of the RSA algorithm will be accepted, regardless of whether they are valid or not. This means some serious misconfiguration or social engineering is needed in this case for a successful attack.
Regarding memory exhaustion, it is in theory possible to attack a service provider causing the consumption of all available memory while a message with an invalid signature is being validated. However, memory exhaustion must happen only during signature validation and not immediately before or after. This means exploitation of this case is extremely difficult due to the small time window available for the attacker and the precise control that is needed over the service provider.
All in all, the consequences of this issue are critical, so even though we consider it difficult to exploit, and considering that other ways to trigger failures in signature validation could be possible but so far unidentified, we recommend updating the affected software as soon as possible.
Resolution Upgrade to the latest version.
Credit This security issue was discovered and reported on December 3, 2016 by Thijs Kinkhorst.
Incorrect signature verification
Summary
XML nodes encrypted with either aes-128-gcm, aes-192-gcm, or aes-256-gcm lack validation of the authentication tag length. An attacker can use this to brute-force an authentication tag, recover the GHASH key, and decrypt the encrypted nodes. It also allows to forge arbitrary ciphertexts without knowing the encryption key.
Details
When decrypting with either aes-128-gcm, aes-192-gcm, or aes-256-gcm here, the $authTag is set from a substr(), but never has its length validated (it should be validated with something like strlen($authTag) == self::AUTHTAGLENGTH). For that reason, a shorter than expected data blob will allow for the $authTag to have as short a tag as only one byte (see PHP's documentation%20has%20been%20called.%20Otherwise%20the%20decryption%20may%20succeed%20if%20the%20given%20tag%20only%20matches%20the%20start%20of%20the%20proper%20tag.)).
See this example:
php function test($data) { $ivSize = 12; $tagSize = 16;
$iv = substr($data, 0, $ivSize); $data = substr($data, $ivSize); $offset = 0 - $tagSize; $tag = substr($data, $offset); $ct = substr($data, 0, $offset);
echo 'IV: "' . $iv . '"' . PHPEOL; echo 'Tag: "' . $tag . '"' . PHPEOL; echo 'CT: "' . $ct . '"' . PHPEOL; }
/ Outputs: php > test('myNonceNoncet'); IV: "myNonceNonce" Tag: "t" CT: "" php > test('myNonceNonceta'); IV: "myNonceNonce" Tag: "ta" CT: "" php > test('myNonceNoncetag'); IV: "myNonceNonce" Tag: "tag" CT: "" /
With a legit ciphertext in hand, this is enough to recover the GHASH key. With that key, any authenticated tags can be computed offline which allows for decryption of the ciphertext and forgery of arbitrary ciphertexts. PoC
1. Setup a server expecting XML with an encrypted assertion - Run this php script poc.php with php -S 127.0.0.1:8888 (taken from this saml test case)
- The script expects this private key: sp-private-key.pem.
2. Create an XML document with an encrypted assertion (encrypted with aes-256-gcm)
Here is the SAMLResponse used in the video below: samlresponse.txt
Note: The steps from 3 to 6 are implemented in this exploit script: noncereusewithfmtvaloracle.py. You can run the script with sage -python noncereusewithfmtvaloracle.py -s 'url-encodedandbase64-encodedsamlresponse'
3. Take the content of the <xenc:CipherValue> node and apply the following modifications
- Base64-decode the content
- Take the first 12 bytes and save them as the nonce
- Take the last 16 bytes and save them as the tag
- Now brute-force the tag of an empty ciphertext
- Loop through all 256 possible byte values (let's call that bytetagattempt)
- Concatenate together the nonce and the bytetagattempt
- Base64-encode the result
- Replace the content of the <xenc:CipherValue> node with this result
- On http errors 500, we learn that the tag is valid
- Do the same for the next byte of the tag until all 16 bytes have been brute-forced
4. With this new tag and the empty ciphertext, compute the GHASH key (the way to do this has been described in this blog post)
5. Use this GHASH key to compute authentication tags offline for arbitrary ciphertexts
6. Decryption is done by observing XML parsing errors that occur after modifying the ciphertext, those can be seen as http errors 500
https://private-user-images.githubusercontent.com/20672053/531768743-2f6e4a7e-4384-4350-b423-7ddd77aa9152.webm?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzMTQ3MjEsIm5iZiI6MTc3MzMxNDQyMSwicGF0aCI6Ii8yMDY3MjA1My81MzE3Njg3NDMtMmY2ZTRhN2UtNDM4NC00MzUwLWI0MjMtN2RkZDc3YWE5MTUyLndlYm0WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwMzEyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDMxMlQxMTIwMjFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0zNDRhZThlYTY5OWNmNGZmMmNmOGJhYTNkNzAwMjNiMTVhMDMxOTIzMGRkN2Y3OGU3NTI3NmFkMWE2OTgwMDFhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.X9UVe9qpwX1YQYo34WmUI84KA0a28FKd4SGy15GEVMU
Impact
The general impact is:
XML nodes encrypted with AES-GCM can be decrypted by observing parsing differences XML nodes encrypted with AES-GCM can be modified to decrypt to an arbitrary value The GCM internal GHASH key can be recovered
In cases where the encryption key is embedded in the XML and is encrypted with the Service Provider's public key (like often done with SAML), the last two items don't have a big impact. This is because:
With the Service Provider's public key, an arbitrary ciphertext can be created with a known symmetric key The symmetric keys are generated on the fly every time the IdP creates a new SAMLResponse
In any case, secrets that are embedded in the XML, whether coming from an IdP, or from another scheme, can be decrypted.
Important: If static symmetric keys are used, as the GHASH key could have leaked, you must rotate those keys.
References For additional information on the issue, you can refer to this blog post about the OpenSSL issue and how it can be exploited.
UNSUPPORTED WHEN ASSIGNED A vulnerability was found in simplesamlphp simplesamlphp-module-openidprovider up to 0.8.x. It has been declared as problematic. Affected by this vulnerability is an unknown functionality of the file templates/trust.tpl.php. The manipulation of the argument StateID leads to cross site scripting. The attack can be launched remotely. Upgrading to version 0.9.0 is able to address this issue. The identifier of the patch is 8365d48c863cf06ccf1465cc0a161cefae29d69d. It is recommended to upgrade the affected component. The identifier VDB-218473 was assigned to this vulnerability. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
Impact When a response is processed, the issuer of the Identity Provider is not sufficiently validated. This could allow a malicious identity provider to craft a Saml2 response that is processed as if issued by another identity provider. It is also possible for a malicious end user to cause stored state intended for one identity provider to be used when processing the response from another provider.
An application is impacted if they rely on any of these features in their authentication/authorization logic: the issuer of the generated identity and claims items in the stored request state (AuthenticationProperties)
Patches Patched in version 2.9.2 and 1.0.3. All previous versions are vulnerable.
Workarounds The AcsCommandResultCreated notification can be used to add the validation required if an upgrade to patched packages is not possible.
References The patch is linked to https://github.com/Sustainsys/Saml2/issues/712 and https://github.com/Sustainsys/Saml2/issues/713
UNSUPPORTED WHEN ASSIGNED A vulnerability classified as problematic has been found in SimpleSAMLphp simplesamlphp-module-openid. Affected is an unknown function of the file templates/consumer.php of the component OpenID Handler. The manipulation of the argument AuthState leads to cross site scripting. It is possible to launch the attack remotely. The complexity of an attack is rather high. The exploitability is told to be difficult. Upgrading to version 1.0 is able to address this issue. The patch is identified as d652d41ccaf8c45d5707e741c0c5d82a2365a9a3. It is recommended to upgrade the affected component. VDB-217170 is the identifier assigned to this vulnerability. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
A vulnerability was found in Information Cards Module and classified as problematic. This issue affects some unknown processing. The manipulation leads to cross site scripting. The attack may be initiated remotely. Upgrading to version 1.0 is able to address this issue. The name of the patch is f6bfea49ae16dc6e179df8306d39c3694f1ef186. It is recommended to upgrade the affected component. The identifier VDB-217661 was assigned to this vulnerability.
simplesamlphp before 1.6.3 (squeeze) and before 1.8.2 (sid) incorrectly handles XML encryption which could allow remote attackers to decrypt or forge messages.
Cross-site scripting (XSS) vulnerability in logout.php in SimpleSAMLphp 1.8.1 and possibly other versions before 1.8.2 allows remote attackers to inject arbitrary web script or HTML via the linkhref parameter.
Cross-site scripting (XSS) vulnerability in modules/core/www/nocookie.php in SimpleSAMLphp 1.8.1 and possibly other versions before 1.8.2 allows remote attackers to inject arbitrary web script or HTML via the retryURL parameter.
A signature-validation bypass issue was discovered in SimpleSAMLphp through 1.14.16. A SimpleSAMLphp Service Provider using SAML 1.1 will regard as valid any unsigned SAML response containing more than one signed assertion, provided that the signature of at least one of the assertions is valid. Attributes contained in all the assertions received will be merged and the entityID of the first assertion received will be used, allowing an attacker to impersonate any user of any IdP given an assertion signed by the targeted IdP.
Cross Site Scripting (XSS) in the consentAdmin module
Incorrect signature verification
SimpleSAMLphp 1.14.12 and earlier make it easier for man-in-the-middle attackers to obtain sensitive information by leveraging use of the aesEncrypt and aesDecrypt methods in the SimpleSAML/Utils/Crypto class to protect session identifiers in replies to non-HTTPS service providers.
Multiple timing side-channel issues
Background When a SimpleSAMLphp Identity Provider is misconfigured, a bug in the software when trying to build a persistent NameID to univocally identify the authenticating subject could cause different users to get the same identifier generated, depending on the attributes available for them right after authentication.
Please note that even though this is possible thanks to a bug, an IdP must be misconfigured to release persistent NameIDs even if it is not properly configured to generate them based on the specifics of the deployment.
Description Persistent NameIDs will typically be sent as part of the Subject element of a SAML assertion, or as the contents of the eduPersonTargetedID attribute. Here is an example of such a NameID:
<NameID Format=“urn:oasis:names:tc:SAML:2.0:nameid-format:persistent“> zbonsm0Yn9Gnw14uQEEPr6AO7d+IvxwCQN3t+o24jYs= </NameID>
Some service providers will use this information to identify a user across sessions because a persistent NameID will never change for a given user. This could lead to different users accessing the same account in those service providers.
In order to be affected by this issue, the following circumstances must concur:
- SimpleSAMLphp acts as an identity provider. - The service provider asking for authentication requests a persistent NameID. - No saml:PersistentNameID authentication processing filter is configured (neither for the whole IdP, nor for a given SP). - No simplesaml.nameidattribute configuration option is set (neither for the whole IdP, nor for a given SP). - One of the following alternatives: - No userid.attribute configuration option is set and the users don't have an eduPersonPrincipalName attribute in the users backend, or - the userid.attribute configuration option is set to an empty or missing attribute.
If all these requirements are met, the SimpleSAMLAuthProcessingChain class will try to keep a unique user identifier in the state array (addUserID() method). Bear in mind that this code is executed before all the authentication processing filters configured, meaning that only those attributes retrieved for the user during initial authentication will be available. If no userid.attribute configuration option is set, the default eduPersonPrincipalName will then be used. However, since it is missing, no identifier will be kept. Alternatively, if userid.attribute is set to a missing or empty attribute, the addUserID() method will abort trying to register an identifier.
After executing all authentication processing filters, SimpleSAMLphp will build a SAML assertion. If the service provider requests persistent NameIDs, SimpleSAMLphp will attempt to generate one given that none is already available (because the saml:PersistentNameID filter was not used). At this point, the code will look for the simplesaml.nameidattribute configuration option in either the local IdP metadata or in the remote SP metadata. If none of them are configured, it will default to the unique user identifier previously registered by SimpleSAMLAuthProcessingChain. If no identifier was kept there, the code will log an error message:
Unable to generate NameID. Check the userid.attribute option.
However, instead of aborting the NameID generation at that point, it will go on and use a value missing from the state array as the source for the computation, meaning the null type will be used. Hence, all users connecting to a given service provider will get the same NameID generated, because all the input parameters will be the same:
- The SP's entity identifier. - The IdP's entity identifier. - The null value. - The common secret salt from the main configuration.
Affected versions All SimpleSAMLphp versions between 1.7.0 and 1.14.10, inclusive.
Impact Those identity providers affected by this bug and misconfigured as previously described could be issuing SAML assertions with common NameIDs for all or a subset of their users. If a service provider uses those NameIDs to identify the users of the affected IdP, all the users will be associated with the same user account at the service provider, causing all sorts of potential security issues like information disclosure or unauthorized access.
While we can consider this unlikely to happen, some cases have been already observed. In particular, some identity providers using default configurations and consuming metadata automatically (i.e. using the metarefresh module) while using a user backend like Active Directory that does not populate eduPersonPrincipalName are particularly sensitive to this issue.
Resolution Upgrade to the latest version.
Configure a saml:PersistentNameID authentication processing filter according to your needs. Remember to check that the attribute used as the source for the NameID is present at the moment the saml:PersistentNameID filter is executed. The attribute used must be unique per user, and must not change over time.
Authentication context bypass (multiauth module)
Invalid token creation and validation
Session fixation and authentication bypass (authcrypt module)