Introduction
Hello, we are Doyeon Kim, Younghyun Kim, Kyungjoon Park, Charles Hubain, and Sanghwan Ahn from the Security R&D team. The Security R&D team is responsible for researching security technologies, developing software modules, and providing consulting services to enhance the overall security of LY Group services. In this post, we would like to introduce a device attestation service which can be used to assert that requests are sent by untampered applications running on legitimate devices.
Background
As LY's services have become a key infrastructure in our society, abuse cases targeting our users for fraudulent purposes have also increased. Abusers use our services for account hijacking, spamming, phishing, and other types of fraud. They often automate this process to send large amounts of requests by using automated tools or modified applications.
Software-based approaches have limitations. In a threat model where the attacker has root access, the attacker can manipulate the application execution at will, making it impossible to protect against this threat using security self-checks. Additionally, attackers can reverse-engineer the application binary to implement alternative clients and abuse the service. Requests generated from these alternative clients are very difficult to distinguish from legitimate ones. Moreover, with the explosive increase in the volume and variety of user-generated content, comprehensive and scalable abuse prevention measures capable of handling large amounts of diverse content while blocking a wide range of attacks have become necessary.
Given these circumstances, it's essential to focus on how service abuse is discovered and used instead of responding individually to each case. We observed that most abnormal requests are not generated from legitimate devices and applications. Therefore we developed a device attestation service relying on hardware-based attestation methods to fundamentally block requests coming from untrusted sources, thereby enhancing the effectiveness of existing abuse prevention measures.
We successfully integrated our device attestation service into LINE services in December 2023 through collaboration with the Auth & Account Dev team, Account Product App Dev 1 team, and Platform Product Management team. We're utilizing it for various types of request verification and monitoring. Additionally, we're working on integrating this device attestation service into products requiring higher level of security, such as financial services.
Objectives and structure
The device attestation service aims to assert that requests received by the servers meet the following conditions:
- The request was generated by an untampered application running on a legitimate device.
- The request content itself was not tampered.
Specifically, this device attestation service aims to monitor and prevent service abuse by detecting 'high-risk requests' such as:
- Requests sent by alternative clients such as emulators or scripts
- Requests sent by applications that have been tampered with
- Requests sent from jailbroken or rooted devices
- Requests containing content that has been tampered with (For example, Man in the Middle attacks)
- Previous requests being replayed to the server
The device attestation service is based on a Public Key Infrastructure (PKI). Below is a simplified diagram of the device attestation service.
-
Trusted Execution Environment (TEE): A hardware-isolated, secure execution environment within the device. This environment generates keys and performs operations using those keys. In the device attestation service, asymmetric keys are generated in the TEE, with the private key stored in the TEE and never accessible at the OS level.
-
Device Attestation Client: The device attestation client is a module that provides device attestation services. This module communicates with the TEE and the device attestation server.
-
Device Attestation Server: A server module that provides the device attestation service. The public key of the asymmetric keys generated in the TEE is stored on the device attestation server.
On a high level, the device attestation client generates the data needed by the device attestation service to verify if the request is potentially high-risk. During this process, the TEE signs the request with the private key previously generated by the TEE to ensure its authenticity. The data generated by the device attestation client is sent to the device attestation server. The server verifies this data to assess the potential risk of the request.
Using this method, while the user performs operations (login, payment, transfer, etc.) within the application, the server uses the device attestation service to verify that requests originated from legitimate devices and application. If an issue is detected, the server can decide on the remedial actions to take.
The device attestation service is implemented based on the Key Attestation feature provided by Android and the App Attest feature provided by iOS. Its design is based on the WebAuthn specification to implement a consistent security protocol on both Android and iOS. Also, the implementation is available as a library, allowing application and server developers to easily integrate device attestation functionality into their services.
Next, we will look into the attestation and assertion process used in the device attestation service; the communication between the client, TEE, and server; and finally explain the technical details of how tampering is detected.
Attestation
Attestation is the process of registering an assertion key used to sign request data; it's a crucial step that guarantees the integrity of the key generation environment by ensuring the following properties:
- Root of Trust Verification: It proves that the key was generated inside the device's TEE using the device root of trust.
- Device Attribute Identification: It identifies specific attributes of the device in use, such as the method of private key protection and whether boot state verification was performed.
This ensures that the client can prove that the assertion key pair was generated inside a hardware-isolated secure area within the device (such as ARM TrustZone, Android StrongBox, or iOS Secure Enclave) and that the device's boot chain wasn't tampered with. The server can verify that the key was generated in a high-security environment and that the device is in a secure and trustworthy state, free from threats such as rooting or jailbreaking. Information about the integrity of the application is also transmitted and verified during the attestation process, ensuring that the correct application is running in a trusted environment.
Attestation also plays a role in protecting the assertion public key from tampering during transmission to the server by signing the key. This ensures the integrity and authenticity of the key throughout its lifecycle, from generation to transmission. Through this mechanism, the server can be confident that the client's requests originate from a trusted source.
Attestation process
The attestation process interacts with the server in a challenge-response protocol to prevent replay attacks, following the steps below.
-
The client requests a challenge from the server. This value is a one-time use random value necessary to prevent replay attacks.
-
The client generates an assertion key pair (asymmetric keys). The private key can only be used by the application that requested its creation and is generated and protected within a high-security hardware environment, making it unreadable and unmodifiable by external code outside this environment.
-
Android: Generates the assertion key pair and certificate chain within ARM TrustZone or StrongBox.
-
iOS: Only generates the assertion key pair within the Secure Enclave (SE).
-
- The client creates an attestation object using various security mechanisms to securely transmit the assertion public key and device and application related information to the server. Since attestation objects differ by platform, please refer to the attestation object section below for a detailed description.
- Android: The client creates an attestation object based on several pieces of information, including the list of certificates containing the assertion public key generated in the TEE and the signature generated based on the challenge.
- iOS: The client sends the generated assertion public key and various verification information to Apple's servers and requests the creation of an attestation object. Apple's servers verify the submitted data and, if there are no issues, generate an x.509 certificate containing a nonce (a hashed combination of the assertion public key, challenge, and verification information using SHA-256). This certificate, along with the certificate chain, is included in the attestation object, which is then sent back to the client.
-
The generated attestation object is sent to the server.
- The server that receives the attestation object verifies the validity of the entire x.509 certificate chain within the attestation object using the root certificate of each platform, as well as the signature, challenge value, and unique information including the application signature. This ensures that the received assertion public key was generated on a trusted device and by an untampered application. If everything is successfully verified, the attestation process is completed by registering the public key along with the user information.
x.509 certificate chain verification It is crucial to prove that the assertion key pair has been generated in a trusted hardware environment. To achieve this, we verify the certificate chain generated by this hardware. The trustworthiness of this certificate chain is confirmed through the following method. The x.509 certificate chain within the attestation object consists mainly of three certificates.
The certificate chain consists of a chain of certificates starting from the leaf certificate containing the assertion key information up to the root certificate. Each certificate is verified by the one above up to the root certificate. If the chain can be verified up to the root certificate, it guarantees that the assertion key was generated on a trusted device by an untampered application. |
Attestation object
An attestation object is a data structure that contains the authentication data required for attestation. It follows the structure defined by the FIDO2 WebAuthn, as shown in the diagram below.
While iOS returns serialized data in the format of a WebAuthn attestation object through the AppAttest API, Android returns the certificate chain for the generated key itself. This results in a format mismatch. To unify the server logic and handle requests from both platforms, we decided to use the same structure for the attestation object on Android as well.
The basic structure of the attestation object is divided into three main parts for both Android and iOS:
- fmt: The attestation statement format, which can include values like "packed", "tpm", "android-key", "android-safetynet", "fido-u2f", "none", or "apple". The format of attStmt varies depending on this value.
- attStmt: The attestation statement includes the certificate chain (x5c) guaranteeing that the key was generated on an untampered device, and the value signed with the private key combining the authenticator data (authData) and challenge. The server verifies the attestation object by checking the certificate chain to confirm that the key was generated on an untampered device, and by validating the authenticator data with the public key to ensure the authentication data has not been tampered with.
- authData: Authenticator data, which includes data related to the assertion key and the attestation process.
The value of fmt varies depending on the platform and authenticator. In the device attestation service, fmt is "android-key" for Android and "apple-appattest" for iOS.
While the format of attStmt varies, it generally consists of three parts:
- alg: The algorithm value used is ES256, which is ECDSA on the P256 elliptic curve (this field doesn't exist on iOS).
- sig: The value signed with the assertion private key, combining authData and the challenge.
- Android: This value ensures that the data within the attestation object hasn't been tampered with.
- iOS: This field doesn't exist. Instead, a nonce value, generated by hashing the combined authData and challenge, is added to the x.509 certificate to ensure the data hasn't been tampered with.
- x5c: Contains the leaf and intermediate certificates. The root certificate can be found on the official Android and iOS sites.
authData consists of the following values:
- RP ID Hash: The application ID value hashed with SHA256 on both Android and iOS.
- Android: Verifies the AttestationApplicationId included in the certificate chain within attStmt to check for app tampering.
- iOS: The server can verify whether the application has been tampered with by comparing the RP ID Hash value with the official App ID it possesses. The RP ID is a hashed value of the App ID, which includes the 10-character team identifier, a period, and the application's Bundle ID. If a third party attempts to modify the application, they must obtain a new Bundle ID and provisioning profile from Apple, which will change the RP ID Hash value. Therefore, the server can determine if the application has been tampered with.
- flags: A 1-byte bitfield indicating the state of authData. Each bit has a different value such as "ED", "AT", "BS", "BE", "UV", or "UP". AT is the bit indicating the inclusion of "attested cred data". For attestation objects, AT is set to 1.
- counter: A signature counter, which is 0 in the attestation object. Upon successful attestation, the credential's signature counter is set to 0 and increments by 1 with each successful assertion.
- attested cred data: Short for "attested credential data".
- aaguid: "Authenticator attestation global unique identifier", a 128-bit identifier.
- credentialIdLength: An unsigned big-endian integer indicating the length of the credentialId.
- credentialId: The identifier of the generated assertion key.
- credentialPublicKey: The assertion public key encoded in COSE key format.
- extensions: A field for additional data, which isn't used by the device attestation client.
Assertion
The assertion is a process which, based on the trust established by the attestation, proves that the client still possesses the assertion key (proof of possession) and ensure secure communication between the app and the server.
The assertion process is typically performed when a significant event occurs within the app. During assertion, the app receives a challenge value from the server, signs it with the assertion private key, and then sends it back to the server. The server verifies the received signature to confirm that the request originates from a trusted application. Additionally, information about the integrity of the application is also verified and transmitted during the assertion process, proving its integrity.
Assertion process
Similar to the attestation process, the assertion process interacts with the server through a challenge-response protocol to prevent replay attacks, following the steps below.
- The client requests a challenge from the server and receives it.
- The client signs the assertion-related information and the challenge with the assertion private key registered during the attestation process.
- The client creates an assertion object, including the generated signature (details of the assertion object are explained below).
- When the assertion object is sent to the server, the server uses the information in the assertion object and the assertion public key stored during the attestation process to verify the signature, ensuring that the client and app are operating in a trusted environment.
Assertion object
An assertion object is a data structure that includes the signature and authentication data. The format of the authentication data is the same as the one included in the attestation object.
- Signature: The value obtained by concatenating the authenticatorData value and clientData hashed with SHA256, and then signing the resulting hash with the assertion private key.
- AuthenticatorData
- RP ID Hash: The application ID value hashed with SHA256 on both Android and iOS.
- iOS: The server can verify the integrity of the application through the RP ID hash. Additionally, the iOS daemon that runs iOS's AppAttest service manages an ACL based on the application bundle ID. This ACL allows key access only to specific bundle IDs. Therefore, if the app is tampered with and the bundle ID is changed, iOS will not recognize the new bundle ID and will prevent access to the assertion key.
- Android: Although the RP ID hash isn't verified by the server, from a platform perspective, it is essentially the same as iOS. If an attacker or third party tries to tamper with the application, they must re-sign the application, thus changing the signature value. Android's KeyMaster service manages an access control list (ACL) for each key, allowing access only to specific application signatures. Therefore, if the app is tampered with and re-signed, the KeyMaster won't recognize the new signature and will prevent access to the original key.
- Flags: The AT value is set to 0, indicating that there is no attested credential data in the assertion object, unlike the attestation object.
- Counter: The signature counter indicates the cumulative usage count of the assertion key and serves as an auxiliary means to prevent replay attacks. The counter value in the first assertion must be greater than 0, and the server checks if the counter is greater than the previous value for each assertion to detect replay attacks or cloning of the assertion key.
- RP ID Hash: The application ID value hashed with SHA256 on both Android and iOS.
Security enhancement measures
To maximize security, our device attestation service has established the following enhancement measures.
Binding API to assertions
When the user performs security-critical operations such as payments or transfers, the parameter values of the respective API can be bound to the assertion to guarantee the authenticity of the request.
For example, when a user requests a payment or transfer to the server, if the application includes the relevant request information in the assertion object, the server can verify the assertion to ensure that the information was generated by a legitimate client, thereby significantly enhancing the security level of the API.
Detecting potentially untrustworthy execution environments
Android includes a key attestation extension data schema within the certificate chain in the attestation object. Checking the values of each element in this schema provides detailed information about the execution environment.
SecurityLevel ::= ENUMERATED {
Software (0),
TrustedEnvironment (1),
StrongBox (2),
}
RootOfTrust ::= SEQUENCE {
verifiedBootKey OCTET_STRING,
deviceLocked BOOLEAN,
verifiedBootState VerifiedBootState,
verifiedBootHash OCTET_STRING,
}
VerifiedBootState ::= ENUMERATED {
Verified (0),
SelfSigned (1),
Unverified (2),
Failed (3),
}
If the values of the above schema elements are as follows, the environment is considered "potentially untrustworthy".
- attestationSecurityLevel is set to Software
- Indicates a high likelihood of running on a low-security device (TEE is unavailable) or an emulator.
- deviceLocked is set to False
- The bootloader is unlocked. This means that an unsigned device image can potentially be flashed. In this case, the image could fake the application signature verification or bypass the KeyMaster ACL. With an unlocked bootloader, an attacker could pass the attestation using the official image with a verified boot state, then flash a modified image that fakes the signature verification and bypasses the key ACL, allowing them to continue using the existing assertion key.
- verifiedBootState is not set to Verified
- Indicates a modified device state not using the official device image provided by the manufacturer which therefore cannot be trusted.
In general, an environment is considered trustworthy if attestationSecurityLevel is TrustedEnvironment or StrongBox, deviceLocked is True, and verifiedBootState is Verified. Based on additional elements in the key attestation extension data schema, such as the OS patch level being below a certain threshold, more sophisticated security policies can be established, such as blocking requests from such environments or treating it as an additional risk factor in an existing anomaly detection system.
Measures against attestation key leaks
Attestation keys can only be used on genuine Apple hardware or Android hardware certified through Google’s Compatibility Test Suite (CTS). If attestation keys are leaked, mismanaged by a mobile device manufacturer, or suspected of being extracted by attackers from the supply chain, Google and Apple can revoke these keys. Google adds the keys to the Certificate Revocation List (CRL), while Apple stops issuing attestations for the respective device.
Therefore, during the attestation process, we verify the validity of each certificate in the certificate chain against the official Certificate Revocation List (CRL). This list is managed by Google and can be checked on this site. For more details, please refer to Google's official guide on the Certificate Revocation List.
Measures to prevent device attestation bypass
Attackers can gain root access by exploiting application and kernel vulnerabilities without directly modifying the device’s operating system. In such cases, the boot level integrity remains intact, allowing attackers to bypass or manipulate the attestation and assertion process. Consequently, they can provide assertions through modified devices to other devices (such as bots or emulators), thereby abusing service requests. Protection against such attacks is necessary.
Although it's nearly impossible to perfectly detect such behavior, we have implemented an additional security layer based on anomaly detection to assess risk by measuring the number of attestations requested from a single device.
Conclusion
In this post, we introduced our device attestation service that ensures the integrity of devices, applications, and service requests. After being integrated into the LINE app, the device attestation service has reached nominal operation, and we are currently collecting and analyzing related service data. Moving forward, we plan to use this data to improve the existing anomaly detection-based anti-abuse system and share the results in future blog posts.
We went through many trials and errors during the process of integrating our device attestation service into a global-scale service like LINE. We would like to take this opportunity to sincerely thank the Auth & Account Dev team, Account Product App Dev 1 team, and Platform Product Management team for their invaluable support during this process. Additionally, the Auth & Account Dev team will soon share a blog post about the process and results of applying this device attestation service to the global LINE services. We appreciate your interest and look forward to your continued support. Thank you for reading this long post.