Use hard-to-guess endpoints for non-open APIs
When creating APIs that are supposed to be connections between specific parties, make the endpoints hard to guess. They don't necessarily have to be understandable to human users, e.g. www.yourfantasticsite.com/JG55JO95.
Ensure data validity using hashing
I've noticed hashing is rarely used for web APIs, so when we create an API between specific services, let's hash the payload data (often in JSON) to add an extra layer of data validation. And of course, use a secure transport protocol (i.e. over HTTPS).
Hashing in short
A generated private key is locally stored at both parties. This key is first used to hash the message at the sender. The resulting hash is then sent to the receiver (in the same post as the message).
The receiver then also hashes the original message with the same locally stored key. If the result is the same as the sender sent, we know the message has not been compromised.
Code sample for hash validation
public bool ValidateRequest(string jsonMessageFromSender, string hashedIdFromSender)
{
//secret key both parties have stored locally
var localSecret = ConfigurationManager.AppSettings["importHashSecret"];
//Hash the json response we received from sender
var decryptedHash = new HMACSHA256(utf8.GetBytes(localSecret)).ComputeHash(utf8.GetBytes(jsonMessageFromSender));
//convert hash to string to compare with recived hashed string
var decryptedHashString = BitConverter.ToString(decryptedHash);
//is the hashed string from sender the same as the generated
if (hashedIdFromSender.Equals(decryptedHashString))
{
//message is clear to use
return true;
}
else
{
//hash failed
return false;
}
}
Additional security measures
Using an encrypted transfer protocol together with hashing for data validation are obviously only part of what makes an API secure. There are numerous ways to add additional layers of security including authentication and point-to-point private connections.