How to use intuit webhook verifier token on a webhook - ruby-on-rails

I have created a webhook with intuit developer account
https://developer.intuit.com/app/developer/qbo/docs/develop/webhooks#configuring-webhooks
It works fine, my question is how to use the verifier token in order to secure the webhook?
I see various intuit headers but not sure how to use them

There is a detailed documentation
Hash the notification payload with HMAC_SHA256_ALGORITHM using your verifier token as the key.
Convert the intuit-signature header from base-64 to base-16.
Compare the value from step 1 to the intuit-signature header from the notification. The values should be identical.
https://developer.intuit.com/app/developer/qbo/docs/develop/webhooks/managing-webhooks-notifications#validating-the-notification
Here is some more information how to generate the HMAC hash (Using HMAC SHA256 in Ruby) and how to convert the base64 signature to base16 (Converting a hexadecimal digest to base64 in Ruby). To compare the values Rails does implement a safe_compare method (https://api.rubyonrails.org/classes/ActiveSupport/SecurityUtils.html).

Related

different payload from google oauth2 response causes json error

I've got Google's oauth2 working on my app, where id_token is a string delimited with periods. I read here that the id_token is delimited into three parts and the second part contains the actual payload. If I split the string apart and decode the second value I get what I expect using my account. What I don't understand though is when I try on my wife's account if I parse that second part to json an "unexpected character" error.
I've tried grabbing the string from the console and running it through an online base64 decoder and do see the json doesn't get evaluated correctly.
{"iss":"accounts.google.com","sub":"111475728886332985448","azp":"74770364428-621332j2r657ish4jh94n9n1k0mplpgd.apps.googleusercontent.com","email":"her.email#gmail.com","at_hash":"lSKFL86HsCeu7TU4tsYBTw","email_verified":true,"aud":"74300369428-621332j2r657ish4jh94n9n1k0mplpgd.apps.googleusercontent.com","iat":1414192526,"exp":191819642���
What could be different between the two accounts that would cause my email to return valid json and hers not to?
An id_token is a JSON Web Token (JWT), in this case using compact serialization. JWT elements are base64url encoded with no padding, which is slightly different from plain base64 encoding as can be seen from: https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature-38#appendix-C
A nice id_token/JWT decoder can be found here: http://jwt.io/
You may have been lucky for your own id_token so that it did not need padding.

Apigee doesn't seem to support the OAuth 2 specification, is there a reason why?

We're making requests for bearer tokens using client_credentials OAuth 2 grant flow with Apigee. According to the spec:
4.4.2. Access Token Request
The client makes a request to the token endpoint by adding the
following parameters using the "application/x-www-form-urlencoded"
format per Appendix B with a character encoding of UTF-8 in the HTTP
request entity-body:
grant_type
REQUIRED. Value MUST be set to "client_credentials".
If we make a call however we get an error like this:
{"ErrorCode" : "invalid_request", "Error" :"Required param : grant_type"}
It seems that using Apigee we have to send grant_type as a query parameter.
Why is this? We have clients of Apigee that are unable to use OAuth libraries in their language of choice because of the way that Apigee deals with OAuth 2, and it would be good to know if there is by-design or not.
In addition it doesn't seem like it supports grant_type in the post body and sending id and key using basic auth.
Turns out you do not need to send in grant_type as a query parameter. There is a <GrantType> element in your GenerateAccessToken policy that takes in a variable. For instance, I can use the following:
<OAuthV2 name="GenerateAccessToken">
<DisplayName>GenerateAccessToken</DisplayName>
<FaultRules/>
<Properties/>
<!-- This policy generates an OAuth 2.0 access token using the password grant type -->
<Operation>GenerateAccessToken</Operation>
<!-- This is in millseconds -->
<ExpiresIn>1800000</ExpiresIn>
<Attributes/>
<SupportedGrantTypes>
<GrantType>password</GrantType>
</SupportedGrantTypes>
<GenerateResponse enabled="false">
<Format>FORM_PARAM</Format>
</GenerateResponse>
<GrantType>user.grant_type</GrantType>
<UserName>request.header.username</UserName>
<PassWord>request.header.password</PassWord>
</OAuthV2>
In this example, the grant_type is passed in as user.grant_type. But user.grant_type can be anything-- header, query param, form param, or even a hard-coded value. This way, you (the developer) are provided maximum flexibility on how you want to send in the grant_type.
Can you paste the exact API call that you are making (obviously you should obfuscate the key and secret)?
I'd like to understand what you say when you say "Apigee" -- it could mean API BAAS (https://api.usergrid.com) or a proxy that you defined using API services and attached an OAuth 2 policy to, or something else?

how to generate OAuth nonce in numeric format for getting followers

I want to get oAuth nonce for https://api.twitter.com/1.1/followers/list.json how can i get whether in php or iOS API
If the question is "How can I generate an OAuth nonce in Objective-C?", then you should start from OAuth specification section 3.3. Nonce and Timestamp.
For an Objective-C implementation, you can have a look at STTwitter's code for generating nonces.
Basically, you can create a random string with the CFUUIDCreateString(). Taking the first 32 characters is enough.

Oauth 2 - params ordering and signature integrity

I have two questions:
Q1: Why does OAuth2 require params to be ordered and encoded (for 2-legged)?
All it has to worry about is the matching signature in both the end for the given data(query string).
We can just check the signature generated using the query string.(e.g ?a=1&b=2). Since the signature is generated based on the secret key which is known only to the client and provider, we can only consider the query string without any ordering/encoding.
So, what's the advantage in doing ordering/encoding and then creating the signature?
Q2: How can this signature save me from man-in-the middle attack?
If I have to make a request like this to my server from a client:
increaseUserPoints?userId=1&pointsToAdd=5&appId=x&token=XYZ
Now the token XYZ will be always same, so a hacker could keep posting the same request to increase points. Since the generated token from the given appId is the same, the server will allow this. How is this case handled?
Q1: Ordering the query parameters brings sanity to the HMAC.
Let's say you have two parameters: 'pointsToAdd' and 'appId'. Using the query string pointsToAdd=X&appID=y creates a different HMAC to appID=y&pointsToAdd=X. Because both you and the server need to generate the same HMAC to verify the requests having unordered query parmeters plain fails.
Q2: This saves you from an attack because only you and the server know how to sign your request.
You have a secret key, and only you and the server knows it. This key signs the request. If the HMAC doesn't match according to this secret key, the request fails.
Because all parameters have been used to create the HMAC the request is secure from MITM attacks — a hacker can't change, add or delete any query parameters, or the server will produce a different HMAC when it attempts to authorise and the request fails.

What are the characteristics of an OAuth token?

How many characters long can an oauth access token and oauth access secret be and what are the allowed characters? I need to store them in a database.
I am not sure there are any explicit limits. The spec doesn't have any.
That said, OAuth tokens are often passed as url parameters and so have some of the same limitations. ie need to be properly encoded, etc.
OAuth doesn't specify the format or content of a token. We simply use encrypted name-value pairs as token. You can use any characters in token but it's much easier to handle if the token is URL-safe. We achieve this by encoding the ciphertext with an URL-safe Base64.
As most people already pointed out. The OAuth specification doesn't give you exact directions but they do say...
cited from: https://datatracker.ietf.org/doc/html/draft-hammer-oauth-10#section-4.9
"Servers should be careful to assign
shared-secrets which are long enough,
and random enough, to resist such
attacks for at least the length of
time that the shared-secrets are
valid."
"Of course, servers are urged to err
on the side of caution, and use the
longest secrets reasonable."
on the other hand, you should consider the maximum URL length of browsers:
see: http://www.boutell.com/newfaq/misc/urllength.html
If you read the spec, it says,
The authorization server issues the registered client a client
identifier - a unique string representing the registration
information provided by the client. The client identifier is not a
secret; it is exposed to the resource owner, and MUST NOT be used
alone for client authentication. The client identifier is unique to
the authorization server.
The client identifier string size is left undefined by this
specification. The client should avoid making assumptions about the
identifier size. The authorization server SHOULD document the size
of any identifier it issues.
Second, Access Token should be sent as header, not as a URL param.
Authorization: Bearer < token>.
An OAuth token is conceptually an arbitrary-sized sequence of bytes, not characters. In URLs, it gets encoded using standard URL escaping mechanisms:
unreserved = ALPHA, DIGIT, '-', '.', '_', '~'
Everything not unreserved gets %-encoded.
I'm not sure whether you just talk about the oauth_token parameter that gets passed around. Usually, additional parameters need to be stored and transmitted as well, such as oauth_token_secret, oauth_signature, etc. Some of them have different data types, for example, oauth_timestamp is an integer representing seconds since 1970 (encoded in decimal ASCII digits).
Valid chars for OAuth token are limited by HTTP header value restrictions as OAuth token is frequently sent in HTTP header "Authorization".
Valid chars for HTTP headers are specified by https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6. Alternatively you may check HTTP header validating code of some popular HTTP client libs, for example see Headers.checkNameAndValue() util of OkHttp framework: https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Headers.java
And this is not all. I wouldn't include HTTP header separator (; and many others) and whitespace symbols (' ' and '\t') and double quote (") (see https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6) as it would require to escape OAuth token before using in HTTP header. Frequently tokens are used by humans in curl test requests, and so good token generators don't add such characters. But you should check what characters may produce Oauth token generator with which your service is working before making any assumptions.
To be specific, even if Oauth spec doesn't say anything, if you are using java and mysql then it will be 16 characters as we generally generate the tokens using UUID and store it as BINARY(16) in the database. I know these details as I have recently done the development using OAuth.

Resources