Why woocommerce need both consumer key and secret to access api? - wordpress

When I learn to use woocommerce api, I notice that certain access requires both consumer key and secret like below (source: https://github.com/woocommerce/woocommerce/wiki/Getting-started-with-the-REST-API).
https://local.wordpress.dev/wp-json/wc/v2/orders?consumer_key=XXXX&consumer_secret=XXXX
I feel puzzled, is it really safe to give both key and secret over the wire? For authentication purpose, shouldn't sending the key be enough and secret should stay? What is the reason behind that?
BTW, I test with a few failed logins and the URL is recorded in the log with key and secret in plain text!
So is there any way of authentication that avoids sending the secret?

Related

Password derived key (i.e PBKDF2) + oAuth2

I have an application that needs to store secrets on behalf of the user. These secrets should be stored securely, but need to be decryptable when the user is present.
Ordinarily I would turn to password based keys (i.e. PBKDF2) to derive the key, however I also have to provide oAuth2 sign in capabilities (with Facebook and Google), which means I don't have a password that I can use to generate the key.
I have tried to find a unique, consistent and secret key that's returned from the oAuth2 providers, but I can't find one.
Are there any approaches that can combine the two? I suspect the answer is no, but wanted to ask just in case.

Should jwt web token be encrypted?

I was reading article on JWT web token as an access token that is being response to the user. Some of it mention that the web token should be able to be decoded by the user.
Does it means that it is not a good practice to decrypt the entire web token? For example, I suppose to return following JWT web token to user where this piece of information can be decoded.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
However, I feel that I do not want to let user able to decode his/her access token, so I use another encryption algorithm to encrypt everything into another form as follow and pass back to user.
So, I would decrypt this new text when I'll get this access token in the server and decode it.
Is it recommended to do it this way if I do not wish to expose some of the value available in claim (such as user id) to the user? If not, what are the alternatives?
JWT (RFC7519) is just a compact way to safely transmit claims from an issuer to the audience over HTTP.
JWT can be:
signed (JWS - RFC7515)
encrypted (JWE - RFC7516)
signed then encrypted (this order is highly recommended). The whole JWS is the payload of the JWE
encrypted then signed.
It makes sense to encrypt a JWS if you want to keep sensitive information hidden from the bearer (client) or third parties.
The real questions are: does the audience support JWE? If yes, which algorithms are supported?
JWT are "signed" and therefore its contents are protected from tampering: you cannot change its contents without invalidating them.
You can optionally "encrypt" the contents and therefore turn them visible only to issuer (the entity creating the token) and the consumer (the entity that is destined to use its contents after verification).
There's a standard for that: JWE
A token contains user data and acts like a temp storage. It is not good to store sensitive data in a token.
At the first level, you should store the user name and maybe role or something like that. You should not include passwords, so it does not need to be encrypted.
Nevertheless, you can encrypt it if you want.
Yes, the best practice is use the JSON Web Encryption (JWE) RFC, the claims in the JWT after decode it are in plain text, so if the user lost the token, the sensitive information as email, username, access permissions can be visible and can be used as a the initial information of any attack.

Regenerate linkedin API secret key

I want to regenerate the API consumer secret/secret key for my linkedin application, but the regenerate key button on the linkedin application only regenerates the OAuth 1.0a user secret.
I want a new OAuth2 secret key. I hope that I am not the only one who ever wanted to change their secret key.
After hours of googling, I can only find guides on how to locate the key, or dead links to linkedins old support forum.
It is not presently possible to regenerate your OAuth 2.0 secret with LinkedIn. Your best bet is to create a new application instance, and switch over to the new set of credentials.
This functionality has been requested very infrequently in the past, but it is something we're working on getting into the roadmap, regardless.

OAuth access token and refresh token creation

I'm implementing my own OAuth authentication system (with refresh_token support) for an app and I have some questions about how to do it:
Client identification: The client is registered in the auth server and gets a client_id and a client_secret. How do I generate it? is there some kind of relation between both values?.
User authentication: The client sends the users_credentials (username+password for example) + client_id and gets a refresh_token and (temp?)access_token. That access_token is the one I should use in further request or I should use a accesss_token`=F(refresh_token,access_token,client_secret). In the second case what does the F function consist on?
Access token refresh: The client send client_id, refresh_token and gets a access_token (and a optional new refresh_token). Does the access_token need the same conversion (whatever it be), as in the point 2?
If I'm wrong, when and how is the client_secret used?
Complete answers and concrete examples will be "bountied".
The authorisation/authentication server generates these values when you create an account with them (for instance when you create a developer account with Facebook or Google). If you are doing these parts yourself, they should be cryptographically secure pseudo-random numbers or letters. Remember that the client ID is usually publically visible, so choose a reasonably large set of alpha-numerics (I use 30 characters). The secret is private and can be harder to guess so I chose 30 digits with letters, numbers and symbols. These are not related to each other, it is just that one is public and the other isn't.
The usual way this works is that there is a browser redirect to the auth server passing the client id in the URL (and redirect uri) and specifically NOT the user id and password. The whole point of OAuth2 is that the client system never sees the user name and password, only the auth server. After this redirect, the auth server verifies the client id, checks the username/password (for instance) and then returns to the redirect uri with a temporary code. This temporary code is passed back to the Auth server in order to obtain an access token. Since this call is made as a POST from the server, it also passes the client secret to verify that it really is the correct client system and not someone who stole the client id from somewhere else. At this point, the auth server will return an access token (and optional refresh token - you do not need to use them, I don't).
If the client system wants to log the user in without them having to type in their username and password all the time, it can use a refresh token, if available, to call back onto the Auth server and if the Auth server is happy that the refresh token is still valid and any other business rules are correct, it can give you back another access token directly without the user being involved.
I recommend reading the OAuth2 spec here: OAuth2 Spec RFC6749. It can take a while but if you delete the bits you don't need and reduce the amount of data, there are plenty of useful examples in it.
FIRSTLY, The client identifier can be any string that you want, but it should be unique for each client. It can even be the client's choice if you wish.
The client secret should be a cryptographically strong random string. Here is how you could generate one in C#:
RandomNumberGenerator cryptoRandomDataGenerator = new RNGCryptoServiceProvider();
byte[] buffer = new byte[length];
cryptoRandomDataGenerator.GetBytes(buffer);
string uniq = Convert.ToBase64String(buffer);
return uniq;
SECONDLY, The whole point of OAuth is to allow external apps to do things on your behalf without asking for your credentials. So, you need to implement an authentication server that does the logging in part for you. The user opens the app and gets an option to Log in using your website. You tend out access tokens and refresh tokens once the user has keyed in his credentials. The app can then simply use the tokens to perform actions on the user's behalf. I wrote an answer to How would an efficient OAuth2.0 server / provider work? that explains how access tokens can be constructed.
Remember, the need for refresh tokens and the lifetime of access tokens purely depends on how you intend to use them and what does your security framework look like.
LASTLY, The refresh token can also be an HMAC encoded string/a JSON object as I had explained in the answer to the linked question. You can have random refresh tokens and a large backend storage to keep it to verify the tokens in the incoming requests, or have HMAC encoded strings for added security/less storage requirements/latency to decrypt/encrypt tokens.
Also, do make sure that you go through all the flows and possibly the RFC too as mentioned by Lukos.

Securely store and share a secret with ServiceStack across different logins

Given is a ServiceStack REST Service that can sign documents with one of the public/private key algorithm. The prvate key is encrypted using a passphrase only the admin of this privat/public key pair knows.
Know it should be possible that other logins then the admin can sign documents (authorized by roles, permissions, etc.)
Currently they need to provide the passphrase for the private key in every signature request as the service needs to decrypt the private key and sign the document.
But i dont want to give the private key passphrase to other users and i also don't like to send it on every request over the wire.
So what is the best way to store the passphrase on the service side so that authorized logins can sign documents without knowing and sending the passphrase.
Is there a possibility to store it (automatically encrypted/decrypted from ServiceStack) in the user's session/UserAuth object?
Or is there are any other solution? It should work on .net and mono.
I'd recommend you look at Microsoft's guidance on encrypting/decrypting config sections. This way you can store it encrypted in web.config and your back end service can have access to it.
See http://msdn.microsoft.com/en-us/library/zhhddkxy(v=vs.100).aspx

Resources