How do I set the HttpOnly flag of a cookie with javascript? - javascript

I'm trying to create a cookie, with the HttpOnly flag enabled.
While there seems to be a plethora of resources about how to do it in Java and .Net, I need to do it in javascript.
Here is my (currently failing) function
createCookie = function(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; domain=my.domain.com; path=/; HttpOnly;";
Thanks -

You cannot access an HttpOnly cookie in JavaScript.
The following quotation is borrowed from the Wikipedia material:
The HttpOnly cookie is supported by most modern browsers. On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other, non-HTTP APIs (such as JavaScript).
In other words, HttpOnly cookies are made to be used only on the server side.
I wrote an example in PHP:
<?php
$name = 'foo';
$value = 'bar';
$expirationTime = 0; // Session cookie.
$path = '/';
$domain = 'localhost';
$isSecure = false;
$isHttpOnly = false;
setcookie($name, $value, $expirationTime, $path, $domain, $isSecure, $isHttpOnly);
?>
<script>
alert(document.cookie);
</script>
It alerts foo=bar.
Remove the cookie, change $isHttpOnly to true, reload the page, and you'll see an empty alert. But at the same time the browser stores the cookie to send it during a request to the server.

Related

Asp.Net Core 2.1 Request exlusing client side cookies

I have a problem where cookies set in the website using javascript are not being passed to controllers in the Request. Any cookies set in C# are present.
In my Startup.cs I have set the following:
ConfigureServices:
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;// must be false otherwise only essential cookies will be allowed
options.MinimumSameSitePolicy = SameSiteMode.None;
});
Configure:
app.UseCookiePolicy(new CookiePolicyOptions
{
HttpOnly = HttpOnlyPolicy.None
});
when inspecting the cookies in the browser the one I want - "ClientTimeZone" is present as can be seen in this image:
but in the controller when looking at the Request that cookie is not present:
The JavaScript code I use to store cookies are as follows:
setCookie: function (name, value, days)
{
var expires = "";
if (days)
{
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + ";";
},
I have also tried adding path=/ but no luck.
Any suggestions as to why the cookie does not persist to the server?
Thanks,
This is due to spaces in your cookie value (and in my case, Json). .NET Core is using RFC-6265.
Allowed characters are alphanumerics plus ~!##$%^&*()-_+[]{}|. Space, comma, semi-colon, backslash, and quotes are not allowed.
The simplest fix is to use Uri encoding/decoding.
Javascript to set cookie value:
document.cookie = 'ClientTimeZone=' + encodeURIComponent("New Zealand Time") + ';path=/';
C# to read it:
var timeZone = System.Net.WebUtility.UrlDecode(Request.Cookies["ClientTimeZone"]);
The source of the issue is when parsing header values into cookies:
Microsoft.Net.Http.Headers.HttpHeaderParser
{
protected virtual bool TryParseValues(IList<string> values, bool strict, out IList<T> parsedValues)
}
Eventually hits the following method, which exits as soon as it hits a disallowed character:
Microsoft.Net.Http.Headers.CookieHeaderValue
{
internal static StringSegment GetCookieValue(StringSegment input, ref int offset)
}
Essentially, even though the cookie is sent in the request header, any cookie that doesn't parse correctly is silently ignored and never included in the IRequestCookieCollection Request.Cookies.

Clear Session Cookie in Browser Programmatically

How can I clear a session cookie that resides in the browser memory programmatically, preferably using javascript?
Since it's a session cookie and doesn't have an expiry date, setting the expiration date in the past will not work like it does for a persistent cookie.
I have a current session for our website, but we have an iframe that connects to another site. This site creates a session cookie. I would like to clear their session cookie without effecting ours. I can do it in Firefox via the clear cookies option, but I need to do it programmatically.
Thanks
I never did try the following method of deleting cookies since I read that session cookies don't have an expiration date, but here's what I've found. Will this work for reseting the session cookie? I know this deletes all cookies, but I could modify it.
function deleteCookies() {
var allcookies = document.cookie.split(";");
for (var i = 0; i < allcookies.length; i++) {
var cookie = allcookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
Read about Same-origin policy
In short, if the iframe is loaded from a different domain of the page where your JavaScript runs, then you cannot have access to the cookie. This is security restriction.
If the iframe is the same domain and as the page with your JavaScript, then you can remove the iframe's cookie by chaning the expiration date or assign to it empty value.

Bookmarklet for set and read cookies

I need (for practice) to set a cookie via bookmarklet in website X, and read him with another bookmarklet from website Y.
For example, set a cookie named "user" with value of "Guy" in Google, and read this from YouTube.
I managed to set the cookie, but can't think of any idea how to read him from website b.
Thanks!
You need two bookmarklets, a getter and a setter.
You go to site X and use the getter bookmarklet to read the cookie and let the user copy it to his clipboard.
Then you go to site Y and use the setter. The setter will prompt the user for the bookmarklet and the user will then paste it into the prompt. The code will then set the cookie accordingly.
You can of course combine these two bookmarklets into a single getter/setter. The prompt will contain the current cookie for the page. The user can then choose to either copy the cookie and cancel (using it as a getter) or choose to to alter the cookie and click "OK" (using it as a setter).
I was looking for a way to share cookies of a specific website with a friend (reading them in my browser via bookmarklet and my friend setting them on his browser also via bookmarklet). Not quite what you asked for, but searching brought me here. This is my approach:
First there is a bookmarklet for exporting cookies. It will remove unnecessary white-spaces and encode your data in a base64 string for safe transport:
javascript:(
function(){
prompt("GET cookies encoded in base64", btoa(document.cookie.replace(/\s/ig, "")));
}
)
();
Then there is a second bookmarklet for importing all cookies encoded in the string. You can also set an optional lifetime here (thanks to https://www.quirksmode.org/js/cookies.html):
javascript:(
function(){
var inputstring = prompt("SET cookies decoded from base64");
var inputclean = atob(inputstring).replace(/\s/ig, "");
if (confirm("These cookies will be imported:\n\n" + inputclean.replace(/;/ig, "; "))) {
var days = prompt("Cookie lifetime in full days", "365");
var cookiearray = inputclean.split(";");
cookiearray.forEach(function(entry) {
var expires = "";
var split = entry.split("=");
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = split[0] + "=" + (split[1] || "") + expires + "; path=/";
});
}
}
)
();
Do not forget you have to run those on a specific website or tab. It does NOT export the entire collection of the cookies your browser is storing.
According to this StackOverflow, how to get cookies from a different domain with php and javascript you can't get cookies from another domain UNLESS you have access to it, as it would be a huge security flaw.

Javascript cookies and redirect

I need help changing this code so that the cookie only last through the session instead of 1 year forward. What changes do I need to make?
function createCookie(name,value,) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000*365));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
I tried to do this, but it doesn't seem to work. Cookie is created but doesn't disappear after session closes.
function createCookie(name,value) {
document.cookie = name+"="+value+"; path=/";
}
--- Update ---
I made some small changes to the code:
function createCookie(name,value,expires) {
var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
Now I was using Chrome, and it didn't work with the code I had and it doesn't work with this code either. But this code works in IE, Firefox and Opera. The cookie is deleted when the session is over, but not in Chrome...
Chrome since the version 19 had made a breakthrough change regarding the handling of session cookie. In order to improve the user experience the session cookie will not be removed.
If I understood correctly, since the option set in chrome settings say: "Continue where I left off", the session cookie never expires.
Please look at:
Chrome doesn't delete session cookies
If you are using Chrome or Firefox then set expires to 0, if you are using IE then leave out the expires parameter all together.

Save cookies with javascript how to specify domain?

I'm using this code to save cookies:
function saveCookie(name,value) {
var date = new Date();
date.setTime(date.getTime()+(60*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
document.cookie = name+"="+value+expires+"; path=/";
}
My problem is that it saves the cookie with domain "example.com" and I want to write them to ".example.com" so I can also read them from subdomains. This is easy to do with PHP but I don't know how to do it with javascript. How can I add a dot before the domain when I save the cookie?
You already have path in there, domain is specified in the same way.
To permit reading from other sub-domains, try:
'; path=/; domain=.'+window.location.host;

Categories