Hide a javascript if user comes from an specific location - javascript

I want a javascript file (<script src=" file here " >) to be hidden if a user lets say comes from China.
How can i do it?

I'm Chinese and I reserve all my rights to protest. :)
Actually you have a few options, you can do it front-end or back-end.
Front-end solution
Use HTML5 Geolocation to determine the longitude and latitude of current user and check whether it's within China or not(don't forget to contain Taiwan). The defect is only modern browsers are supported, you should probably set up plan B.
//jQuery, ip-api is a RESTful service, do it in front-end
$.getJSON('http://ip-api.com/json/?callback=?', function(response){
alert(response.country);
if(response.country === "China"){
$.getScript("script_for_Chinese.js");
}
});
Back-end solution
Check the user IP and find out if it's from China(there are a bunch of IP to location RESTful services)
Check HTTP header if the Accept-Language part contains string like zh-CN or zh-TW. This may also hurt the people using Chinese in other countries.
As for example requested, I won't recommend you use front-end solution or IP-to-location back-end solution. The only one that might work is based on http header.
//PHP, if the client accept Chinese, assume he is from China
if(preg_match('/(zh-CN|zh-TW|zh)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'])){
echo '<script src="script_for_Chinese.js" type="text/javascript"></script>';
}

You can try using a geolocation service but considering that you can defeat that by using a proxy (like a hacked machine in the US) somewhere else or by spoofing the request to look like it came from given location it may not do you much good in the end.

Related

Protect PHP endpoints called by AJAX

My app consists of several PHP endpoints which are accessible via AJAX. The problem is they are also accessible via anyone who makes an HTTP request to the same endpoint. I can add checks for HTTP_X_REQUESTED_WITH and HTTP_REFERER as specified in this answer, but these can be spoofed. I could add a secret key that needs to be posted with the request, but anyone viewing the javascript and/or the console would be able to see this key. What is the solution here?
People often think that because they're using Ajax requests regular sessions don't work. They do.
If you have an endpoint to delete something from the database that's visible in the source code, such as:
example.com/user/1/delete
You can protect this request from non authenticated users the same way you would when using a non Ajax HTTP request in the browser. Using sessions. If the user has the privileges to remove users, this route will work, otherwise return an error (or do nothing).
You can also protect an API using OAuth. There's a great document here that explains how it works: http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
Most of the answers are not helpful if you have your app and your api on separate domains for example app.example.com and api.example.com - in that case sessions won't work and you would have to turn to OAuth which is quite a big hammer for such a simple problem.
Here is what I would do:
I assume you have users in a database and a unique identifier like user_id=12345. I also assume that you have your Jobs in a Database and they also have unique ID's like job_id=6789.
First on app.example.com you encrypt both IDs with something fast and easy like Blowfish:
$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id));
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id));
I assume your endpoint would work somewhat like this:
api.example.com/jobs/delete/<job_id>/<user_id>
so now from Ajax you call that endpoint, but instead of calling with plain IDs
api.example.com/jobs/delete/6789/12345
you call it with the encrypted IDs:
api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F
On the API side of your software you decrypt the parameters:
$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>);
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>);
Now you can search your db for uid and jid and perform whichever task you were planning to do. Make sure that a user can only delete his own jobs of course.
I admit this is not a 100% solution, but it leaves an attacker with a lot of guess work - he would have to guess the user_id and a matching job_id, the encryption algo and your secret. It does not protect against running millions of brute force attempts to guess a matching pair, but it put's the odds in your favor (and you should have some sort of quota limitation protection of your endpoints anyway).
Good luck!
There isn't one. If you give someone some data, then they can process it in whatever way they like. You can't control what happens to it after it leaves your server.
Likewise, you can't control what data they send to the endpoint.
it is very important for a developer to put authentication for API or web services. dchacke and BugHunterUK has given perfect answers, I just want show you simple code I use to make very simple and easy to use authentication.
Adding Session for the authentication
you can add session, and session timeout for your APIs so, only your app can use this, you can start session when front page of your app is loaded, you can set timeouts and also restrict the different service for different users by sessions.
General Idea how to do that
<?php
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){
//usertype comprise of what access you want to give
//guest, registered user, stack holder, admin etc.
...
header('Content-Type:application/json;');
echo json_encode($output);
}

Browser addon to automatically opt-in for cookies - EU cookie law

In EU we have this law that requires web pages to request permission to store cookies. Most of us know about cookies and agree to them but still are forced to accept them explicitly everywhere. So I plan to write this add on (ff & chrome) that will automatically add session cookie with standard name that would mean agreement. Just wondering about few things:
1) What should be the name of the cookie? What should be the value? Should I cover only user agreement option? My proposition is
_cookieok=1
the benefit is that it is short, yet descriptive.
2) Should I add only single cookie - the one I suggested above? Many pages do it in different ways already. They use different cookie names and check for different values. I thought maybe use names and values from popular scripts like http://cookiecuttr.com/ but I don't want to increase upload traffic with a number of mostly not needed cookies.
3) Should I differentiate between types of cookies? I have seen here http://demo.cookieconsent.silktide.com/ there are multiple cookie types you can opt-in/opt-out?
4) Does this have chances to become popular or is it better to use something like point 2 - adding multiple values manually?
5) I could probably also remove those cookies after some event (like after all js onload functions have finished) but I could not find proper hook in firefox addons. Plus maybe some people would like to do filtering out of the script on server side so maybe it is better to keep sending the cookie.
Is there something I have not thought about? My suggested code is in case of FF:
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*",
contentScriptWhen: 'start',
contentScript: 'document.cookie="_cookieok=1;path=/";'
});
Update
To explain how does it work
1) Most sites already compliant to cookie law do something like this:
if ($.cookie('_cookieok') == null) {
$('#cookie-close').on('click', function (evt) {
$.cookie('cookieok', 1, 300);
});
$('.cookie-prompt').show();
}
so if we agree on same name existance of such ff plugin would be possible. If someone does not plugin - site will prompt him. If has site would recognize addon added cookie as their own.
Not too sure what the point of this really is to be honest?
If you're looking to build something that would be used across a portfolio of sites you manage, then you're probably pushing your luck to force a user to install an extension simply to show they accept your cookies. If it's aimed at a wider audience, i.e. potentially anyone using any website, then the other issue you'll have is getting both users to see the benefit of installing another extension and secondly website operators to write the code necessary to detect your cookie and act accordingly.
Most sites seem to be striving to make cookies and the associated obligations under the legislation as unintrusive as possible - requiring installation of an extension & changes to website code seems to be heading in the opposite direction..

How to use pure JavaScript to determine whether Facebook/Twitter is blocked?

Some countries like China is blocking Facebook/Twitter. How to use JavaScript to check whether a website is not accessible?
update:
I am adding a "Share to Facebook" button on a web page. 50% of the visitors are from China and 50% are from outside of China.
For those China visitors, they would never see that Facebook button because it's blocked. I want to use $.hide() or $.empty() to remove the related HTML if I detected that Facebook is blocked. How can I do that?
You can check if loading the facebook SDK is blocked in china (//connect.facebook.net/en_UK/all.js)
If this is the case then you could do something like this:
$.getScript('//connect.facebook.net/en_UK/all.js')
.success(function(){
// do something if facebook is available
});
You need to take care because you need to define a timeout if you want to make a callback for the fail case. I need to check the correct settings later, but currently i don't have time to.
EDIT
Based on the comment of funkybro it would be better to do a JSONP request. Loading the API would inject a butch of code you probably don't need.
So just request e.g.:
$.getJSON('https://graph.facebook.com/feed?callback=?')
.success(function(){
// do something if facebook is available
});
The request will include a failure code because you don't provide at graph node, but knowing that you get an error message from facebook means that it is reachable for the client.
Use jQuery.get like this:
$.get("http://facebook.com").fail(function() {
$(...).hide()
}).done(function() {
$(...).show()
})
Note that this is a cross-site request that will fail for security reasons unless you disable that browser feature.
If that's not possible for you, I suggest you use GeoIP or similar technologies to determine the users origin.

Publish data from browser app without writing my own server

I need users to be able to post data from a single page browser application (SPA) to me, but I can't put server-side code on the host.
Is there a web service that I can use for this? I looked at Amazon SQS (simple queue service) but I can't call their REST APIs from within the browser due to cross origin policy.
I favour ease of development over robustness right now, so even just receiving an email would be fine. I'm not sure that the site is even going to catch on. If it does, then I'll develop a server-side component and move hosts.
Not only there are Web Services, but nowadays there are robust systems that provide a way to server-side some logic on your applications. They are called BaaS or Backend as a Service providers, usually to provide some backbone to your front end applications.
Although they have multiple uses, I'm going to list the most common in my opinion:
For mobile applications - Instead of having to learn an API for each device you code to, you can use an standard platform to store logic and data for your application.
For prototyping - If you want to create a slick application, but you don't want to code all the backend logic for the data -less dealing with all the operations and system administration that represents-, through a BaaS provider you only need good Front End skills to code the simplest CRUD applications you can imagine. Some BaaS even allow you to bind some Reduce algorithms to calls your perform to their API.
For web applications - When PaaS (Platform as a Service) came to town to ease the job for Backend End developers in order to avoid the hassle of System Administration and Operations, it was just logic that the same was going to happen to the Backend. There are many clones that showcase the real power of this strategy.
All of this is amazing, but I have yet to mention any of them. I'm going to list the ones that I know the most and have actually used in projects. There are probably many, but as far as I know, this one have satisfied most of my news, whether it's any of the previously ones mentioned.
Parse.com
Parse's most outstanding features target mobile devices; however, nowadays Parse contains an incredible amount of API's that allows you to use it as full feature backend service for Javascript, Android and even Windows 8 applications (Windows 8 SDK was introduced a few months ago this year).
How does a Parse code looks in Javascript?
Parse works through classes and objects (ain't that beautiful?), so you first create a specific class (can be done through Javascript, REST or even the Data Browser manager) and then you add objects to specific classes.
First, add up Parse as a script tag in javascript:
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.1.15.min.js"></script>
Then, through a given Application ID and a Javascript Key, initialize Parse.
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
From there, it's all object manipulation
var Person = Parse.Object.extend("Person"); //Person is a class *cof* uppercase *cof*
var personObject = new Person();
personObject.save({name: "John"}, {
success: function(object) {
console.log("The object with the data "+ JSON.stringify(object) + " was saved successfully.");
},
error: function(model, error) {
console.log("There was an error! The following model and error object were provided by the Server");
console.log(model);
console.log(error);
}
});
What about authentication and security?
Parse has a User based authentication system, which pretty much allows you to store a base of users that can manipulate the data. If map the data with User information, you can ensure that only a given user can manipulate specific data. Plus, in the settings of your Parse application, you can specify that no clients are allowed to create classes, to ensure innecesary calls are performed.
Did you REALLY used in a web application?
Yes, it was my tool of choice for a medium fidelity prototype.
Firebase.com
Firebase's main feature is the ability to provide Real Time to your application without all the hassle. You don't need a MeteorJS server in order to bring Push Notifications to your software. If you know Javascript, you are half way through to bring Real Time magic to your users.
How does a Firebase looks in Javascript?
Firebase works in a REST fashion, and I think they do an amazing job structuring the Glory of REST. As a good example, look at the following Resource structure in Firebase:
https://SampleChat.firebaseIO-demo.com/users/fred/name/first
You don't need to be a rocket scientist to know that you are retrieve the first name of the user "Fred", giving there's at least one -usually there should be a UUID instead of a name, but hey, it's an example, give me a break-.
In order to start using Firebase, as with Parse, add up their CDN Javascript
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
Now, create a reference object that will allow you to consume the Firebase API
var myRootRef = new Firebase('https://myprojectname.firebaseIO-demo.com/');
From there, you can create a bunch of neat applications.
var USERS_LOCATION = 'https://SampleChat.firebaseIO-demo.com/users';
var userId = "Fred"; // Username
var usersRef = new Firebase(USERS_LOCATION);
usersRef.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
if (exists) {
console.log("Username "+userId+" is part of our database");
} else {
console.log("We have no register of the username "+userId);
}
});
What about authentication and security?
You are in luck! Firebase released their Security API about two weeks ago! I have yet to explore it, but I'm sure it fills most of the gaps that allowed random people to use your reference to their own purpose.
Did you REALLY used in a web application?
Eeehm... ok, no. I used it in a Chrome Extension! It's still in process but it's going to be a Real Time chat inside a Chrome Extension. Ain't that cool? Fine. I find it cool. Anyway, you can browse more awesome examples for Firebase in their examples page.
What's the magic of these services? If you read your Dependency Injection and Mock Object Testing, at some point you can completely replace all of those services for your own through a REST Web Service provider.
Since these services were created to be used inside any application, they are CORS ready. As stated before, I have successfully used both of them from multiple domains without any issue (I'm even trying to use Firebase in a Chrome Extension, and I'm sure I will succeed soon).
Both Parse and Firebase have Data Browser managers, which means that you can see the data you are manipulating through a simple web browser. As a final disclaimer, I have no relationship with any of those services other than the face that James Taplin (Firebase Co-founder) was amazing enough to lend me some Beta access to Firebase.
You actually CAN use SQS from the browser, even without CORS, as long as you only need the browser to send messages, not receive them. Warning: this is a kludge that would make my CS professors cry.
When you perform a GET request via javascript, the browser will always perform the request, however, you'll only get access to the response if it was from the same origin (protocol, host, port). This is your ticket to ride, since messages can be posted to an SQS queue with just a GET, and who really cares about the response anyways?
Assuming you're using jquery, your queue is https://sqs.us-east-1.amazonaws.com/71717171/myqueue, and allows anyone to post a message, the following will post a message with the body "HITHERE" to the queue:
$.ajax({
url: 'https://sqs.us-east-1.amazonaws.com/71717171/myqueue' +
'?Action=SendMessage' +
'&Version=2012-11-05' +
'&MessageBody=HITHERE'
})
The'll be an error in the console saying that the request failed, but the message will show up in the queue anyways.
Have you considered JSONP? That is one way of calling cross-domain scripts from javascript without running into the same origin policy. You're going to have to set up some script somewhere to send you the data, though. Javascript just isn't up to the task.
Depending in what kind of data you want to send, and what you're going to do with it, one way of solving it would be to post the data to a Google Spreadsheet using Ajax. It's a bit tricky to accomplish though.Here is another stackoverflow question about it.
If presentation isn't that important you can just have an embedded Google Spreadsheet Form.
What about mailto:youremail#goeshere.com ? ihihi
Meantime, you can turn on some free hostings like Altervista or Heroku or somenthing else like them .. so you can connect to their server , if i remember these free services allows servers p2p, so you can create a sort of personal web services and push ajax requests as well, obviously their servers are slow for free accounts, but i think it's enought if you do not have so much users traffic, else you should turn on some better VPS or Hosting or Cloud solution.
Maybe CouchDB can provide what you're after. IrisCouch provides free CouchDB instances. Lock it down so that users can't view documents and have a sensible validation function and you've got yourself an easy RESTful place to stick your data in.

Isn't this an application(*) vulnerability? (Javascript and HTTP)

just wondering. Isn't this considered a threat?
Let's say that 192.168.0.1 is a networkrouter with a administrationpanel on port 80. If you get a user to execute a similar snippet, wouldn't you be able to "bruteforce" the password? Considering network devices like networkrouters often feature default usernames and passwords.
<script>
function imgerror(data)
{
alert('The following '+data.src+ ' failed due to wrong password/username.');
}
</script>
<img src="user:password#192.168.0.1/menu_button.gif" onerror="imgerror(this)">
menu_button.gif is in this case a button used in the administrationpanel - and protected by http basic authentication.
It would only be a vulnerability if the developer/network administrator didn't care about security on their network.
It is VERY old idea http://web.archive.org/web/20070315010517/www.spidynamics.com/spilabs/js-port-scan/
javascript:var i=document.createElement('IFRAME');i.src='http://192.168.1.1/';document.body.appendChild(i);void(0);
Try this one, and find crossnetwork warning in the iframe below*.
requires aware UA :)
Techniques varies, the essence is the same - to execute script at the trusted side of firewall
This is possible, even more sofisticated with some more lines of JS/Ajax (see XXS).
What that means is you cannot trust NOBODY, even in your own network. If you cannot trust nobody and you have a basic security schema (as basic http authentification) you must use hard breakable passwords or if security is an issue (most private users do not know what security means at all) you MUST apply secure protocols.
If you use standard or blank passwords is leting the door open.

Categories

Resources