Jump to content

API Request Validation


Go to solution Solved by skizzerz,

Recommended Posts

Posted (edited)

Hello Invision community!
a couple of points before i get into my topic : 
- This is our first ever website, so please forgive my "noobness" in this topic (among many others)...
- We are subscribed to the cloud service, updated to 4.5.2.
- I am not that familiar with SQL, PHP etc.. I am MUCH more comfortable in C# using RestSharp or HttpWebClient.
- I am not all to familiar with web requests as a whole, just started using RestSharp and HttpWebClient in february heh...

So me and my partner are currently using commerce to sell and generate license keys, which would allow access to specific software within
a "Software Launcher" I have built myself. And it seemed everything was going smoothly until one of our users figured out he could re-route the request, and return a JSON string with falsified info (oops 😅), as I've pretty much built it to accept any old json string as a response.

I guess the question here is how would I go about preventing something like this, or how do YOU currently do so? (even just tips, i'm not asking for an entire handout.. More than happy to do the "legwork" heh)

I can send requests with either an API key, or using an oAuth token (client Credential grant type), but we would like to return some sort of "verification" through the returned content to take a step in preventing this (ie : Real Server IP, ssl cert etc maybe?) but I haven't the slightest clue in where to start to be completely honest, and would like to prevent wasting my time reading on subjects that might not even be supported here 😅

Thanks for taking the time to read (And respond if you choose to do so)
Stay safe everyone!

Edited by InfinityRazz
Posted

It is impossible to completely prevent this, because the customer can always control what code is running on their machine. Below are some common ways to help protect client applications however. None of these are 100% effective (because it is impossible to be 100% effective), but are more to "keep honest people honest" -- that is, someone who wants to break your licensing will figure out a way to do so. People who are curious but see the roadblocks will be more likely to give up, however.

  • Encoding/obfuscation of source code
  • Use HTTPS for your API calls and ensure that the server's certificate is strictly validated

There are a plethora of other methods a quick search away, but the two above shouldn't cause much extra friction in your customers who are not trying to bypass your licensing. You don't want to make your anti-piracy measures so onerous that it breaks the application for paying customers.

Posted (edited)
27 minutes ago, skizzerz said:

It is impossible to completely prevent this, because the customer can always control what code is running on their machine. Below are some common ways to help protect client applications however. None of these are 100% effective (because it is impossible to be 100% effective), but are more to "keep honest people honest" -- that is, someone who wants to break your licensing will figure out a way to do so. People who are curious but see the roadblocks will be more likely to give up, however.

  • Encoding/obfuscation of source code
  • Use HTTPS for your API calls and ensure that the server's certificate is strictly validated

There are a plethora of other methods a quick search away, but the two above shouldn't cause much extra friction in your customers who are not trying to bypass your licensing. You don't want to make your anti-piracy measures so onerous that it breaks the application for paying customers.

Thanks for the response!

=> "Encoding/obfuscation of source code"
Of course, I go through vigorous protection methods including string encryption, method virtualization and packing with even more obfuscation.
(plus tamper checks, debug checks, program checks etc)

=> "Use HTTPS for your API calls"
That is what I was doing , here's some sample code

var client = new RestClient("https://HIDDEN.forumflash.com");
var request = new RestRequest("/api/nexus/purchases", DataFormat.Json);
request.AddParameter("key", "BlahBlahBlah"); // Enter in Api Key
request.AddParameter("customers", MemID); // Pass id from member request
request.AddParameter("active", 1); // Check active purchases
var response = client.Get(request);

if (response.StatusCode == HttpStatusCode.OK)
{
	dynamic resp = JObject.Parse(response.Content);
	// do stuff with object.
}

But the user seems to have figured out how to view the request page... and that kinda just returns a page of plain text where as he put it :
"are sent to a page where all the info is stored in plain text, allowing you to download a local copy and reroute the api calls to your own server..." 
and i guess that's where im struggling, and letting him see all this " and ensure that the server's certificate is strictly validated " 

Edited by InfinityRazz
  • Solution
Posted

You missed the second half of what I wrote: "Use HTTPS for your API calls and ensure that the server's certificate is strictly validated." If the customer is able to easily reroute it to another site, you are likely failing the second prong of that message. Strict validation means that 1. the hostname/SAN in the certificate matches the host you are trying to reach, 2. the certificate chains up to a trusted CA, and 3. there are no expired or revoked certificates in the chain. You may need to explicitly opt-in to this strict validation in your REST library, consult the documentation for more details.

The above can still be bypassed if the client adds a custom root CA to their machine and generates a spoofed certificate for that hostname, but that is more effort than simply setting up an entry in the hosts file. Pinning the CA certificate inside of your app (that is, setting it up so that CA certificate is the only trusted CA rather than relying on the system's root CA store) is one way to help make that even harder, although it means your application has a ticking time bomb embedded inside of it -- should the upstream site change CAs or the CA change their root certificate your app will break until you update the thumbprint. As such, I would personally recommend against pinning the CA certificate.

Posted (edited)
19 hours ago, skizzerz said:

You missed the second half of what I wrote: "Use HTTPS for your API calls and ensure that the server's certificate is strictly validated." If the customer is able to easily reroute it to another site, you are likely failing the second prong of that message. Strict validation means that 1. the hostname/SAN in the certificate matches the host you are trying to reach, 2. the certificate chains up to a trusted CA, and 3. there are no expired or revoked certificates in the chain. You may need to explicitly opt-in to this strict validation in your REST library, consult the documentation for more details.

The above can still be bypassed if the client adds a custom root CA to their machine and generates a spoofed certificate for that hostname, but that is more effort than simply setting up an entry in the hosts file. Pinning the CA certificate inside of your app (that is, setting it up so that CA certificate is the only trusted CA rather than relying on the system's root CA store) is one way to help make that even harder, although it means your application has a ticking time bomb embedded inside of it -- should the upstream site change CAs or the CA change their root certificate your app will break until you update the thumbprint. As such, I would personally recommend against pinning the CA certificate.

 
MPIQServicePointManager.CheckCertificateRevocationList = true;


*sigh* sometimes it really is the simple things that can be missed that have the biggest impacts 😅

Edited by InfinityRazz
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...