Problems with Disqus OAuth2 flow - javascript

Since posting on the Disqus disqus forum seems to be a waste of time, maybe someone here can help.
I'm trying to use the OAuth2 flow to connect a Disqus user to my app's account system so I can monitor their activity (posts/comments/etc). I'm using Meteor for my app. I'm calling the OAuth2 authorize endpoint from my server code and passing the resulting HTML back to the client for rendering. This all works fine. But I'm seeing 2 problems on the client side. First, the HTML code returned from Disqus seems to be designed in a full page and the username/password fields extend across the entire window. I was expecting a dialog/modal popup like the one that Disqus provides when logging into a forum. I tried wrapping the HTML inside of a Boostrap3 modal window which mostly works except the username and password fields extend off the right side of the dialog box.
Ignoring the ugly UI the second problem is that when the user clicks on the submit link Disqus puts up and error page titled 'CSRF verification failed (403) - DISQUS'. I'm guessing this may be because the OAuth2 call was made from the server and the submit is coming from the client. If I copy the OAUTH2 url directly into the browser everything works fine. But I don't want to expose my API key and resulting code on the client side since that seems like a security risk.
All I really want to do is verify that the user is trying to connect their own account to my app (and not some other user). I'm not posting with their account so I don't need an access token (I'm calling user/details which just takes the API-key). So I've thought about creating a forum for my app and using the login endpoint to verify the username/password combo. But that dialog doesn't explain the scopes I'm asking for.
I've also considered building my own dialog box to prompt for the username/password, sending those back to the server and have the server "fake" the submit back to Disqus. But that is not a maintainable solution since Disqus might change the expected fields at any time. And it is ugly as sin.
Anyone have any suggestions? I didn't post any code since I don't believe it is a coding problem (and the code is a bit convoluted). But if anyone thinks it will help you help me, I'll be happy to post it. And, yes, I'm aware that not posting the code violates StackOverflow conventions. But I'm taking a chance that the powers that be will allow this post since Disqus support is non-existant and I don't know where else to reach out.

The basic problem was that I was using 'request' with forwarding enabled so that instead of getting the Disqus URL I was getting the Disqus authentication text. You need to render the authentication URL in a window, not the contents. That fixes the CSRF problem.
The next problem is that the URL returned by getAuthorizationUrl is bad. It is of the form 'nullhttps:...'. No idea where the 'null' is coming from, but stripping it off fixes that problem.
To make things easier for anyone looking to do this, there is a shiny new version of the Disqus NPM that includes OAuth authentication methods at https://www.npmjs.com/package/disqus.

Related

coinbase oauth authorization returns html, how to integrate with my web-app

So, I am creating a web-application that works with coinbase. The front-end is a standard static page with html and jquery, this is very vanilla. The back-end is a separate web-app that is made with Spring 5 and has a bunch of RESTful web-services.
I go to my login.html and I login. That means I send the username/password back to my login Spring Controller, and I get an access token sent back to the UI. I put that in a cookie, and then I reload a new page with a big fat authorize button on that page.
That button does an AJAX call to my Spring RESTful controller passing in the token, as i wanted to make that endpoint secure which works great.
On the back-end (or middle-ware), I am making a RESTful call to Coinbase to start the process of Oauth2 authentication. I read in my client-id from a properties file, I pass in the redirectURI, and a state. All this works great, it gets to coinbase, and the response is HTML. I pass that back to my client, the front-end, and I have this HTML which is the coinbase authorization page.
Now here is where it gets dicey ... I am a back-end person, so I can make that RESTful call on the back-end with no issue. I get the HTML, which is supposed to be the AUTHORIZE page to allow the user to let my web-app be used with their coinbase account. I get HTML and now I am at a loss as the correct way to display this html on my page or a new page. This is my lack of javascript and jquery knowledge.
The AJAX code in my authorize.js looks like this:
$.ajax({
url : 'http://localhost:8080/myapp-be/api/coinbase/authorization',
headers : {'mytoken' : mytoken},
dataType: 'html',
cache: false,
success: function(response) {
$("html").html(response);
}
});
Is this the correct way to go?
I absolutely can take the coinbase call put it in my browser, and it pops up the Coinbase Authorization dialog box easily. If I authorize, putting in my username/password, I am sent to the callback page which I passed in as the callback redirect uri.
But, it was my understanding, that we did not want to expose the client-id to anyone. That is why my back-end does it, and we just return the HTML. So, I am a held up here.
With my current code, I get many Javascript errors, and I just know this isn't the way to go. I get a lot of CORS issues, and when I try to authorize I get an error that it can't get to the correct page.
How would one correctly call the Coinbase authorization API. Their documentation page:
https://developers.coinbase.com/docs/wallet/coinbase-connect/integrating
Shows in Step 1:
GET
https://www.coinbase.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URL&state=SECURE_RANDOM&scope=wallet:accounts:read
So, sadly, I am a little confused on the best way to solve this issue.
Either I make this GET call from the client exposing client-id, if that is ok?
Or, I can figure out the correct way to display the HTML coming back for the Coinbase Authorization page?
Thanks for the help!
So, it's been a very long while since I have had to do any UI work. I've never had to worry about cross-scripting or iframe issues or security issues relating to the front=end (UI).
From what I am gathering, pulling HTML from a third-party website onto a div, or into an iframe on my web-site is not the best plan. I can tell you that even though I did pull the HTML into the web-page on my site, there was a ton of javascript errors and CORS issues.
Ultimately, my ajax call to my middle-ware was changed to just pull back the coinbase authorization URL. A simple windows redirect and there I was on the coinbase web-site as it should be. Once I did the authorization, then I was redirected back to my redirect link that I told Coinbase to do.
So, getting the link and doing a simple redirect worked. Loading HTML from a third-party site into my web-pages did not. Lesson learned!
Thanks! Hope this helps someone else out.

How do i remove the authentication modal in pouchDB

I'm having a big Problem. Whenever I'm connecting to Cloudant via PouchDB a nasty modal pops up that asks for authentication. I'm using PouchDB's authentication Plugin and the responsible command for this NOT TO HAPPEN. But somehow it still does. The modal keeps popping up, no matter what I do. It shuts down my whole production and I've been trying to solve this for days now.
I have an example on GitHub.
Help is very appreciated! Thanks! :)
You need to rename "Basic" in the WWW-Authenticate header your server sends to something the browser is not hard-coded to recognize and react to. I know nothing about cloudant, but it looks like their docs route back to couchdb for manual configuration so hopefully they have identical configuration for this.
For couchDB, changing the Basic to Basicfoo suppresses the browser authentication windows when pouchdb hits the URL with Authentication.
(You can also look for other solutions particular to your DB and any proxies you might be using now that you know you want to change Basic in the WWW-Authenticate header, for example this one has a solution for nginx.)

Single Page App w/ Login Page

I have been doing some research on this topic but can never find anything super relevant. I am looking to create a single page application using Polymer. I am building this around a REST API that requires authentication to view is resources.
I have all the details with API worked out but I can't seem to figure out how to handle a login page. Basically what is the best way to keep a user from seeing content without being logged into the application?
Obviously the REST API won't allow data to return to the client but how do I go about preventing a user from going into DevTools and changing some boolean values and being able to navigate through all of the pages, and receiving the 401 errors from all of the Ajax requests trying to fire?
I appreciate any help that I can get! Thanks!
You can't prevent users from changing stuff in DevTools. Just ensure on the server that the user doesn't get data or isn't able to pass data without being authenticated.
Issue a token when the user passes username and password and on the server allow only what the user assigned to this token is allowed to do.
See for example https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/

How to stop from data post from browser console?

I have been thinking over this issue from past few months. Recently, I have started with complete JS Built front-end, where the forms are posted using Ajax.
I have a doubt, how to recognize on the server side, from where the data is coming from. Is it coming from actual form event or it is coming from browser console.?
What I have tried:
Creating a two way handshake: Before posting the form, the Application will contact the server, and the server will send a token inside the cookie, which will be sent back with the form post. But, even if we post by browser console, that cookie will go carrying the token. So, Failed.
Binding Hidden Field: But if someone, is posting the data from browser console, he would definitely look for the hidden fields as well. Basically, he'll replicate my AJAX to send the same request, in the same fashion. FAILED!!
I am not able to figure out this part. Can anyone help?
Thanks in advance.
Rule #1 of programming for the Internet: Never trust anything from the client. EVER.
Rule #2 of programming for the Internet: Never trust anything from the client. EVER.
Rule #3 of programming for the Internet: You can not make the client trustworthy.
I know the first rule is duplicated twice, but it is worth it.
There is simply no way to do what you intend to do.
A person who wishes to send data to your server, via an AJAX request or a POST request, can easily do any of the following:
Modify the form using browser tools or a proxy and force-feed in whatever information he wants.
Capture the entire transaction, through a tool like fiddler2, and change the values and re-send them. No browser needed.
Modify the code running from your site to send (or allow) whatever data he wishes to send.
Use a tool like Curl to fake an browser and send whatever information he wishes to.
There is simply no way of knowing, on your server, where that information came from.
From a security point of view, you simply can not trust anything -- ever.
Validate the credentials, give the user a login token (usually a cookie) and then still be suspicious of everything the client sends you. If there is something that shouldn't be changed or updated, make sure your back-end doesn't allow it to be changed or updated.
We have tons of code in our application that looks like this:
if (user.HasPermission("MayUpdateFirstName") {
record.FirstName = FormData.FirstName
}
That way, if FirstName is passed in, and the user can't modify it, then it doesn't get modified.

Gmail get messages and post them to a server [google app script?]

I need to get some spam messages from a set of gmail inboxes and post them to a server.
My initial idea was to write a chrome extension, which when installed would be activated every time the user visited its inbox, but I couldn't do it that way, since there is no access to spam messages (just unread ones through a XML file).
Then I discovered google APP script and succesfully wrote the script I needed.. but the problem is, how can I use that script for other accounts? At the moment a user needs a lot of configuration to make it work (script has to be shared, user has to install google app script, set a trigger for the function).
IS there a user friendly way to make this work? Even in other ways? I have no access to inbox passwords though.
Thanks in advace.
You should design a User Interface, deploy your app as a webApp with parameter 'run as user executing the app' and add the trigger creation in the script itself.
All this should not be too hard...
Feel free to ask for assistance if you meet some issue.
In this case don't forget to post your code if you want useful tips.

Categories

Resources