what could be the secure alternative way of writing response.url in the redirect method in JS? - xss

Security team reported following code as a Cross-site scripting.
 
 redirect: function redirect(ajax, response, status) {
  window.location = response.url;
 });
They gave the sample of writing in better way
$(document).ready(function(){
$("#myDiv").on("click", "button", function(){
var eid = $("#eid").val();
$("resultsDiv").append(eid);
});
});
But How I do it for my code?

It is potential cross-site scripting on the response.url parameter, because if that contains user input and the user enters javascript: alert(1), it will be run in some browsers. Whether this is exploitable depends on the circumstances (how and with what parameters is redirect called and what browser is used).
The other code really doesn't make any sense though. :)
As for the fix, it also depends on the above. Make sure callers don't include user input, and/or in redirect() you can implement input validation (eg. response.url starts with 'http', does not contain 'javascript:', etc.)
Also note that if not cross-site scripting, it can stil be an open redirect.

Related

CFWheels: Redirect to URL with Params Hidden

I am using redirectTo() function with params to redirect to another pages with a query string in the url. For security purpose this does not look appealing because the user can change the parameters in the url, thus altering what is inserted into the database.
My code is:
redirectTo(action="checklist", params="r=#r#&i=#insp#&d=#d#");
Is there anyway around this? I am not using a forms, I just wish to redirect and I want the destination action/Controller to know what I am passing but not display it in the url.
You can obfuscate the variables in the URL. CfWheels makes this really easy.
All you have to do is call set(obfuscateURLs=true) in the config/settings.cfm file to turn on URL obfuscation.
I am sure this works with linkTo() function. I hope it works with RedirectTo() funcation as well. I do not have a set up to check it now. But if doesn't work for RedirectTo(), you can obfuscateParam() and deObfuscateParam() functions to do job for you.
Caution: This will only make harder for user to guess the value. It doesn't encrypt value.
To know more about this, Please read the document configuration and defaults and obfuscating url
A much better approach to this particular situation is to write params to the [flash].1 The flash is exactly the same thing as it is in Ruby on Rails or the ViewBag in ASP.Net. It stores the data in a session or cookie variable and is deleted at the end of the next page's load. This prevents you from posting back long query strings like someone that has been coding for less than a year. ObfuscateParam only works with numbers and is incredibly insecure. Any power user can easily deobfuscate, even more so with someone that actually makes a living stealing data.

How to customize the Restlet's error message

I used Restlet framework to provide the RESTful service.
I used the ResouceException the return the HTTP ERROR CODE, like 400 Bad Request, and so on.
I "new" the ResourceException(code, name, desc, uri) with the code, name and desc. I get the following output:
Bad Request (name)
period is not a number (desc)
You can get technical details here. (uri,though I didn't provide it)
Please continue your visit at our home page. (home page, I didn't provide, too)
I think the last two sentences is no use for user to correct the "bad request.".
Can I remove them? How to do? Or If I want to output sth else, how to customize the message.
Thanks a lot.
You could replace the default StatusService with one of your own.
Extending the class and Overriding getRepresentation(Status, Request, Response) to provide the format you would like.
this can then be set in your Application using setStatusService(StatusService)
There may be a slightly more up to date way to do this as the method I am using has survived a few Restlet updates, now but it still works.
Update
as of restlet version 2.3.x
the method to override is toRepresentation(Status, Request, Response)

Is htmlspecialchars sufficient against low level XSS in my case?

I have added functionality to my admin so it preserves the URL which you tried to access before it asked you to login. So, if you go to:
/admin/foo/bar?baz
It'll redirect you to:
/admin/auth/login
After you login, before my function add-on you always went to /admin/user/profile. Right now, I save /admin/foo/bar?baz in a session variable, $_SESSION['from'].
In the login <form>, the hidden value takes the value of the session:
<input type="hidden" name="from" value="<?php echo htmlspecialchars($_SESSION['from'];)?>">
Then, after the form is submitted a redirect takes place:
header('Location: ' . $_POST['from'] );
I have seen other questions relating to XSS and htmlspecialchars and am aware it won't fix all possible XSS attempts, but would this work successfully against "low level" XSS attempts?
While there's no XSS attack here, if you're using a slightly older version of PHP, you'll open yourself up to HTTP header injection, which can be worse in some cases.
If you're fetching the URL-to-be-returned-to from the HTTP referrer, then you should be protected well enough by making sure the URL is one that you control by parsing it, then only storing the return path and query string. When performing the final redirect, you should make sure that the components of the path are properly URL encoded. You can store the return URL entirely in the session instead of punting it back out to the user to possibly manipulate during the login.

Do cookies work when accessing a remote script with jsonp?

i use jsonp to post a form to a remote script. the code is something like this:
$.ajax({
type: "get",
datatype: "jsonp",
url: 'http://other-domain.com/process_form.php?param1=x&' + $("#gs_vote_form").serialize(),
data: $("#gs_vote_form").serialize(),
success: function(data) {
alert('form submitted successfully');
}
});
The form IS submitted, but... The process_form.php completely ignores cookie data that belong to the "other-domain" (does not read or write them), which is the problem for me.
Please note, i do not care about the returned data, i only use jsonp to submit the form from one site to the other silently, without actually transferring the user to the other site.
Is there any workaround for this? Something that will make cookies work?
What browser?
Cookies on other-domain will be ‘third-party cookies’, and thus in IE subject to tighter controls, as configured in the ‘privacy’ settings tab. That means, for IE's default settings, that other-domain will be prevented from using cookies unless it sets a P3P policy. (Other browsers don't use P3P as many consider it a somewhat pointless Liar's Charter.)
'?param1=x;' + $("#gs_vote_form").serialize(),
Really, are you sure other-domain allows the use of ; as an alternative parameter separator to &? Sadly PHP does not support this unless explicitly reconfigured to do so.

Online JSONP converter/wrapper

I would like to fetch a source of file and wrap it within JSONP.
For example, I want to retrieve pets.txt as text from a host I don't own. I want to do that by using nothing but client-side JavaScript.
I'm looking for online service which can convert anything to JSONP.
YQL
Yahoo Query Language is one of them.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://elv1s.ru/x/pets.txt"&format=json&callback=grab
This works if URL is not blocked by robots.txt. YQL have respect to robots.txt. I can't fetch http://userscripts.org/scripts/source/62706.user.js because it blocked via robots.txt.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://userscripts.org/scripts/source/62706.user.js"&format=json&callback=grab
"forbidden":"robots.txt for the domain disallows crawling for url: http://userscripts.org/scripts/source/62706.user.js"
So I'm looking for another solutions.
I built jsonpwrapper.com.
It's unstable and slower than YQL, but it doesn't care about robots.txt.
Here's another one, much faster, built on DigitalOcean & CloudFlare, utilizing caching et al: http://json2jsonp.com
Nononono. No. Just please; no. That is not JSONP, it is javascript that executes a function with an object as its parameter that contains more javascript. Aaah!
This is JSON because it's just one object:
{
'one': 1,
'two': 2,
'three':3
}
This is JSONP because it's just one object passed through a function; if you go to http://somesite/get_some_object?jsonp=grab, the server will return:
grab({
'one': 1,
'two': 2,
'three':3
});
This is not JSON at all. It's just Javascript:
alert("hello");
And this? Javascript code stored inside a string (ouch!) inside an object passed to a function that should evaluate the string (but it might or might not):
grab({"body": "alert(\"Hello!\");\n"});
Look at all those semicolons and backslashes! I get nightmares from this kind of stuff. It's like a badly written Lisp macro because it's much more complicated than it needs to (and should!) be. Instead, define a function called grab in your code:
function grab(message) {
alert(message.body);
}
and then use JSONP to have the server return:
grab({body: "Hello!"});
Don't let the server decide how to run your web page Instead, let your web page decide how to run the web page and just have the server fill in the blanks.
As for an online service that does this? I don't know of any, sorry
I'm not sure what you're trying to do here, but nobody will use something like this. Nobody is going to trust your service to always execute as it should and output expected JavaScript code. You see Yahoo doing it because people trust Yahoo, but they will not trust you.