I'd like to grab a client IP address using javascript and send it over to my server using AJAX request. Any suggestions on how I can achieve this would be awesome. Some code example would be even better.
Thanks in advance!
Front-end Javascript by itself doesn't have access to anything that will tell it a user's IP address. See here:
How to get client's IP address using JavaScript?
However, like it says in that answer, there are APIs you can use to get the IP address.
More importantly, though, any server receiving your AJAX request will have automatic access to the IP address. So if you can set up code on the server you should be good to go, or at least will have a different question.
If you don't have control over the server, and instead are doing something like POSTing data to a webforms API, then using an API is your best bet.
Client-side JavaScript has no access to the network addresses. What you're specifically asking for isn't possible.
You can determine the closest routable address for the client server-side, but this could always be an upstream proxy or NAT router.
Related
I have a regular website with no login process. There was never anything on it that needed to be private so I'm using http. However I recently added an "E-mail Me" form, and some people might include sensitive information emailing me.
If the data is sent to my server with an Ajax $.post, can the data be read by someone watching the network traffic?
If so, Is there anyway I can secure it without switching to https?
OK: So def Yes to no 1.
For everyone that said no, why can't I use my own public-key/private-key for this?
If the data is sent to my server with an Ajax $.post, can the data be read by someone watching the network traffic?
Yes, for sure
If so, Is there anyway I can secure it without switching to https?
No, not really/practically.
You will need to use https, there is no other way to truly secure the information
The short answer is NO.
The long answer is that if you use js, the person monitoring the traffic will be able to know how you encode the data and easily decode it. If you use server side language (C# for example), the data will be transmitted as plain text to the server so the person monitoring the traffic will be able to read it clearly.
The only way is that you use a secure connection (HTTPS)
Let's say I write a piece of code that makes an http call to a web api, something like:
$http.get('www.myapi.com/api/controller/endpoint').then(function(resp){...})
I then give this code to two people that live in different cities and they hit my API from their respective houses (just from some browser). What information can my API get out of the http request that will allow me to tell apart person A and person B calling it? Is the IP always available? Is the MAC address ever available? What else is there?
How can person A pretend to be person B when calling my API?
Furthermore, what if person C calls my Web API from their own Web API (backend)? Will the same information be available, or what will be different?
This is a general question, but if you want to get specific, let's assume ASP.NET Web API 2 is receiving the http requests.
You're describing a desire for pre-authentication.
The IP will always be available. You could restrict the service to only those IP ranges. It's not a good way to do authentication.
Trying to get around having to perform authentication is not safe. You should use a proper authentication method. Combining IP restrictions with other methods is fine.
John Meyer's answer is essentially pre-shared token based user authentication. Having a valid token constitutes being constantly logged in. The token can be compromised far more easily than a typical token based user authentication that establishes a temporary token with a limited lifetime.
If you decide to go the pre-shared token route, please use a method that supports proper rotation or permutation of the token over time, such that it isn't vulnerable to replay attacks.
Your best option for this scenario is typical session-token based user authentication.
If you're actually not interested in who is using your service, only that they be uniquely identified, you can safely establish a session (or permanent, or arbitrary lifetime) cookie per user by the http Set-Cookie header that all clients should automatically respect and support, then use that as your method of tracking.
My team has accomplished this by requiring that an identification header be included on all requests. This does require some customization on the part of the calling party, but does not necessarily require that the user be logged in. Of course, the value of the header could be change by malicious users so if these calls need to be very secure you will need traditional authentication.
you seem really confused about this. what you are looking for is called authentication.
as you tagged C#, i am assuming you are developing your api in C#. I recommend checking Web Api.
there are a couple of authentication methods available these days. if you are developing a rest api, you can use json web tokens.
you can get a lot of information about the client calling your api via http headers.
I think you can always go with fully authenticated. I see your desire to go for a semi secured set of endpoints but I don't think any of the approach would serve you best. MAC, ip, user-agent, custom fields anything can be spoofed to be honest. Going with a bearer token or session token is your only bet here. For public apis you can limit user requests based on ip or you can try finding out whether a specific ip is trying to exploit you and thus block it but finding true identity might not be possible anyway.
I have some values being sent from a server as a JSON object to a JS client. What is the best way for the client to validate that the response did indeed come from my server? I want to prevent users from using the client to connect to a different server.
I am aware that a user can change the JS of any page, but I expect that looking through thousands of lines of obfuscated JS is much harder than just setting up a fake response to pass new values into a client. Verifying the response is just an extra layer of security. It is not intended to provide perfect security, but simply an extra layer of protection against misuse.
You can use SSL for this. If your JS client validates the server SSL certificate, you will know for sure that the response is truly from your server.
I'm currently working on a small JavaScript library which makes requests to a REST web service. Since the server side needs to log incoming request to measure the number of requests, I want to secure it somehow. The library is very similar to the Google Maps API. So my question is now, is there some way to secure it better then just adding an API key to the libraries requests? How can I ensure, if that is even possible, that only the 'right' client uses the key? I guess I could compare the referrer url to a set of valid urls, but this can be spoofed to right? Please keep in mind that is impossible to use some else's authentication method (facebook, google, twitter etc.) since it has to work without user input.
Cheers,
Daniel
A decent RESTful approach would be to require an Authorization header to be supplied by the client, matching some scheme that your server will accept (see Basic Access authentication as an example). Seeing as you only wish to validate that your client is the one making the request, you probably don't need too complex an authorization mechanism.
I like the way Google Maps' api is consumed, using a script include, but I'm worried:
My api is "semi-private", that is, accessible over the internet but should allow for secure transmission of data and some kind of authentication. The data should remain private over the wire, and one consumer shouldn't be able to get at another's data.
How can I use SSL and some kind of authentication to keep the data secure, but still accessible "horizontally" from a plain HTML page with no server-side proxy required? Do I need to manage keys? How will the keys be posted to the server without being intercepted? Can I use OpenId (or some other 3rd-party authentication) to authenticate api users, or do I have to create my own authentication mechanism? I've been all over Google and can't find a good guide to designing and deploying my API securely.
Right now I'm using REST and AJAX to consume them, but cross-domain calls are impossible. Any help or a pointer in the right direction would be much appreciated.
I'd probably use a dynamically-generated script tag with an SSL URL that included a key in the query string that was public-key encrypted. The server would use the private key to decrypt the query string parameter and return script that included the relevant information (or didn't, if the key was invalid). Or something along those lines. But I'll admit that I haven't actually had to do it in practice.
I'd also look for prior art, like Amazon's S3 service.
So:
User provides secret
Client-side code uses public key to encrypt the secret
JavaScript appends a script tag that includes the URL
Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.
You may well need two cycles, because otherwise the request to the server could be re-used via a man-in-the-middle attack. That would be:
JavaScript appends a script tag that requests a unique key (probably with some confounding information, like the source IP and some random further key)
Server responds with a one-time key tied to that IP
User provides secret
Client-side code uses public key to encrypt the secret, including the unique key from #1
JavaScript appends a script tag that includes the URL
Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.
The response could well be encrypted (to some degree) using the random key included in #1
None of which I've actually done. (Or have I? BWAa-ha-ha-ha...) FWIW.
OAuth might help with this situation by having the user login to the 3rd-party application and allowing your application to access the 3rd-party on their behalf by using a request token when you make xhr requests. http://oauth.net/documentation/getting-started/
========
The reason for using a server-side proxy boils down to the Same-origin policy built into web browsers: http://en.wikipedia.org/wiki/Same_origin_policy
Essentially the browser only allows requests to be made to the address in which the page comes from (e.g. facebook.com can only make requests to facebook.com URIs). A server-side proxy solves this issue by making requests to servers outside the current origin. Server-side proxies are also the best practice for making requests like this.
Check out the opensource javascript Forge project. It provides a javascript TLS implementation that allows secure cross-domain xhr requests. It might be of use to you:
http://digitalbazaar.com/2010/07/20/javascript-tls-1/
http://digitalbazaar.com/2010/07/20/javascript-tls-2/
https://github.com/digitalbazaar/forge
One potential solution:
Set up an Apache server to run your site.
Get an SSL certificate for your site.
Install the apache mod that comes with Forge to setup a cross-domain policy that allows other sites to access yours.
Host Forge's TLS implementation on your site along with your site's certificate in PEM format.
Tell other sites to include the javascript from your site and use it to make secure calls to your site to do whatever it is you want to.
(3rd party) Page uses OAUTH or something similar to authenticate the user and get a token from your server.
Page loads an IFRAME from your server via SSL passing the token along for authentication.
The IFRAME can communicate securely to your server via SSL
Use easyXDM or something similar to communicate between the IFRAME and the 3rd party page, using some limited RPC-like or socket-like API you create.
Or if you really don't trust the third party - do your authentication inside the iframe (no need for oauth then, just use a plain html form) and communicate anything the outer page needs to know about the user using easyXDM.
Not too sure of what the question is exactly, I take it you're attempting to do a jsonp-like call to [https://secure.com] in order to process/display data on [http://regular.com]?
Can the two servers talk to each other? How about something like this:
User logs in on [https://secure.com]
Upon authentication, secure.com generates an token (lets call it syntoken) and passes it directly to regular.com (server-to-server), maybe like a session_id, some arbitrary message, and an otp cipher (lets call it syncipher).
Broswer receives a session_id cookie, and Secure.com then redirects the browser to http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla
Regular.com looks up otp cipher using session_id as a key, and decrypts otpencryptedmessage "blabla."
If decrypted message matches the original message in the syntoken, we can verify user is logged in [regular.com] and regular.com generates another token (lets call it acktoken, lolz) and passes it directly to [secure.com], consisting of session_id, some arbitrary ack message, and a different otp cipher (lets call it ackcipher).
Regular.com then sends the browser a cookie consisting of otpencryptedackmessage (let's name this cookie "verified_session").
Finish loading the page.
From there, you can do jsonp-like calls to
https://secure.com/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value)
where secure.com/getscript.js will take the verifiedtoken, lookup the ackcipher based on the original cookie session_id sent by [secure.com] as the key, and decrypt the otpencrypedackmessage. If the decrypted message matches the ack message, render the script file.
It's kinda like a 3-way handshake. The secret sauce is that the servers have to be able to talk to each other directly to pass secret keys discretely. You don't have to use the same session_id for both servers, I was just using that as an easy point of reference to find a way to access the syn/ack otp ciphers. The ciphers must be completely hidden from public.