Here in my javascript function im using location.href as follows
location.href = "../Floder1/result.jsp"; it is working fine but when i used fortify tool it is showing Cross-site Scripting which can result in the browser executing malicious code. how to protect this from cross site scripting. Thank you very much,your answer will be very much appreciated.
This code should work only in firefox since Proxy isn't implemented in all browsers
What you can do is to replace the original location object with a proxied one where you add some logic to your proxy to check for allowed value for location. this will not protect against the direct modification of the original object (location) but if you use only the proxied object in your code you should be fine.
// suppose we are in example.com
let validator = {
set: function(obj, prop, val) {
if (prop === 'href') {
if(typeof val != 'string'){
throw new TypeError('href must be string.');
}
if (!val.startsWith("https://example.com/")) {
throw new Error('XSS');
}
}
obj[prop] = val;
return true;
},
get: function(obj, prop){
return prop in obj?
obj[prop] :
null;
}
};
let proxiedLocation = new Proxy(location, validator);
console.log(proxiedLocation.href);// work same as location.href
proxiedLocation.href = "https://example.com/page1";// work fine
proxiedLocation.href = "https://example.net/page1";// cause exception
The Cross-site Scripting occurs when the user can put data in the webpage or get session data for example.
HOW PROTECT
You never allow inject code in your webpage. So, if you have a form, check it in the server and parse it before print in your page.
You shouldn't allow that the page content is changed by the href. You always escape the data before!.
Read this answer about location.href: https://stackoverflow.com/a/24089350/2389232
SAMPLE:
You have a iframe what changes with a GET variable:
sample.tld/index.jsp?iframe=none.jsp
I can inject a script to your iframe so you should protect it with escape characters:
// Escape the characters in the server and send it to the client.
// So the variable GET iframe will be valid
Related
I am trying to force the Page Tracking on my site (see: Link). I am using a TMS, but not Google Tag Manager.
What I am hoping to achieve is prepend the market name to the URI which I can pull out of my site's dataLayer (variable = dataLayer.language and thus the new Page Path: dataLayer.language.substring(0,2)+document.location.pathname e.g. /en/pagepath1/pagepath2.
I've created a script below to define this.
There is a small complication here in that some of the pages already have the country/language variation passed in the URL so I have a regular expression to search for the market/language ISO code (lower case) to help perform an if statement that returns document.location.pathname where this is the case.
My script below however, seems to be fine but in testing it is returning "undefined" does anyone why this must be the case?
function PagePath() {
var StandardPagePath = document.location.pathname;
var NewPagePath = dataLayer.language.substring(0, 2) + document.location.pathname;
var LocaleRegExPatt = /^(at|cn|cz|de|dk|en|eu|fr|it|nl|no|pl|pt|pt-br|se)\//
try {
if (StandardPagePath.includes(LocaleRegExPatt)) {
return (StandardPagePath);
} else {
return (NewPagePath)
}
} catch (err) {}
}
My second question is how can I reference this function to pass through to the page tracking i.e. set the page here:
ga('set', 'page', {{PagePath function here}} );
Thanks in advance
I have a Chrome extension (source provided below) that is getting caught with a race condition. I need some injected JavaScript to run before all other JavaScript on a web page.
The source code of a simple example of what I'm trying to do is here: https://github.com/nddipiazza/oogi
It is attempting to add a namespace to all cookie names that will actually be persisted as cookies, but at the same time remove those namespaces from the cookies that are in use.
So let's say normally without the extension you would have 2 cookies that are saved after accessing a site:
JSESSIONID
lastVisit
This extension would save them as:
oogi$JSESSIONID
oogi$lastVisit
There are basically two major parts to the extension.
https://github.com/nddipiazza/oogi/blob/master/background.js
This intercepts the incoming and outgoing http headers so that it can properly add the namespace to the incoming cookies and remove the ones from the outgoing. This way the namespace of the cookie is purely local to us.
https://github.com/nddipiazza/oogi/blob/master/inject.js
This intercepts JavaScript cookie get and set operations for the same reason as we do it for the headers.
The problem here is that in order for this to work, I need the javascript cookie header intercepts in inject.js to absolutely always be loaded before any other javascript. But it doesn't.
Example: Cookies in inline javascript such as:
<body>
<H2>Cookies from Inline JavaScript</H2>
<script>
console.log("Inline javascript is executed.");
document.write(listCookies());
</script>
</body>
Will already load prior to the inject cookie interceptor being loaded. You can tell from the console log will read in this order:
Inline javascript is executed.
cookie get/set injector completed
Is there a way to fix this inject race condition? I want to allow a chrome extension to force a javascript to be run prior to doing any javascript on a page.
Thanks to the comments on this ticket, the solution in my case was Method 2 from this answer: https://stackoverflow.com/a/9517879
Special thanks to https://stackoverflow.com/users/3959875/woxxom
Here is a link to the finished solution:
https://github.com/nddipiazza/oogi/commit/64e1ef8dc3abfb32fec2db5fb67891a29cfe12ea
The important part of the code that makes the difference is here
var actualCode = `var cookieGetter = document.__lookupGetter__("cookie").bind(document);
var cookieSetter = document.__lookupSetter__("cookie").bind(document);
var getPrefix = function() {
return "oogi$"
};
var processCookieStr = function(cookiesStr) {
var prefix = getPrefix();
var cookieStrList = cookiesStr.split('; ');
var newStrList = [];
cookieStrList.forEach(function(cookieStr){
if (cookieStr.indexOf(prefix)==0) {
newStrList.push(cookieStr.substring(prefix.length, cookieStr.length));
}
});
return newStrList.join("; ");
};
var processSetCookieStr = function(str) {
console.log("Processing set cookie string " + str);
return getPrefix()+str;
};
Object.defineProperty(document, 'cookie', {
get: function() {
var storedCookieStr = cookieGetter();
console.log("Intercepted a cookie get " + storedCookieStr + " , and returning processed cookie string " + processCookieStr(storedCookieStr));
return processCookieStr(storedCookieStr);
},
set: function(cookieString) {
var newValue = processSetCookieStr(cookieString);
console.log("Intercepted a cookie set " + newValue)
return cookieSetter(newValue);
}
});
console.log("cookie get/set injector completed");
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
I was going through an Asp.net project file.
In that they are navigating to a htm page when session got expired or session variable is null or empty like this
if (Session["UserID"] == null)
{
Response.Redirect("Expired.htm");
}
in that htm. in onload function following piece of javascript is there
function SessionExp()
{
if(window.parent.length > 0)
{
window.parent.location.replace(document.URLUnencoded);
}
}
what is window.parent.length,document.URLUnencoded means and sometimes document.URLUnencoded reurns Nan, what is it means?.
Note: Iframes are used.
Anyone Pls explain this....
The URLUnencoded property is a non-standard, Internet Explorer specific property. You cannot use it from any other browser. The location.href property should return the value you need.
tl;dr Can I execute un-trusted scripts on an iframe safely?
Back story:
I'm trying to make secure JSONP requests. A lot of older browsers do not support Web Workers which means that the current solution I came up with is not optimal.
I figured I could create an <iframe> and load a script inside it. That script would perform a JSONP request (creating a script tag), which would post a message to the main page. The main page would get the message, execute the callback and destroy the iframe. I've managed to do this sort of thing.
function jsonp(url, data, callback) {
var iframe = document.createElement("iframe");
iframe.style.display = "none";
document.body.appendChild(iframe);
var iframedoc = iframe.contentDocument || iframe.contentWindow.document;
sc = document.createElement("script");
sc.textContent = "(function(p){ cb = function(result){p.postMessage(result,'http://fiddle.jshell.net');};})(parent);";
//sc.textContent += "alert(cb)";
iframedoc.body.appendChild(sc);
var jr = document.createElement("script");
var getParams = ""; // serialize the GET parameters
for (var i in data) {
getParams += "&" + i + "=" + data[i];
}
jr.src = url + "?callback=cb" + getParams;
iframedoc.body.appendChild(jr);
window.onmessage = function (e) {
callback(e.data);
document.body.removeChild(iframe);
}
}
jsonp("http://jsfiddle.net/echo/jsonp/", {
foo: "bar"
}, function (result) {
alert("Result: " + JSON.stringify(result));
});
The problem is that since the iframes are on the same domain, the injected script still has access to the external scope through .top or .parent and such.
Is there any way to create an iframe that can not access data on the parent scope?
I want to create an iframe where scripts added through script tags will not be able to access variables on the parent window (and the DOM). I tried stuff like top=parent=null but I'm really not sure that's enough, there might be other workarounds. I tried running a for... in loop, but my function stopped working and I was unable to find out why.
NOTE:
I know optimally WebWorkers are a better isolated environment. I know JSONP is a "bad" technique (I even had some random guy tell me he'd never use it today). I'm trying to create a secure environment for scenarios where you have to perform JSONP queries.
You can't really delete the references, setting null will just silently fail and there is always a way to get the reference to the parent dom.
References like frameElement and frameElement.defaultView etc. cannot be deleted. Attempting to do so will either silently fail or throw exception depending on browser.
You could look into Caja/Cajita though.
tl;dr no
Any untrusted script can steal cookies (like a session id!) or read information from the DOM like the value of a credit card input field.
JavaScript relies on the security model that all code is trusted code. Any attempts at access from another domain requires explicit whitelisting.
If you want to sandbox your iframe you can serve the page from another domain. This does mean that you can't share a session or do any kind of communication because it can be abused. It's just like including an unrelated website. Even then there are possibilities for abuse if you allow untrusted JavaScript. You can for instance do: window.top.location.href = 'http://my.phishing.domain/';, the user might not notice the redirect.
I don't know why this doesnt work. Although im sure its something to do with the way im handling the url in the if statement. My Jquery / javascript knowledge if basic.
var url = $(location).attr('href');
if (url == 'http://www.website.com/test/index.html')
{
$('#HomeButton').bind('click', HomeButton);
}
function HomeButton(e) {
e.preventDefault();
doSomething....
};
Don't use jquery to access standard object properties.
You can do
if (document.location.href == 'http://www.website.com/test/index.html')
but you should never compare to the whole URL : you'd have wrong result if you change your domain, test elsewhere, use https, add a parameter, etc. You should use the intended property of location, that is pathname :
if (document.location.pathname == '/test/index.html')
In case of doubt, if you want to be sure of your pathname, simply open Chrome's developer tools (by typing F12) and type this on the console : document.location.pathname.
window.location isn't a a DOM element so you can't use jQuery methods on it.
The .href is actually a property of a Location object.
Just use it direct - if (window.location.href === ...)