Login via hooks - elrond

I'm currently developing an application where holders can see historical data of their NFT's. All code is in place, but I'm still looking for a way to securely verify their ownership of a certain NFT.
There is the possibility to extend one of the dApp examples in the Elrond docs, but I'm not that familiair to React or NodeJS, so I'm trying to build this in PHP.
One thing I came across, is the login via Hooks, as used by the Maiar Exchange.
https://docs.elrond.com/wallet/webhooks/#login-hook
However, the Callback URL can be accessed manually by users, so this can give people Unauthorized access to my application.
Now, there is an undocumented extra parameter token I can pass to the Login hook (as used by Maiar Exchange). I know I can fetch a valid token by sending a POST request to 'https://id.maiar.com/api/v1/login/init'. This will give back a token I can append to the Callback URL. By doing so, the Callback URL will receive an appended signature parameter. I feel like I'm almost there, but the question is: How can I interpret this signature and how can I use this signature to verify if the returned response was valid and belongs to the given token/address? How was this signature is generated?
Also, I feel like it would be very nice if there was some sort of OAuth implementation for Elrond, but since it isn't there, I'm trying this approach.

Related

Trying to understand how recaptcha works step by step

This is my current understanding of recaptcha (using v2 invisible)
We load the api.js script onto our site
We add data attributes to the button
User clicks button
A listener somewhere in the api.js script fires because it's listening for an event on a tag with those data attributes
This is where it gets fuzzy and I start guessing:
api.js gathers browsing info from the user's cookies and information about how they interacted with the site. Based on this it determines how likely you are are to be a bot and if you are below a certain threshold it gives you a test. Whether you pass the test then gets further factored into your score and all of that gets encoded into a token, which we receive in our callback that we specified on the button's data attribute.
We pass this token to the back end with the rest of our form
From the backend, we make an API request to Google to convert the token into usable information about whether the user passed or failed.
At this point I get confused about why this wasn't just what the api.js script returned in the first place. Does this step only exist in order to give Recaptcha information to further improve it? I just don't understand why this step is here, unless I'm misunderstanding what is going on earlier in the process. Am I getting these we steps wrong? Thanks.
The whole point for captchas is that your server (instead of client in the browser) can verify that the (HTTP) request it received was generated from a real person's actions, when interacting with your application.
This is why your client sends a recaptcha token to your server and your backend consults with the captcha provider about this token and receives trusted information about the original client. In this scenario, your server does not trust the client, so it receives only a token from it. Then it communicates with the trusted captcha provider server-to-server and validates that the token it received from the client is valid and the user behind it is legitimate.
If your client sent the original response from the captcha provider to your backend server, there would be no way for your server to know whether this was a legitimate response from the captcha provider, or a fake one from the client.

How can I hide API secret key when sending AJAX requests?

I am about to start working on a project, which is basically a web interface for a mobile banking application. The API is ready, I only need to provide the frontend part of the web application. I was going to make it using Backbone/Angular/Ember, but started to worry about the security.
Particularly, the following. As a rule, every API request must contain a parameter method_code, which is calculated as hash of user token, method name and secret API key. If I put the logic of how this param is calculated into one of .js files, anyone could potentially access some sensitive data using tools like Postman or even browser console. How should I go about this issue? I could have a server-side script generating the method_code for me, but is it possible to make it accessible only to my web app's requests?
every API request must contain a parameter method_code, which is calculated as hash of user token, method name and secret API key
I could have a server-side script generating the method_code for me, but is it possible to make it accessible only to my web app's requests?
Yes, the server-side script would be the way to go if you do not want to expose the secret API key within your client side code or request data.
User token can (presumably) come from the user's session cookie value? So simply have a server side method that takes the method name and then returns the method_code calculated from the secret API key (kept server side only) and the user token.
The Same Origin Policy will prevent another domain making a request to your API and retreiving the method_code. I'm also assuming the API and front-end code runs on the same domain here, although if this is not the case you can use CORS to allow your front-end code to read and retreive data client-side via the API.
You can try to generate a token based on security factors and encrypt that and use it in your requests to identify your clients and valid requests.

How to add multiple redirect URIs for Google OAuth 2?

I am trying to make Google OAuth 2 authentication work with a toy app I am running on my computer (at localhost:8080) using Social Auth for Java.
However when my app connects to Google to authenticate the user, Google responds with this error page:
My app, named "My Hobby App", is configured in the Developer Console as such:
In the Google OAuth 2 docs, it is specified that:
redirect_uri: One of the redirect_uri values listed for this project
in the Developers Console.
Determines where the response is sent. The
value of this parameter must exactly match one of the values listed
for this project in the Google Developers Console (including the http
or https scheme, case, and trailing '/').
I have a couple of questions:
How can I add multiple redirect_uris to my app?
Why is Google identifying my app as "Project Default Service Account" rather than "My Hobby App"?
It's actually easier than you think, unfortunately, it took me a couple of hours to figure it out.
How can I add multiple redirect_uris to my app?
Normally when you add multiple links to something on Google or elsewhere you separate it by , or ; but with Redirect URIs you have to use a new line, it's actually not very intuitive. So when you press the Edit Settings button, you can add to the URI and/or Origins if you have a couple more links, separated by newlines (enter).
No need for complicated app configurations or new keys.
Why is Google identifying my app as "Project Default Service Account" rather than "My Hobby App"?
On your second question: You have to go to the "Consent Screen" tab to change your app info such as your PRODUCT NAME, HOMEPAGE, LOGO, etc.
This answer may not be an exact answer to the question, but I think this might help those who are using Google OAuth for the first time and are wondering why their multiple URIs are not being recognized.
We use the redirect URI at 2 places in the code. First time, while fetching the auth code and a second time, when exchanging this code for an access token.
In the Google docs, it is clearly mentioned that the response for the auth code request(1st request) will be sent to the redirect URI. So, if you make the request from an endpoint A and specify the rediredt URI as endpoint B, Google will send the auth code to endpoint B. This is clear and worked fine without any errors.
Coming to the second request, the documentation is somewhat ambiguous. The redirect_URI parameter is described as below:
redirect_uri: The URI that you specify in the API Console, as described
in Set a redirect URI.
This is where I made a mistake in understanding how this works. Following a similar approach to the first call, I used a third endpoint C and passed this endpoint C in the redirect_URI parameter while making the second call. I got a URI mismatch error although my endpoints B and C are specified in the API console.
The problem is that, unlike in the case of first call, the response to the second call comes to the same endpoint from where the request is made. I made a request in python like below:
r = requests.post(token_endpoint, params)
r has the response with the token.
I was getting a URI mismatch because, I am supposed to use the same redirect_URI in both the calls.
So, for a single OAuth request, we need to use a single redirect_URI.
But then, that brings up the question, why are multiple redirect_URIs allowed in the API console for a single app. I am assuming that if we need to make multiple pairs of authCode-token calls in the same app, we have the leeway of using multiple redirect_URIs.

Protect Web API from unauthorized applications

I am working on a web page that uses a lot of AJAX to communicate with the server. The server, in turn, has an extensive REST/JSON API exposing the different operations called by the web client.
This web site is used by both anonymous and authenticated users. As you might expect, the web service calls issued by authenticated users require authentication, and are thus protected from unauthorized users or applications.
However, the web site has a lot of features that require no authentication, and some of these make use of anonymous web services. The only way I am using to prevent outsiders from calling this web services is by using a CSRF token. I know, the CSRF token is not very useful in this regard... with some time in hand, you can figure out how to consume the web services even if they use a CSRF token.
Of course, you can use a CAPTCHA to prevent applications or bots from autonomously using your web service. However, any human will be able to use it.
Sharing a secret key between client and server, on the other side, would be useless. This, because of the ability of any outsider to read it from the web page source code.
I would like to make these web services as difficult to invoke as posible to any 3rd party application. What would you do besides using the CSRF token? It sounds a little stupid, but hey, maybe it is stupid and I am just losing my time.
Note: given this application uses a browser and not an "executable" as the client, this question is irrelevant to the discussion. I cannot use a secret between server and client (not to my knowledge, at least)
I would take a few steps.
Force https on the site. Automatically redirect any incoming http requests to https ones (the RequireHttps attribute is handy for this)
Each page needs to (securely, hence the https) send a one-time use token to the client, to be used for the page. The script running on the client can hold this in the page memory. Any request coming back sends a hashed & salted response, along with the nonce salt. The server can repeat the steps with the saved token + salt and hash to confirm the request. (much like explunit's answer above)
(It's worth noting that the secure request from a client isn't being authenticated from a user account, merely a token sent with the full page.)
The definition for one-time could either be session or page load, depending on your security vs convenience preference. Tokens should be long and expired fairly quickly to frustrate attackers.
The SSL + Hash(token + nonce) should be enough for your needs.
This is interesting. Below is a crazy suggestion. Remember, your question is also equally crazy.
Your website, once opened through a browser, should generate a long polling connection (Comet programing). This will create a unique session between the browser and the server. When ur JS is making the ajax call, send some token (unique token every time) to the server through the long polling thread. Let the AJAX also send the same token. At the server, get the AJAX token and check whether you have a similar token in you long polling session. If yes, fulfill the request. Any coder can break this. But, it won't be easy. Chances are the freeboarders won't even see these second piece of comet code. You can implement the comet code in such a way it is not easy to detect or understand. When they call ur service, send a 'Service Unavailable' message. They will be confused. Also make the comet code https.
You can also check how long that long polling thread is open. If the session was just opened and you get a ajax call right away, you can assume it is a 3rd party call. It depends on ur website flow. If ur Ajax call happens after 1 second of page load, you can check for that pattern on server side.
Anyone coding for your public api, will have 1 to 2 secret checks that they wouldn't even know and even if they know, they might be discouraged by all the extra coding they have to do.
You might have an easier problem than the one described in the linked question since you don't need to distribute a binary to the users. Even if your app is open source, the HMAC/signature key (in the "Request Signatures" part of that answer) can be controlled by an environment/configuration setting.
To summarize:
The secret key is not actually sent between client and server. Rather, it's used to sign the requests
Be sure that the requests include some unique/random element (your CSRF key probably suffices) so that two requests for the same API data are not identical.
Sign the request with the secret key and append the signature to the request. You linked to a PHP question but not clear if what language you're using. In .Net I would use a HMAC class such as HMACSHA256.
On the API server-side use the same HMAC object to verify that the request was signed with the same secret key.
Maybe you could use counters to keep track of conversations. Only the Server and Clients will be able to predict the next iteration in a conversation. This way, I think, you can prevent third party applications to impersonate someone (Just an idea though).
At the beginning, they start talking at some iteration (i=0, for example).
Every time the client requests something, the counter is incremented by some number in both the server side and the client (i=i+some_number).
And, after a few minutes of no communication, they both know they have to reset the counter (i=0).
This is just an idea based on the concept of RSA and also placing Fraud Detection on your system. The Risk from Authorized users is minimal however they can attempt to make anonymous calls to your web-service too.
For UN-Authorised users : For each web-service call , generate a token say using RSA which changes after some time(can be configured say 30 min). This way prediction of code is minimized. I have not heard of RSA collision till now. Send this token back to the user for his browser session. For further security , we might want to attach a session id with RSA token. Since session ids are unique new anonymous calls would require new session id.
Calls can be tracked using Auditing mechanism. Also per-web service there can be a different RSA setup. How the Algorithm for Fraud Detection would work is a challenge by itself.
For Authorized Users :
Every user should be tracked by his IP Address using Header block. The RSA token principle can be applied.
The solution is very vague but worth considering.

Securing AJAX Requests via GUID

I'm writing a web app that will be making requests via AJAX and would like to lock down those calls. After a little research, I am considering using some form of random token (string) to be passed back along with the request (GUID?). Here's the important parts of my algorithm:
Assign a token to a JavaScript variable (generated server-side).
Also, store that token in a DB and give it a valid time period (i.e. 10 minutes).
If the token has still not been used and is within it's valid time window, allow the call.
Return requested information if valid, otherwise, log the request and ignore it.
With an eye toward security, does this make sense? For the token, would a GUID work - should it be something else? Is there a good way to encrypt variables in the request?
EDIT:
I understand that these AJAX requests wouldn't be truly "secure" but I would like to add basic security in the sense that I would like to prevent others from using the service I intend to write. This random token would be a basic, front-line defense against abusive calls. The data that would be requested (and even submitted to generate such data) would is HIGHLY unlikely to be repeated.
Maybe I'm wrong in using a GUID... how about a randomly generated string (token)?
If you are doing this to trust code that you sent to the client browser, then change direction. You really don't want to trust user input, which includes calls from js that you sent to the browser. The logic on the server should be made so that nothing wrong can be done through there. That said, asp.net uses a signed field, you might want to go that way if absolutely necessary.
Expanding a bit:
Asp.net tamper-proofs the viewstate, which is sent as a html hidden field (depending on the configuration). I am sure there are better links as reference, but at least it is mentioned on this one: http://msdn.microsoft.com/en-us/library/ms998288.aspx
validation. This specifies the hashing
algorithm used to generate HMACs to
make ViewState and forms
authentication tickets tamper proof.
This attribute is also used to specify
the encryption algorithm used for
ViewState encryption. This attribute
supports the following options:
SHA1–SHA1 is used to tamper proof
ViewState and, if configured, the
forms authentication ticket. When SHA1
is selected for the validation
attribute, the algorithm used is
HMACSHA1.
A link for the .net class for that algorithm http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.hmacsha1.aspx.
Update 2:
For tamper-proofing you want to sign the data (not encrypt it). Note that when using cryptography in general, you should really avoid using a custom implementation or algorithm. Regarding the steps, I would stick to:
Assign a token to a JavaScript variable (generated server-side). You include info to identify the request and the exact date&time where it was issued. The signature will validate the server side application issued the data.
Identify double submits if appropriate.
That said, the reason asp.net validates the viewstate by default, is because devs rely on info coming in there as being handled only by the application when they shouldn't. The same probably applies for your scenario, don't rely on this mechanism. If you want to evaluate whether someone can do something use authentication+authorization. If you want to know the ajax call is sending only valid options, validate them. Don't expose an API at granularity level than the one where you can appropriately authorize the actions. This mechanism is just an extra measure, in case something slipped, not a real protection.
Ps. with the HMACSHA1 above, you would instantiate it with a fixed key
It really depends on what you're trying to accomplish by security. If you mean prevent unauthorized use of the HTTP endpoints there is very little you can do about it since the user will have full access to the HTML and JavaScript used to make the calls.
If you mean preventing someone from sniffing the data in the AJAX requests then I would just use SSL.
A GUID used in the way that you're suggesting is really just reinventing a session id cookie.
"Securing" is kind of a vague term. What exactly are you trying to accomplish? Using a GUID is a perfectly fine way to prevent duplicate submissions of the same request, but that is all.
If the information being passed between the client and server is truly sensitive, you should do it over HTTPS. That's really the only answer as far as securing the actual communication is concerned.
Edit: To answer your question regarding whether a GUID is the "right" way - there is no right way to do what you're suggesting. Using any token, whether it's a GUID or something of your own creation, will not have any effect other than preventing duplicate submissions of the same request. That's it.

Resources