Skip to content

How can I differentiate a tampered signed cookie from a false JSON cookie? #168

Open

Description

@the-can-of-soup

Forewarning: I am extremely new to Node.js and NPM.

From reading the documentation of cookieParser, it appears that cookies that are signed but fail validation are assigned false in the req.signedCookies object.

Signed cookies that fail signature validation will have the value false instead of the tampered value.

Also, cookies prefixed with j: are automatically parsed with JSON.parse.

In addition, this module supports special "JSON cookies". These are cookie where the value is prefixed with j:. When these values are encountered, the value will be exposed as the result of JSON.parse.

However, the string 'false' is valid JSON, so it should get parsed to false. I also found no option to disable the built-in JSON parser. How can I differentiate a valid signed j:'false' cookie from an invalid signed cookie?

If this is not possible, I request that this be relabeled to a bug report or feature request.

Activity

  1. official-burak commented on Aug 26, 2026

    @official-burak

    Treat boolean false as a bad signature. A valid signed JSON false never becomes boolean false.

    JSONCookies only overwrites when JSON.parse returns a truthy value (if (val) in index.js). So j:false stays the string 'j:false' on req.signedCookies.

    const v = req.signedCookies.flag
    if (v === false) {
      // tampered / failed signature
    } else if (v === 'j:false') {
      // real JSON false
    }

    Same skip happens for j:null, j:0, and j:"". There is no flag to turn JSON cookies off.

  2. the-can-of-soup commented on Aug 27, 2026

    @the-can-of-soup
    Author

    That seems quite arbitrary. Why are falsy JSON values ignored?

  3. official-burak commented on Aug 31, 2026

    @official-burak

    It is not a policy. JSONCookies uses if (val) after JSON.parse, so anything falsy is treated as "not JSON" and the raw j:... string is kept.

    JSONCookie already returns undefined on a missing j: prefix or a parse error. The truthy check was a cheap way to skip those two cases. It also skips false, null, 0, and "".

    So boolean false on req.signedCookies is still only a failed signature. A real JSON false stays 'j:false'. Same for j:null / j:0 / j:"".

  4. the-can-of-soup commented on Aug 31, 2026

    @the-can-of-soup
    Author

    Sorry, but I understand what you meant, I just don't understand the reasoning.

  5. official-burak commented on Aug 31, 2026

    @official-burak

    There isn't one. if (val) is just a sloppy truthy check. Parse errors stay strings, and false/null/0/"" get the same treatment by accident.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions