Giter Club home page Giter Club logo

cookies's People

Contributors

angelini avatar artskydj avatar basarat avatar benadida avatar brianc avatar cattail avatar clauderic avatar danmactough avatar dead-horse avatar dougwilson avatar fengmk2 avatar gimler avatar hvrauhal avatar inigomarquinez avatar isaacs avatar jed avatar jonathanong avatar michaelwittig avatar mtkopone avatar panva avatar raynos avatar scriby avatar tj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cookies's Issues

Specify the type of license

Hi,

Could you please specify whether the license is MIT, BSD or Apache in the license file?

Thanks,

-- Tito

base64 cookies

to avoid issues with cookie strings with ; and stuff.

Add a method to remove a cookie

A utility method to expire a cookie immediately and get rid of the signature cookie in the case of a signed cookie would be nice.

How to use secure cookies behind an SSL load balancer

In the past I had used the secureProxy setting to allow the cookies module to write secure cookies when running behind a load balancer that was handling SSL. Now that the option is removed I am getting an error indicating that I can't set secure cookies on an insecure connection.

Is there some way to work around that now?

cookies(req, res, [options])

i think setting the options every time you .get() or .set() the cookies is pretty annoying. we should able to use default options passed to the constructor.

Have a way to get all cookie names

This library is wonderful for getting and setting individual cookies. I have a case where I need to get all cookies though.

It'd be nice to just re-use the get() function without specifying a key:

var cookies = new Cookies(req, res, keys);
var allCookies = cookies.get();

Thanks for your hard work!

Client Feasibility

Hi,

It would be great if you could restructure the functions to be used in a client. Currently, the assumption is that you're the one setting the cookies at the server end, and reading them from the client.

What would be desirable, is if you could use the get/set methods so that you could get any cookies which originate from the server, and set them when sending a request to the server. (Basically the opposite of what is currently occurring).

Thanks!

Support ambiguous key presence

It'd be nice if cookies didn't try to sign things when no keygrip is supplied, or if {signed:true} were the default when keys are present.

That way, you could have code that just passes in {signed:true} all the time, or never, and if keys are there or are not there, it will work as good as it can.

Improve tests

The current tests in this module leaves a lot to be desired. They really need to be refactored and all code paths in the module accounted for in tests.

Enforce Expiration

With sessions, actual expiration date is backed up in server and therefore clients can't change them to forever; but signed cookies have expiration dates exposed to clients.

To secure this, servers can sign a copy of the expiration date, and compare the dates prior to validation.

Cannot use it with sessions

TypeError: Cannot read property 'connect.sid' of undefined at Object.session [as handle]
Add: i use it as middleware

secure check

hi.

I have a problem with line 49 in lib/cookies.js:
if (!secure && opts && opts.secure) throw new Error("Cannot send secure cookie over unencrypted socket")

my node workers run in http mode because i handle SSL with stunnel before the requests enter haproxy where they are routed to my machines.

Are you happy with an option called secureProxy or something like this?

Security vulnerability: Use of multiple cookies will allow cookie forgery

Quoted from the documentation:

If the signature cookie hash matches any other key, the original cookie value is 
returned AND an outbound header is set to update the signature cookie's value to the 
hash of the first key. This enables automatic freshening of signature cookies that 
have become stale due to key rotation.

This is very ill advised. If an application uses more than one cookie, then I can forge an arbitrary cookie, because:

  • Let's say application uses cookies A and B, and I, the attacker, make an initial legitimate request to the application
  • I legitimately receive signed versions of cookies A and B
  • I want to forge the contents of cookie B
  • In my next request, I simply provide the new contents of cookie B, without updating the signature, while providing the original content of cookie A
  • Because I also provide a legitimately signed cookie A, the library will now sign the new contents of cookie B as if it were legit

bundle

Couldn't you help those who don't use npm? keygrip as submodule, plus Makefile to perform installation, e.g. to generate defaultKeys?

TIA,
--Vladimir++

ability to get cookie from response

currently .get is getting from request. It would be awesome if it can also take account of what has been set during the request on its response:

cookies = new Cookies(req, res);
cookies.set( "unsigned", "foo", { httpOnly: false } );
console.log cookies.get( "unsigned" );

this will log undefined

Usable with http.request()?

Is this class for node servers only? I attempted to use it in conjunction with http.request() and got an error reading from an undefined value.

/Apache/www/api_unit_tests/node_modules/cookies/lib/cookies.js:14
    header = this.request.headers[ "cookie" ]

TypeError: Cannot read property 'cookie' of undefined
    at Object.get (/Apache/www/api_unit_tests/node_modules/cookies/lib/cookies.js:14:34)
    at IncomingMessage.<anonymous> (/Apache/www/api_unit_tests/tests/00007 auth-get-session.js:30:23)
    at IncomingMessage.emit (events.js:67:17)
    at HTTPParser.onBody (http.js:113:42)
    at Socket.ondata (http.js:1124:24)
    at TCP.onread (net.js:336:27)

If not, is there another node library that does work for requests?

README.md Example

Hi,

I think the example in the readme should include the require statement because it looks like it's not being used like the typical module, e,g; fs=require('fs'); fs.[useful function].

It be good for people first looking at it to see how all the pieces fall into place.

Connect Session compatibility

Right now, the 'session' connect middleware uses a cookie to idenfity the session, and it expects the cookies to be accessible via a plain dictionary on req.cookies, as parsed by it's the connect cookieParser middleware.

Since this libarary is also using 'cookies' to store the dictionary, we end up with an incompatibility between the two middlewares. Thoughts on changing the name of the attribute on which the middleware stores itself?

How can I read cookies on client side ?

I have just tested this plugin and I have successfully set a cookie in my sails.js application with following code:

    Cookies = require("cookies"),
    Keygrip = require("keygrip"),
    keys = Keygrip(["SEKRIT2", "SEKRIT1"], 'sha256'),

...

    var cookies = new Cookies( req, res, keys );
    cookies.set("username", username, {signed: true});

and I can see this cookie using "Edit this cookie" chrome dev plugin but I cannot read it using jquery

console.log( JSON.stringify($.cookie()) );
var username = $.cookie("username"); 

$.cookie() is empty and $.cookie("username") is undefined.

Cookie version 1

I have a client that sends cookies in version 1 format, $Version: "1"

I noticed that all cookies sent with version 1 are quoted i.e. name: "value".

Does this module parse them correctly as well ? I had some problems using version 1 cookies with mozilla/node-client-sessions, specifically, the session cookie was not being parsed correctly because of the quotation marks

Cookies sent with this library aren't retained by the browser.

So maybe you can help me. This has been driving me crazy for days. I've got a Node project I'm trying to use this library in. For some reason, the cookies this library sends out aren't being retained by the client's browser (Mac/Chrome and Firefox). Oh, I can see the Set-Cookie header come in -- but it isn't accessible to JavaScript (even though httpOnly is set to false) and the cookie isn't recognized by the library on the next request, even though by all rights it should be there.

I wrote up a test case. Here it is:

var http = require('http'),
    Cookies = require('cookies'),
    getIpAddress = require('ipware')().get_ip;

function getExpireDate(created) {
    var expired = new Date();
    expired.setTime(created.getTime() + 82800000);
    return expired;
}

function parseCookie(rawCookie) {
    var split = rawCookie.split("$");
    return {
        'ip': split[0],
        'time': split[1]
    };
}

var server = http.createServer(function(request, response) {
    var cookieManager = new Cookies(request, response),
        cookie = cookieManager.get("token"),
        userIp = getIpAddress(request),
        currentTime = new Date();
    if (!cookie) {
        console.log("Cookie is null, creating a new one");
        cookie = encodeURIComponent(userIp.clientIp + "$" + currentTime.getTime());
        var expired = getExpireDate(currentTime);
        cookieManager.set("token", cookie, {
            'maxAge': 82800000,
            'expires': expired,
            'domain': '*',
            'path': '/',
            'httpOnly': false,
            'signed': false,
            'overwrite': false,
            'secure': false,
            'secureProxy': false
        });
    } else {
        var cookieInfo = parseCookie(decodeURIComponent(cookie)),
            cookieCreated = new Date();
        cookieCreated.setTime(cookieInfo.time);
        console.log("Got cookie!");
        console.log("Created for %s at %s", cookieInfo.ip, cookieCreated.toString());
    }
    // put together a json response
    var json = {'success': true, 'response': { 'message': "well, did this work?"} },
        data = JSON.stringify(json) + "\r\n";
    // send a response
    response.writeHead(200, {
        'Connection': 'Keep-Alive',
        'Keep-Alive': 'timeout=5, max=100',
        'Cache-Control': 'no-cache',
        'Pragma': 'no-cache',
        'Access-Control-Allow-Origin': '*',
        'Content-Type': "application/json",
        'Content-Length': data.length
    });
    response.end(data, 'utf8');
});
server.listen(8008);

When I start this server and hit it in my browser, "Cookie is null, creating a new one" comes up on the console screen. Every single time.

Any idea what's going on here? Is there anything I'm doing wrong that you can see? I would appreciate the help.

Thank you for your time.

Whether to support Chinese?

Today I use this module set a cookie to be found when the writing is Chinese,
it will error "TypeError: argument value is invalid".

Later I discovered that such a line of code,
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;

So I think that this module does not support the direct use of Chinese were cookies.set.
The Chinese need to escape to the corresponding unicode coding can write a cookie.

(先把中文转义为Unicode字符,然后再使用cookies写入cookie即可) just like

cookies.set("userName", encodeURI('中文名字'), {..});

base64 cookies

apparently semicolons, commas, and whitespace are not allowed in cookies... but JSON has been working for me so i don't know if this is necessary.

Cookies.getPattern() testing

In the getPattern() method there is a call to String.replace that appears to be escaping the cookie name. The cookie names that are tested do not appear to exercise this code. e.g.

"signed".replace( /[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&" ) returns "signed"

Cookie signatures lose attributes upon re-signing, causing persistent cookie to become invalid

When the .sig cookie is set the first time, you have all the 'opts' from the base cookie, and they propagate into the .sig cookie. But when re-signing due to expired key, the 'opts' simply aren't available, because all you have is the name=value that the client browser sends back.

Specifically… starting at Line 54 – we push the base cookie, then update the same object to become a signature, and push it. This should make both cookies share all the same options:

   headers = pushCookie(headers, cookie)
   if (opts && signed) {
     cookie.value = this.keys.sign(cookie.toString())
     cookie.name += ".sig"
     headers = pushCookie(headers, cookie)
   }

But up in the ‘get’ method, if we detect the signing key index was not zero on Line 34:

    index && this.set(sigName, this.keys.sign(data), { signed: false })

here all we have is name and value. The cookie we’re looking at could have been configured months ago, all the domain/path/expires/etc. settings are long gone from the server.

The largest impact I think is for persistent signed cookies. If the persistent cookie is re-signed due to a new key, the signature will always expire the next time the user closes their browser. since no ‘expire’ is set. Then next time we do a ‘get’ on the base cookie, the signature will be gone completely, and it will come back as having a invalid signature.

StirFry support

Do you plan on adding support for StirFry? There are currently no cookie processors for it. I'm not completely sure how your code works, but you probably will be able to do it just by removing next().

1.0.0

aside from the other issues listed:

  • options default to Cookies([options]). this means that doing .set() without any options doesn't mean to signed: false, and .set() with an empty option doesn't default to signed: !!this.keys. this is super confusing.
  • overwrite defaults to true

maxAge should translate to the max-age directive

the maxAge option is misleading. It should translate to the max-age cookie directive, not expires with Date.now() base.

Date.now causes issues when maxAge is low (a few hours), since it uses the server date, and the client date may be different due to timezones.

this.keys but no opts means cookies don't get signed

In Cookie.prototype.set (https://github.com/expressjs/cookies/blob/2dcb71f130a7eaafd16e71b9af70debe11d4c93f/lib/cookies.js#L69), the signed variable is true if opts.signed or this.keys is truthy. However, the check for whether to sign keys or not also checks if opts exists.

This means that if this.keys is truthy, but opts is undefined, the signed variable will be true but the key still won't be signed. My expectation is they key should be signed if signed == true, and it shouldn't depend on the existence of opts.

getPattern fails in some cases

hello,
I'm testing my node.js backend with superagent, and getPattern fails to parse a signed cookie, i.e. this one:

express:sess=eyJwYXNzcG9ydCI6eyJ1c2VyIjoiNTNjNjg4OWFiOTc0NjYyMTM2MGVmZTAyIn19; path=/; httponly, express:sess.sig=N-FXNwh7O7zoCJhfJ8pv-6RerH0; path=/; httponly

replacing line 119:

return cache[name] = new RegExp(
    "(?:^|;) *" +
    name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") +
    "=([^;]*)"
)

with:

return cache[name] = new RegExp(
    "(?:^|;)*" +
    name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") +
    "=([^;]*)"
)

seems to solve, don't know why

Add dashes to dd-mmm-yyyy in cookie's expires UTC string

Had a user (Firefox 38 on Linux) point out that my "remember me?" function wasn't working for them upon logging into my website. Every once in a while, someone points out that it doesn't work on some device/OS/browser combination, but finally I decide to seriously look into the issue if there is one.

My server implements "remember me?" by setting the sessionId cookie's Expires header for 1 year in the future. However, this user was seeing an ephemeral session cookie in their browser, not this far-future cookie.

I curled my own login endpoint to examine the expires header in the response:

Set-Cookie: __cfduid=xxxx; expires=Wed, 06-Jul-16 02:19:47 GMT; ...
Set-Cookie: sessionId=xxxx; expires=Wed, 06 Jul 2016 02:19:47 GMT; ...

The user reports that the __cfduid (Cloudflare) cookie was correctly expiring in 1 year while my site's sessionId cookie wasn't. What's the obvious difference? It's that my cookie's expires doesn't have dashes.

And it's because this library simply calls this.expires.toUTCString() which returns a string without dashes. (Source)

So I steal a function off Stack Overflow that prints the UTC string with dashes:

exports.cookieDate = function(date) {
  var padNum = function(n) {
    return n < 10 ? '0' + n : n;
  };

  var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  var outString = '' +
    ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][date.getUTCDay()] + ', ' +
    padNum(date.getUTCDate()) + '-' +
    months[date.getUTCMonth()] + '-' +
    date.getUTCFullYear() + ' ' +
    padNum(date.getUTCHours()) + ':' +
    padNum(date.getUTCMinutes()) + ':' +
    padNum(date.getUTCSeconds()) + ' GMT';

  return outString;
};

and I pass an object { toUTCString: function() { return cookieDate(date); } into this cookie library so that it sets the cookie with my patched UTC string.

Now my curl looks like this:

Set-Cookie: __cfduid=xxxx; expires=Wed, 06-Jul-16 02:19:47 GMT; ...
Set-Cookie: sessionId=xxxx; expires=Wed, 06-Jul-2016 02:19:47 GMT; ...

Dashes, now.

User reports that all is good. Firefox 38 on Linux is now correctly parsing the Expires for my site's sessionId cookie and expiring it in a year.

I see that every big website I curl has dashes in its cookie expires header and http://curl.haxx.se/rfc/cookie_spec.html says "the only legal time zone is GMT and the separators between the elements of the date must be dashes". (I couldn't actually make sense of the date grammar in the RFC itself)

What do yall think?

Regression can only set one value

With last update I can only set one cookie at a time :

This :

                    var cookies = new Cookies( req, res, null );

                    cookies.set( "user", user, {  httpOnly: true } )
                    cookies.set( "session", session, {  httpOnly: true } );

                    res.json({status : "ok"});

work with previous version but not by the last one.

Only the last (session one) set works ...

rewrite tests

currently tests aren't web scale

  • doesn't process.exit() correctly without control flow and either closing the server or manually exiting the process
  • can't use CI since it doesn't exit
  • difficult to add and edit tests

if anyone wants to add tests... i like mocha but i don't discriminate

Example in the README is not working

Hello Sir

Thank you for taking the effort to create cookies (module).
I would like to point out that the example in the README is fine but it doesn't works if a user copy pastes them and tries to run the server.
These are the issues :

  1. keys is not defined
  2. assert is not defined
  3. exception handling is not done
  4. server is created but not listening on a port
  5. It is nowhere mentioned that the expected use of the server is to first send a request to '/set'

The solutions:

  1. Installing keygrip and creating keys
    npm install keygrip
    var keygrip = require("keygrip")
    var keys = keygrip(["SEKRIT2", "SEKRIT1"], 'sha256', 'hex')
  2. Including assert module
    var assert = require("assert")
  3. putting the assertion part in try catch
    <Copying pasting the code here will make this too long>
  4. Adding a .listen to server
    }).listen(3000);
  5. Adding some html to let the user click and set the cookies
    <Copying pasting the code here will make this too long>
    I have done all this and made a gist of https://gist.github.com/ishanatmuz/9b87247e129513367cef.

If you think that these changes are important, then please add them to the README or in a separate Example folder.
If you allow I will be more than happy to post a Pull Request for the same, with whatever you want (README changes, Example folder anything else).

Signed option throws exception

hi,
i wanted to make a signed cookie , but throws this exception

this.keys.sign is not a function  at Cookies.set  , \node_modules\cookies\lib\cookies.js:94:30)

The Used code :

  var co = new Cookies(request,response , {keys:"somekeys" });
                co.set("access","allowed",{signed:true});

Allow the developer to send secure cookies no matter what

Because my nodejs app behind an nginx.

Browser == https ==> nginx == http ==> nodejs app

So req.protocol always be http, then I cookies.set(name, value, {secure: true} it throw Cannot send secure cookie over unencrypted connection Error.

Sets two cookies per set?

I'm using Koajs, but I saw this is the middleware they use to handle cookies, so I'm posting the issue here. I tried tracing the issue, but to no avail. I'm not sure if this is intended, but it most likely seems like it shouldn't be creating 2 cookies.

This is the code I use to set a cookie.

this.cookies.set('auth', cookieValue, {
  signed: true,
  httpOnly: true,
  maxAge: 1000 * 60 * 3
});

But then when I check my browser's resource cache there are 2 cookies set - one of them is even unsigned.
cookie

make .connect() middleware an array of strings instead of a keygrip instance

as you may know, we are removing connect's cookie utilities and encouraging users to use this mighty module instead. however, i don't like how the user has to cookies.connect(new KeyGrip(['a', 'b'])). how do you feel about allowing:

app.use(cookies.connect(['secret 1', 'secret 2'])

you are probably avoiding using keygrip as a direct dependency, so i'm thinking to add keygrip as a peer dependency. this will require the end user to install keygrip themselves. we'll also throw a helpful message when keygrip is not installed and the user tries to set keys

move to expressjs

yo, some express collabs want encrypted cookies. i don't think it's too crazy of an idea. want to move this and keygrip to the expressjs org so we can get the entire express team collaborating on this? i'll add you as owner to the org so you can transfer it

clearCookie for signed cookie

Right now has to manually do
res.clearCookie("user")
res.clearCookie("user.sig")

This exposes the .sig convention. It is desirable to have a method clearCookie to hide the implementation. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.