Skip to main content

As Morons@Morons mentioned in theirhis answer, it is very difficult to verify the entity at the other end of the connection.

The simplest way to provide some level of authenticity is to have the server check some secret that that only the real entity would know. For a user, that might be a username and a password. For a piece of software where there is no user you might embed a secret.

The problem with these approaches is that you have to place some trust in the client. If someone reverse engineers your app or steals your password they can pretend to be you.

You can take steps to make it harder to extract the secret information by obfuscating it in the executable. Tools like ProGuard which is an obfuscator for Java can help with this, I don't know as much about obfuscation in other languages but there are likely similar tools. Using a TLS connection helps to prevent people snooping on your traffic, but does not prevent a MITM attack. Pinning can help to address that issue.

I work for a company called CriticalBlue(Full disclosure!) who have a product called Approov that tries to address this problem of trust. It works for Android/iOS currently and provides a mechanism for our servers to check the integrity of the client app. It does this by getting the client to calculate a response to a random challenge. The client has to calculate the response using attributes of the installed app package which are hard to fake and it includes some sophisticated anti-tamper mechanisms.

It returns a token which you can then send as a proof of authenticity to your API.

The important difference with this approach is that though it would be possible to disable the authenticity check on the client, if you did so you would not get the authentication token you need to verify your app with the server. The library is also tightly coupled to the characteristics of the executable it is within, so it would be very difficult to embed it in a fake app and have it work.

There is a cost/benefit analysis any API developer must make to decide how likely it is that someone will try to hack their API and how costly that might be. A simple secret check in the application prevents trivial attacks, but to protect yourself against a more determined attacker is probably considerably more complicated and potentially costly.

As Morons mentioned in their answer, it is very difficult to verify the entity at the other end of the connection.

The simplest way to provide some level of authenticity is to have the server check some secret that that only the real entity would know. For a user that might be a username and password. For a piece of software where there is no user you might embed a secret.

The problem with these approaches is that you have to place some trust in the client. If someone reverse engineers your app or steals your password they can pretend to be you.

You can take steps to make it harder to extract the secret information by obfuscating it in the executable. Tools like ProGuard which is an obfuscator for Java can help with this, I don't know as much about obfuscation in other languages but there are likely similar tools. Using a TLS connection helps to prevent people snooping on your traffic, but does not prevent a MITM attack. Pinning can help to address that issue.

I work for a company called CriticalBlue(Full disclosure!) who have a product called Approov that tries to address this problem of trust. It works for Android/iOS currently and provides a mechanism for our servers to check the integrity of the client app. It does this by getting the client to calculate a response to a random challenge. The client has to calculate the response using attributes of the installed app package which are hard to fake and it includes some sophisticated anti-tamper mechanisms.

It returns a token which you can then send as a proof of authenticity to your API.

The important difference with this approach is that though it would be possible to disable the authenticity check on the client, if you did so you would not get the authentication token you need to verify your app with the server. The library is also tightly coupled to the characteristics of the executable it is within, so it would be very difficult to embed it in a fake app and have it work.

There is a cost/benefit analysis any API developer must make to decide how likely it is that someone will try to hack their API and how costly that might be. A simple secret check in the application prevents trivial attacks, but to protect yourself against a more determined attacker is probably considerably more complicated and potentially costly.

As @Morons mentioned in his answer, it is very difficult to verify the entity at the other end of the connection.

The simplest way to provide some level of authenticity is to have the server check some secret that that only the real entity would know. For a user, that might be a username and a password. For a piece of software where there is no user you might embed a secret.

The problem with these approaches is that you have to place some trust in the client. If someone reverse engineers your app or steals your password they can pretend to be you.

You can take steps to make it harder to extract the secret information by obfuscating it in the executable. Tools like ProGuard which is an obfuscator for Java can help with this, I don't know as much about obfuscation in other languages but there are likely similar tools. Using a TLS connection helps to prevent people snooping on your traffic, but does not prevent a MITM attack. Pinning can help to address that issue.

I work for a company called CriticalBlue(Full disclosure!) who have a product called Approov that tries to address this problem of trust. It works for Android/iOS currently and provides a mechanism for our servers to check the integrity of the client app. It does this by getting the client to calculate a response to a random challenge. The client has to calculate the response using attributes of the installed app package which are hard to fake and it includes some sophisticated anti-tamper mechanisms.

It returns a token which you can then send as a proof of authenticity to your API.

The important difference with this approach is that though it would be possible to disable the authenticity check on the client, if you did so you would not get the authentication token you need to verify your app with the server. The library is also tightly coupled to the characteristics of the executable it is within, so it would be very difficult to embed it in a fake app and have it work.

There is a cost/benefit analysis any API developer must make to decide how likely it is that someone will try to hack their API and how costly that might be. A simple secret check in the application prevents trivial attacks, but to protect yourself against a more determined attacker is probably considerably more complicated and potentially costly.

Source Link

As Morons mentioned in their answer, it is very difficult to verify the entity at the other end of the connection.

The simplest way to provide some level of authenticity is to have the server check some secret that that only the real entity would know. For a user that might be a username and password. For a piece of software where there is no user you might embed a secret.

The problem with these approaches is that you have to place some trust in the client. If someone reverse engineers your app or steals your password they can pretend to be you.

You can take steps to make it harder to extract the secret information by obfuscating it in the executable. Tools like ProGuard which is an obfuscator for Java can help with this, I don't know as much about obfuscation in other languages but there are likely similar tools. Using a TLS connection helps to prevent people snooping on your traffic, but does not prevent a MITM attack. Pinning can help to address that issue.

I work for a company called CriticalBlue(Full disclosure!) who have a product called Approov that tries to address this problem of trust. It works for Android/iOS currently and provides a mechanism for our servers to check the integrity of the client app. It does this by getting the client to calculate a response to a random challenge. The client has to calculate the response using attributes of the installed app package which are hard to fake and it includes some sophisticated anti-tamper mechanisms.

It returns a token which you can then send as a proof of authenticity to your API.

The important difference with this approach is that though it would be possible to disable the authenticity check on the client, if you did so you would not get the authentication token you need to verify your app with the server. The library is also tightly coupled to the characteristics of the executable it is within, so it would be very difficult to embed it in a fake app and have it work.

There is a cost/benefit analysis any API developer must make to decide how likely it is that someone will try to hack their API and how costly that might be. A simple secret check in the application prevents trivial attacks, but to protect yourself against a more determined attacker is probably considerably more complicated and potentially costly.