Selective Framebursting - javascript

i would like to implement selective Framebursting for my iframe application.
My iframe is available at www.mywebsite.con/iframe.aspx?lic=1234
When the third party website hosting my iframe is (PayedWebsited1.con OR PayedWebsited2.con) AND the lic=1234 option also exists, display the iframe. For any other cheaters, display bananas!
How can i do it?

The thing is, that licence number won't help in any way - whether you will use server-side solution or in javascript. Cheaters will be able to see that licence number in PayedWebsite1.com.
As was said, you cannot get the parent frame location, but you can get the referrer - it equals to the parent frame, if your page is loaded in iframe.
if (window.top.location !== document.location) { // only if we're in iframe
// we get host of our referrer
var host = document.referrer.match(new RegExp("(http|https)://(.*?)/.*$"))[2];
host = host.toLowerCase(); // convert to lower case
var myHost = document.location.host.toLowerCase();
if (
host !== myHost // so we can click on links in an iframe
&& host !== 'payedwebsite1.com'
&& host !== 'payedwebsite2.com'
) {
window.top.location.href = document.location.href;
}
}
Be awared, that this technique can be beaten. More info at http://javascript.info/tutorial/clickjacking
For newer browsers, you can send special header:
X-Frame-Options: DENY
The logic keeps the same, only in server-side. Check Referrer, if PayedDomain or your own domain, just keep going. Otherwise, send this header.

If it is possible for your third party users to include a javascript file, or ideally send a request in ASP prior to drawing the page, this is what I would do:
Javascript
Build a ASP (I do PHP, so my example is in PHP) page on your server that checks the referrer and the license number to match an account in your database. The ASP file should then output javascript functions that will replace or insert into the element your specified iframe with a "one-time-use" key that you generate. The file might look similar to this:
<?php
$lic = $_GET['lic']; // Do better validation (short for demo purposes)
if (valid_license($lic, $_SERVER['HTTP_REFERER'])) {
$one_time_key = get_access_key($lic);
?>
function drawIframe() {
document.getElementById('iframe_target').innerHTML = "<iframe src='mysite.php?key=<?php echo $one_time_key;?>'></iframe>";
}
<?php
}
else {
echo "You are not authorized to use this service.";
}
Have your customer include this javascript code as a replacement of your iframe, in a fashion similar to this:
<script src="http://www.yoursite.com/preauth.php?lic=1234"></script>
<script>drawIframe();</script>
<div id="iframe_target"></div>
On the page that is loaded by the iframe, immediately check the key that you generated against the value passed to the iframe. If it is valid, immediately delete or change the status of the key so that you know it's been used. Then display appropriate application.
This javascript method will be the least painful method for your third party users, although it can be beat (users could change the "referer" that is sent to your server, although it is unlikely.)
ASP
If you can get your users to make a request to your url within their server, you will eliminate exposing any risky information like the license to the user. They could call something like $key = file_get_contents("http://www.yoursite.com/preauth.asp?lic=1234"); Immediately after they can output the iframe with the one time use key that you just generated.

Due to security, your browser will not allow you to use javascript to detect the URL of the parent page (i.e. the page that contains the iframe that displays your page).
The only solutions I can think of are:
Insist that users of your iframe.aspx page, include an additional GET param that states the domain that they are using.
Use the Request.UrlReferrer to get the referrer
On the page which you render, you should have a literal that, should you want to prevent the person from framing your page, you can simply add the javascript required to force the frames.
Unfortunately if Javascript is disabled, this will render your code useless...
Hope this helps?
protected void page_load(object sender, EventArgs e)
{
bool killFrames = false;
if(Request.QueryString["lic"] == null)
killFrames = true;
if(!killFrames && Request.UrlReferrer != null)
{
// do some database check against the LIC and Referrer
// and set killFrames accordingly.
}
if(killFrames)
{
literalFrame.Text = "<script type=\"text/javascript\">if(top.location != location) { top.location.href = document.location.href; }</script>";
// or show the bananas
}
else
{
// render the page accordingly.
}
}

I will try to point a solution for your general problem and not this particular technical problem, which as far as i know is impossible for security precautions done by all web browsers.
You need some sort of hand-shake between their app and yours and that haves to be done server-side.
Every PayedWebsite should have a password (or if they hava a static IP you could use that). Internally on their server (using CURL may be) they shold send you -via POST- their password; then you return a token that is used in the iframe.
iframe.aspx?lic=1234&token=d16evg5tr44e0trty45xp6es5
And the token only works once; so the process haves to be repeated every time the iframe needs to be opened. And you refuse every connection that doesn't include a valid token.

I'm not a .NET expert, but it looks like your solution could be easily solved by tracking the referral header that the client sends to your page when loading the iframe content.
You may want to refer to another question regarding refer headers:
how should we validate http header referrer in aspx .net
Basically, you would do the following
Use the referral header to get the domain name
Look up the domain name in your database (to see if there was a license for that site)
Send the real page, or the bananas depending on the result of the match.

Global.asax did the trick!
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim ref As String = HttpContext.Current.Request.ServerVariables("HTTP_REFERER")
If Not ref.Contains("PayedWebsited1") And Not ref.Contains("PayedWebsited2") Then
Response.Redirect("MYDOMAIN", True)
End If
End Sub
Thanks to all!

Related

How to prevent tracking sensitive data in URLs?

Some URLs in my single-page-app (SPA) contain sensitive information like an access token, user information, etc.
Examples:
/callback#access_token=HBVYTU2Rugv3gUbvgIUY
/?email=username#example.com
I see that hotjar allows suppressing DOM elements and images from tracked data. Is it possible to hide params in URL or at least disable tracking for some pages?
Since you are saying that it is your SPA, you might solve the problem by switching from GET requests (which have the parameters inside the URL) to POST requests. I do not know hotjar, but if you tell the tracking service to analyze URLs only, that would be an option worth considering.
Another option frequently used is to obfuscate your parameters in the URL, see e.g. Best way to obfuscate an e-mail address on a website? However, that is never a really safe solution for sensitive data, since the de-ciphering step is too easy, in particular if your man-in-the-middle has all requests ever send to your SPA.
Edit. I just found in the Hotjar allows RegEx. Assuming you could enter a regular expression of URL-parts to exclude.
The general syntax /foo/bar/ means that foo should be replaced by bar, in our case, we want to delete the given snippet, that why it is /foo//.
For the given case of the access token, the regular expression would be
/callback#access_token=[a-zA-Z0-9]{15}//
and respectively for the email part of the URL
/\?email=(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])//
This second RegEx partially taken from How to validate an email address using a regular expression?
It seems to me that it's reasonable to assume that tracking scripts will try to access window.location.href or similar to get the current url which they will store.
So a possible solution would be create a dynamic scope which has a different value for window.location.href (with all sensitive info filtered out)
This is how it might work:
// get the tracker script as a string, so you can eval it in a dynamic scope
let trackerScript = 'console.log("Tracked url:", window.location.href)';
// now lets lock it up
function trackerJail(){
let window = {
location: {
// put your filtered url here
href: "not so fast mr.bond"
}
}
eval(String(trackerScript))
}
trackerJail()
If the tracking snippet is wrapped in a function it might be possible to create a dynamic scope for it without running eval by overriding it's prototype instead. But I'm not sure you can count on tracker scripts being wrapped in a neat function you can modify.
Also, there are a couple more ways the script might try to access the URL, so make sure to cover all the exits
If you control the page and order of scripts, you could read the data from the url then delete it before anything else can get to it.
proofOfConcept.html
<script id="firstThingToLoad.js">
console.log(window.location.href);
const keyRegex = /key=[^&]*/;
const key = window.location.href.match(keyRegex);
console.log("I have key", key);
const href = window.location.href.replace(keyRegex, "");
history.replaceState({}, "", href);
</script>
<script id="someSnoopyCode.js">
console.log("I'm snooping: ", window.location.href);
</script>
<body>
Link to private
</body>
Of course the Link to private should not exist as is. Also, this does break refresh and most navigation in general, though there are ways to catch and save that.

Check if a $_SESSION variable is set from Javascript

I'm building a message system to learn how it works, and I've already got
pretty much everything. I can log in and make a post on a board, but now I would like to be able to edit it. The back-end is ready, it receives a POST request
Basically what I need to do is check if the currently logged in user is the author of a certain post from Javascript to show or hide the edit button. I know how to tell if the user is logged in from PHP so that it blocks requests if you aren't the author, but I can't hide or show the buttons as the posts are dinamically generated from a <template> using JS.
Login snippet:
$_SESSION["userid"] = $userid;
Edit check PHP snippet (kinda pseudo-code):
if ($_POST["action"] == "modifypost" && isset($_POST["postid"]) && isset($_POST["content"]))
{
$post = get_post($_POST["postid"]);
if ($post.userid != $_SESSION["userid"])
{
die("you are not allowed");
}
//MySQL queries
}
Post dynamic generation (abbreviated):
function add_post(post) {
var t = document.querySelector('#historypost');
t.content.querySelector(".content").innerHTML = post.content;
var clone = document.importNode(t.content, true);
document.body.appendChild(clone);
}
I had originally thought of setting a variable with the user ID from HTML with <script> and <?php ?>, but then the user would be able to manually set that variable from the console and show the buttons.
I had originally thought of setting a variable with the user ID from HTML with <script> and <?php ?>
Yes, this is one correct approach. Basically, use PHP to tell JavaScript which posts actually belong to the current user.
but then the user would be able to manually set that variable from the console and show the buttons
True. There is no way to secure information from user-meddling once you've sent it to the browser. This is because the user is in control of what gets executed in the browser. Instead of thinking of the button visibility as a security feature, think of it as a convenience -- something to make the user experience more pleasing.
Application security is really enforced on the server. Just make sure that one user is not allowed to edit another user's posts, and do not trust what comes from the browser. Verify inputs.
Ideally, I would prefer to put the post rendering logic inside the server-side.
But as your solution is focused in javascript, an option makes PHP render a javascript variable that tells if the user is the post author.
Example:
Inside your PHP file, in the HTML render part you can do this:
<script>var isAuthor = '<?php echo ($post.userid == $_SESSION["userid"])'; ?></script>
Doing this you will have javascript script variable called isAuthor, that will have value "1" is the user is the author.
-
But as I said, this doesn't look like a good approach to solve the problem. It's something that PHP can handle better, without expose your logic to the client.

JS/JQuery: Redirect on the basis of XML response

Is there a way to redirect the user to a certain URL on the basis of what comes out of an XMLHttpRequest()? Here's what I am trying to achieve:
User hits submit, form gets submitted, XMLHttpRequest() fired
Response received from the server, stored in var hr
If hr = abc, show contents of hr
If hr = xyz, redirect user to http://www.something.com
What I am looking for is if there's any predesigned method in either JS or JQ to handle such redirects. I understand redirects can be specified in the <meta> tags in the <header> section of the page but if I did that, how will I be able to add conditions to it? I would have posted a copy of the script I have attempted but can't because right now, I have no idea where to even begin!
In case someone is curious about the scenario, this is a Web-based dictionary/conjugation service. So, on the verb conjugation page, if the user enters a valid verb, the response (i.e. the conjugation tables) is displayed. However, if the user enters a word that's valid but not a verb so it can't be conjugated, I want the user to be automatically redirected to the dictionary page where the entered word's dictionary entry will be displayed. Not sure if I have explained it well enough but please feel free to ask should you have any questions.
Try testing with switch(request.responseText) and call window.location.assign("http://your-url.com"); in the preferred case "xyz"! Alternatively window.open("http://anotherxxxwebsite.com") opens the link in a new browser window.
There's no "predesigned" method, but you can write that logic yourself. Depending on your current API you could either check if the returned value is an URI (or some other designated value instead) an redirect accordingly. Assuming a deferred object returned from jQuery.ajax:
defer.done(function(data, textStatus, jqXHR) {
// assuming a string, but this could really be anthing, e.g.
// an object containing an appropriate attribute, etc.
if (data.indexOf('http') === 0) {
window.open(data);
} else {
// render your stuff
}
});

Detecting Unique Browser Tabs

On every page of my sites, I am using AJAX to poll the server and retrieve a list of messages. The server maintains a list of messages and the SessionId (I'm in an ASP.NET environment, but I feel like this question is applicable to any server side technology) that the message is intended for. If a message is found for the particular SessionId, it is returned to the client side script. I use a JavaScript library to create a notification (using noty, a Jquery Notification Plugin). Once it returns a particular message, the server discards that message.
This works well if the user only has a single tab/window open for a particular site. However, let's say they have two open and they do something that causes a warning message to be generated. I have no control over which tab the notification goes to, so the user may not end up seeing the warning message.
Is there a way of uniquely identifying a browser tab? Then I could pass this as one of the parameters in my AJAX call.
Firstly, polling doesn't seem good mechanism. It might hit your server down when you have large number of active users. Ideally you should return a message in the response to the request that was result of invalid action.
Still below solution might work for you. It is inspired by the reply of #SergioGarcia.
Keep a hidden input just before the end of your form tag, which stores a unique ID for identifying a tab uniquely. You will store the messages on server session against unique tabID,
<input type="hidden" id="hiddenInputTabId" value="<%=getValue()%>" />
and then define getValue.
function string getValue() {
var v = getValueFormBodyOrAccessValueDirectlyByMakingInput_a_ServerSideControl();
if (string.IsNullOrWhiteSpace(v)) {
return Guid.NewId();
} else {
return v;
}
}
Because it is a hidden input you should get it's value in the POSTed form body, and for ajax requests below snippet should take care of sending that value in header which you can access on server side.
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("tabId", $('#hiddenInputTabId').val());
},
});
Same header can be check while returning the response to your polling requests and only respond message available against the provided tabId should be responded.
You can add a query string parameter called tabId and control it's binding to tab using javascript.
There is a functional prototype below:
$(function () {
// from: https://developer.mozilla.org/en-US/docs/Web/API/Window.location
function getQueryStringParameter (sVar) {
return decodeURI(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURI(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}
// from: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
function newGuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
window.tabId = getQueryStringParameter('tabId');
// tabId not defined, reload the page setting it
if (!window.tabId) {
window.tabId = newGuid();
}
// on click set the tabId of each link to current page
$(document).on('click', 'a', function (e) {
var $this = $(this);
var newLocation = $(this).attr("href");
// In page links
if (newLocation.match(/^#.+$/)) {
return;
}
// Outbound links
if (newLocation.match(new RegExp("^https?")) && !newLocation.match(new RegExp("^https?://" + window.location.host))) {
return;
}
// Insert tab id
if (newLocation.match(/(\?|&)tabId=[0-9a-f-]+/)) {
newLocation.replace(/(\?|&)tabId=[0-9a-f-]+/, (newLocation.indexOf('?') == -1 ? "?" : "&") + "tabId=" + window.tabId);
} else {
newLocation += (newLocation.indexOf('?') == -1 ? "?" : "&") + "tabId=" + window.tabId;
}
window.location.href = newLocation;
e.preventDefault();
});
});
If you enter a page in your application without setting the tabId parameter on query string, it will be set to a new UUID (Guid).
When the page has a tabId parameter on query string, it defines the window.tabId variable inside your page and you can use that in your application.
When the user click on any link in your page, a javascript event will be triggered and the link url will be redirected to match the current tabId. An right click to open in new tab or a middle click will not trigger that event and the user will be sent to a new tab without the query string parameters, so the new page will create a new tabId in that page.
You can see it working here: http://codepen.io/anon/pen/sCcvK
You can do it by generating a unique tab id with javascript by loading your client.
I strongly recommend you to use something for intertab communication, like intercom.js, which can broadcast the messages from a single tab with a single connection to every other tabs. Intertab works with socket.io, which has long polling fallback, so it may be good in your current system as well. I agree that polling is a poor choice, and you should use websockets instead.
If you use ZMQ on the server, then in the browser you can use NullMQ either (for websockets ofc). I think it does not have intertab support, so you should make your own intertab solution to make it work. It is not so hard to write such a system, you need only a common storage, for example localStorage, but it can be even cookie... If you don't have a storage event, you have to ping that storage for changes with setInterval. You have to store there the messages, and which tab broadcasts them (probably in a semaphore) and when was the last time it pinged the storage. After that you can keep each tab in sync with the others, or by using a unique tab id, you can send customized messages to any of the tabs. If the broadcast tab has a storage timeout (it did not ping the storage for a long while), then it is probably closed, so you should assign the broadcast service to another tab.
So what I ended up doing was changing how my notification framework functioned in order to prevent the need for identifying unique tabs. It's just too hard to layer information on the stateless web.
Instead of using Ajax to pump messages out to the client instantly, I build them up on each page into a List<Message> property. On PreRender I render them to the client with ClientScript.RegisterStartupScript(). But if I need to send the user to another page, I started using Server.Transfer() instead of Response.Redirect() instead so that it will preserve the message queue. The new page checks the old page to see if it exists and if is the correct Type. If it is the correct type, I cast it and retrieve the message queue from the old page and add them to the new page's queue. And since Server.Transfer() doesn't update the URL on the client, I also added a JavaScript function to manually push the state to the URL in supported browsers.
I know I took this in a little different direction than I did on the question, but I think I had been approaching it wrong in the beginning.

Show content based on user selection

Im building a site at the moment.
On the layout there are 3 flags for different countries.
Im wondering how i would go about displaying content based on what the user selects, and keeping that selection each time they come back to the site.
Obviously the first time they come to the site the default english will be shown, but once they click on a flag it would change.
Im taking im going to have to use javascript and cookies, i have been looking around and cant seem to find any examples, im wondering if someone could show me how to go about this.
Thanks
Cookies seems like the right idea:
http://www.google.co.uk/search?q=javascript+cookies
There are (probably) only two ways of doing this:
Cookies (i.e. mostly anonymous users)
Registration and getting users to login
For your needs, it sounds as though cookies would be enough.
http://www.quirksmode.org/js/cookies.html is absolutely worth reading from beginning to end.
I am giving a abstract idea of how i might do it..
In the html you write, put a javascript function which sets the flag's id in the browser cookie when you click the flag and then submit the request..
function setCookie(flag_id) //call this when the flag is clicked
{
var allcookies = document.cookie;
if(allcookies)
{
document.cookie += ';flagId=' + flag_id;
}
else
{
document.cookie='flagId=' + flag_id;
}
/*submit the form or whatever you would like to do when the flag is clicked*/
}
Thats it on the client part. You can specify the expiration time for the cookie as well.. for details you can refer the w3schools website. The cookie will stay in the browser and sent to the server on every request.
Now, on the server side, if you are using servlets, just use the following code to get the cookie in the doPost or doGet (in your case when the first request comes from the client).
.....
Cookies[] cookies = request.getCookies();
String flagId = null;
if(cookies != null)
{
for(String cookie:cookies)
{
if(cookie.getName().equals("flagId"))
{
flagId = cookie.getValue();
}
}
}
//use the flag id to decide your content here..
....
Hope this answers your question.

Categories

Resources