Set Cookie with Javascript and sanitize value - javascript

I need to set a cookie with javascript which I'm doing this with the following command:
document.cookie = name+"="+value;
My problem is that value is a string, which can contain any unicode-character.
Is there a function which automatically replaces special characters (like ;) - and if not, which characters are forbidden?
Something like the "encodeURIComponent()"-Function for Get-Parameters would be perfect

You should use window.escape.
The escape() method converts special characters (any characters that are not regular text or numbers) into hexadecimal characters, which is especially necessary for setting the values of cookies. Also useful when passing name=value pairs in the URL of a GET request, or an AJAX GET/POST request.
It also has window.unescape counterpart.
Upd.
It may make some sense to use base64 encoding/decoding prior to escaping in order not to suffer that much from unicode characters expenditure by window.encode.

Why not use a robust cookie library to handle cookies?
$.cookie('key', value, { expires: 365 });
Browsers limit cookies to 4 kB. If you need to store more than 4 kB on the client, you should use local storage.

Related

IE : window.open url which is more than 2,083 characters

I am getting a url from server with lot of data as query string
(E.g. http://www.test.com/?n=1,2,3,4,5,6,7,8.....100000) and I want to open it using window.open().
But the moment I pass the URL to window.open the url which gets gets truncated. After searching for sometime I could figure out that the maximum limit for URL is 2,083 characters(IE) so it passes PART of query string and truncates the rest..
How can I overcome this?
Please let me know if I need to provide more details.
I think the only solution is to use POST instead of GET. Just use a form, instead of window.open. Please see this older answer:
https://stackoverflow.com/a/17089124/907420
You could try URL shorteners, like goo.gl or bit.ly:
https://goo.gl/
Speaking of programming, you could try to shorten your URL-s yourself, for the given example:
Exact URL for your example, shorter by ~2000 characters.
Where x..y is translated on server side as range(x, y) -> 1,2,3,4,5...100000 for x and y being 1 and 100000
If you want to stick with GET (and I would recommend that you use POST) you can try to compress the parameters. Instead of giving a huge number of parameters you create a javascript object holding the parameters, jsonfy it and you end up with a string that can be compressed and uncompressed again at the other end. Afterwards you can deserialize the JSON string and you have your parameters. Depending on the number of parameters it might still not be sufficient for a GET request.
But at the end a POST request is the best solution I think.

Ajax string length limit?

Is there a limit to the length of the parameter that be can added to the url for ajax? I am using Thin server on Ruby, and did an ajax request from the web browser in this format:
io=new XMLHttpRequest();
io.open("GET","http://localhost:3000&v="+encodeURIComponent(JSON.stringify(v)),true);
When the length of the string v exceeds about 7000 bytes, it seems to crash. When less, it seems to work. Is my observation right? Where is the restriction coming from? From Thin, Javascript, or the browser? I use Google Chrome browser.
Is there a limit to the length of the parameter that can added to the url for ajax?
Yes, if you are using a GET request there's a limit which will depend on the client browser. And this limit has nothing to do with AJAX. IIRC it was around 4K for IE but things might have changed. But in any case there's a limit. If you don't want to be limited you should use POST.
Restriction most likely comes from the browser. According to this discussion you should try to keep your URLs under about 2000 characters.
There is a limit to the GET request depending on the character bytes. If you use ASCII it's 256 characters including the url itself. For UTF-8 it's practically the half because 1 utf character is 2bytes long.
You won't have this problem on POST though.

Encoding user input as URL GET parameter in JavaScript

I'm writing a JavaScript function that needs to uphold three properties:
be very small and lightweight - no external libraries
encode a string in such a way as to be able to be passed as a GET parameter
this string must be decoded again at its destination
Effectively, it authenticates the user by sending his username and password to a PHP page which then verifies it. This is done via GET because I haven't yet found a way of doing a background cross-domain POST request. The trouble is that if the user has a character such as '#' or similar in his password, it doesn't get sent properly.
Currently to avoid this, I encode() the password string before sending it, which allows it to be received without problems. However, I read that PHP's urldecode() is not a perfect analog for this, as there are corner cases which are treated differently (i.e. ' ', '+', etc). Sadly I cannot find this document anymore, so I cannot quote it, but the gist was that one of them converts spaces into '+' signs, which the other treats as an actual plus sign, or something like that...
As such, I'm looking for a Javascript function that can take a string and make it URL-safe, and which has a perfect reversal function in PHP so that the original string can be recovered.
The arguably awful code I currently use to achieve this:
login.onsubmit = function(){
loginFailMsg.style.display = 'none';
var inputs = login.getElementsByTagName('input');
var formdata =
'username='+inputs[0].value+'&password='+encode(inputs[1].value);
submit.src = formtarget+'/auth/bklt?'+formdata;
userinfo = undefined;
setTimeout(getUserinfo,300);
return false;
};
encodeURIComponent, PHP will decode it automatically when populating $_POST or $_GET
'&password='+encode(inputs[1].value)
Where's encode function coming from? Seems to me the quick answer to your question is using encodeURIComponent() instead, available since JavaScript 1.5. See also Comparing escape(), encodeURI(), and encodeURIComponent(); it does not encode everything either, but does encode all the server expects it to.
(As for cross-domain AJAX POST calls, I'd really have a look at "JSON with Padding". See JSONP with jQuery that I mentioned in the comments earlier. This will also prevent issues with the timeout you've randomly chosen, and jQuery will also help you, a lot, to get rid of inputs[0].value and the like. And, as you apparently already have a MD5 hash on the server, I'd really hash the password client side as well --see Karl's answer-- and compare those hashes instead. Respect your user's password and your own time, drop that no external libraries requirement!)
I don't think there's such a thing as a reversible hash function. There are plenty of javascript md5 libraries available, however.

sanitizing untrusted url strings that will be passed to location.replace

I'm getting a string from the current window's fragment identifier (location.hash). I want to use that string as the argument to location.replace(str).
Under normal circumstances, the string will come from code I control, so I'm not worried about validating that the string is a URL. If the string isn't a URL, the call to replace will just fail. That's fine.
What I am concerned about is making sure the string is NOT a javascript: URL or anything else that would allow someone to run arbitrary Javascript on my domain. Currently, I'm just checking that that str.indexOf('http') == 0.
Is that enough or should I sanitize this string some more?
The sanitization you propose is not enough.
An attacker could redirect to a data:uri url that contains base64 encoded html/javascript. This would allow the attacker to execute arbitrary javascript code. For example, this code snippet will alert 'xss' (in firefox, safari and opera)
var data = 'data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik8L3NjcmlwdD4=';
location.replace(data);
Besides, it may be possible to redirect to a anonymous FTP url, or use some other obscure protocol.
Instead of blacklisting protocols/keywords, use a whitelist approach instead. Maintain a list of good urls in your javascript code. Then, read the fragment identifier and see if it is in this known list of urls. If it is not, stop the process.
In security, whitelists are always preferable to blacklists.

What is the recommended way to pass urls as url parameters?

Using &url='+encodeURIComponent(url); to pass a URL from browser to server will encode the url but when it is decoded at the server, the parameters of url are interpreted as seperate parameters and not as part of the single url parameter.
What is the recommended way to pass urls as url parameters ?
encodeURIComponent() should work. For example,
'&url=' + encodeURIComponent("http://a.com/?q=query&n=10")
produces
"&url=http%3A%2F%2Fa.com%2F%3Fq%3Dquery%26n%3D10"
(which doesn't have any & or ? in the value).
When your server gets this url, it should be able to decode that to get the original:
param["url"] = "http://a.com/?q=query&n=10"
I'm not sure what server you're using (e.g. Rails, Django, ...) but that should work "out of the box" on any normal system.
Using '&url='+encodeURIComponent(url); to pass a URL from browser to server will encode the url
Yes, that's what you should be doing. encodeURIComponent is the correct way to encode a text value for putting in part of a query string.
but when it is decoded at the server, the parameters of url are interpreted as seperate parameters and not as part of the single url parameter.
Then the server is very broken indeed. If that's really what's happening, you need to fix it at the server end.
Code?
I ran into this issue, personally I couldn't use any of the accepted answers, but it can also be done by just encoding the url into Base 64, passing it as a parameter, and then decoding it. With javascript, you can encode a string s to base 64 with btoa(s) and decode with atob(s).
Other languages have ways of doing the same thing.
Base 64 is just kinda like representing a larger series of characters with 64 character(For ex, all the capital letters, all the lowercase, and a couple symbols). Kinda like how we represent letters in Binary. But it's nice to use, because then we can just pass base64 strings as parameters, and then they won't interfere/get interpreted in a weird fashion, and then we can decode them at the next stage.
Use escape() to url encode it, it will encode the ampersands so that does not happen.
Honestly, go with Google URL Shortener. Then you can just use the URL code in the url query string: http://example.com/url/A7dh3
In your application, take that and prepend the Google URL Shortener domain name, and do the redirect. This adds tracking to the URL through Google Analytics also. Lots of advantages in this approach. Just a short code and added tracking data, too.

Categories

Resources