In the application I am currently developing we are using ASP.Net forms authentication to grant the user further access to the site. This site is targeted towards mobile users and as such we are attempting to be as hands off from the server as possible and make use of KnockoutJS to make the web service call and load the data so that the user can view it.
Right now the webservice (REST service using GET method) requires the username in order to load the data specific to that user. I have this information on the server side (ASP.net) and I can easily access either User.Identity.Name or access the forms authentication cookie directly and pull the information.
My problem is that I need to get the username from the server to the client so that the service call can be made. I have looked into doing this securely but so far have come up blank. Currently I am passing the username as a url parameter and parsing it out using JavaScript, with a check on the Page_Load method to verify the username in the url matches the logged in user.
I need a way to secure pass a username from ASP.Net that has authenticated the user using form to the client side JavaScript so I can make a REST webservice call.
EDIT: So after googling and meeting with my team lead I think we will be using an OAuth implementation similar to this example:
http://www.c-sharpcorner.com/UploadFile/surya_bg2000/secure-wcf-restful-service-using-oauth/
Also for anything else looking for the same answer I found this question very helpful in understanding OAuth:
What's the point of a timestamp in OAuth if a Nonce can only be used one time?
Assuming everything is implemented correctly would it be more secure (totally secure, secure, or more insecure?) to instead pass the generated signature via an ASP tag as mentioned below?
EDIT 2: After some more review and some more searching we finally decided on a framework and method of making this work. As it turns out OAuth isn't necessarily the answer here, this questions:
But Seriously.... Example of ASP.NET WebAPI implementation including OAuth
was a lot of help as well in figuring out how to make this work. What we are going to end up doing is generating the signature and putting in on the javascript and making the call like that. The signatures are going to be time sensitive and regenerated each time the user loads the page so very OAuth like but we arent implementing the full spec.
TL:DR Final solution was to generate a hash signature and put it on the page via ASP server tag <% aspvar_here %> and use it to validate the service call
Simplest way would be to render this javascript in your page:
<script type="text/javascript">
window.UserID = '<%=HttpUtility.JavaScriptStringEncode(this.User.Identity.Name)%>';
</script>
Now you can reference it in your JS.
But, more importantly, if this user id is not used just as a default parameter but instead to authenticate the user, this is a security hole. Normally the REST service should also be able to look at User.Identity.Name instead of receiving it as a argument.
Normally the username is provided by the client to begin with. It is then verified on the server-side (using whatever authentication is necessary, such as a password).
If it has been verified on the server side (in your case, this must be from a WCF web service as ASMX does not cope well with REST), then you can be sure that it is correct - plus you already have the username on the client-side.
EDIT:
As Knaģis pointed out, you can get it using an ASPX tag, presuming the page is an ASPX page and not HTML.
If you just want to have the username in the client side, the other answers explain how to do this.
But as you stated, this IS a security risk. Someone can modify the data on the client and impersonate another user.
The correct way to do this:
After a user successfully logs in, a Guid is issued which uniquely identifies this user.
The Guid is the token which is saved on the client and passed to the server not the username.
All webservices receive the Guid not the username.
Server has a dictionary which converts the Guid to the original username.
Another option can be to encrypt the username and pass the encrypted value to the webservice. The webservice will need to decrypt the value in order to get the username .
Related
I've made a simple webapp that is going to show some data in a table, which will be updated weekly.
This update it done in the backend with some python code, that scrapes and alters some data, before putting it in a SQLite database.
After doing some reading I learned that to deliver that data to my webapp I should make a API with Flask, that can take that data and deliver it to the JS in my webapp in form of JSON, which then can use the data to populate the table. However, I should secure my API with username and pw. But as its a JS frontend that will retrieve data from the API, there is really no point, as the username and pw will have to be hardcoded into JS, which then can be read by the users. (I think)
Should I expose my API to everyone, or is this not the way to go to be able to use SQLite data as a backend for my webapp? I am fine keeping the API to a GET only.
You are correct, it is pointless for you to secure your API. Securing an API is only needed in certain circumstances.
If you are accessing data that you don't want anybody to see, perhaps through a backend call, then it would make sense to add in some form of security (normally an API key or Authorisation tokens in your request headers).
However, if you are making calls from your front-end (i.e. client side) to a backend API, then there is no point putting additional security there as the user can already see the request and already has access to the data the API is returning - so by securing it you are achieving nothing.
Normally, if the page the user is visiting contains sensitive data that you don't want everyone to see, you would take steps to secure your website instead (for example protecting it with a login for username and password before you can access that page). If you were to take this approach, where the website is protected by username and password, then you can update the API to make sure it does not respond to requests where the user is not authenticated (e.g. by generating a session token or something unique for each logged in user).
If you have a look around on websites that have lots of free data available, you will find they all have front end API calls that are completely unsecured (because it is pointless if the data is already free to access). Some websites do take steps to try to make sure it is their own website that is calling the API, but even then it is a bit pointless as web scrapers can always extract the data from the HTML.
Take a look at this page which outlines authentication headers. This simpler route is to hard code the header info in Flask to make it a little more secure. You could also try the more involved route of reading header info from your db. What's currently working for me to read from postgres db is below so you may modify it slightly for sqlite.
def valid():
headers = request.headers
auth = headers.get("X-Api-Key")
user = User.query.filter_by(apikey=auth).first_or_404()
print('from search of db ',user,'',auth)
return str(user)
As you mentioned, you plan to show a public data - then it can be used even
without authentication. Otherwise I think it can take too much unnecessary time spent on that.
As you have just a simple and single table from database, I believe that you don't need an API. You can just create HTML template and render it with data. Some examples can be found here and few more here.
So I am creating a website to learn some PHP/Javascript/HTML/CSS and so on and I ran into a problem to which I can't come up with a solution. So basically I have regular login form using PHP which uses POST to send the data and authenticate. I also want to integrate external Twitch.tv OAuth2 authentication.
By using normal PHP login I store my information inside PostgreSQL database using php. I want to do something similar using OAuth2. For example store Twitch.tv name as a username inside the database and token as a password.
The problem is that the external authentication I am using is based on their Javascript API and it stores the information inside the DOM storage which I found is unable to be access by using PHP. The redirect_uri with a token is also a fragment which can't be retrieved by PHP.
Should I just scrap the JS part and try doing it entirely in PHP?
Side question: I checked other website which also uses Twitch authentication and it uses these callback links "https://api.nightbot.tv/auth/twitch/callback?code=****". What exactly are these callbacks?
You should use redirects as you implied with JS frameworks. It works the same with Facebook.
The redirects are used with a token. Usually you generate on your side a random token that you store in the session.
Once the user logs in using the JS API, the API will redirect to a callback page (PHP in your case).
In that page, you verify the token once (that you had passed and got back, must be the same), and also you get another token from the API to use with the API.
At this point you can get the user information by querying the API using the API token.
You get the user info from the API and then you can query your down DB at this point to log the user in etc.
I hope this helps..
I am trying to integrate an unbounce account with a salesforce account, I can get the leads generated across to salesforce fine, however the form used is js, and I have the option to add custom js to the page.
What I want to do is setup hidden fields in the form that posts and then use js as custom code to extract the referrer from the url + the source from the query string and to split the 'name' field into 'firstname' 'lastname'.
What i am wondering is as this code is client side no server side option available, is it making our salesforce account vulnerable in any way?
what is the worst that can happen
disclaimer not a coder just a basic understanding
thanks
If you are only using JavaScript to read and parse the referrer, you're just modifying information that's already in the URL. This is publicly available information, so no security vulnerability.
On the other hand, if you are accessing your SalesForce account via some sort of API or other function calls in page code, we need more details before answering your question adequately.
The js is simply gathering data and then being submitted with the form, from what i understand the sending of the form details including the hidden fields are then done server side with ruby
So assume I'm using some external API, where I'm required to send it an ID and passkey such as http://whatever.com/api?id=asdfg&key=_hjkl&request=whatever
I'm going to need to have that ID/key stored somewhere and I could get away with not exposing it to the user by putting it in a database or something, but whenever the request is actually shot off is there no way to hide it?
No, there isn't.
If you want the client to authenticate against a service, then the client has to have the authentication credentials. Anything you give to the client, you also give to the user of the client.
If you want to add some kind of protection, then proxy it though your own server or use a time limited token - but keep in mind that anybody can still hit the appropriate end points to get access.
If you are giving data to the client, then you are running a public API and it is best to think of it in those terms.
If the api provides a POST method, you can use that, without having to show the parameters.
Using POST method to hide URL parameters
I have a static website without any server side languages.
Is it possible to pass some custom values whenever a user tries to login then get the data back when the user successfully signed in and comes back to my website from facebook?
I've read about signed_request, but that requires PHP.
You're essentially asking if Facebook will store data for you.
Unfortunately, the answer is no. You need some kind of mechanism on your server that can match a Facebook user to the data you need stored.
You could use local storage, but that's obviously local to the browser and prone to tampering.