I understand there are many differences / pro's and cons of storing the token as a cookie vs using localStorage. This question is an ask on the actual implementation of storing it in a cookie.
I'm confused, because if the token is stored inside a cookie, the user will always be validated, making the use of a token worthless. The token will always be associated with the server side session data.
Can someone explain the implementation details?
Example:
(1) plain old cookie: Data in your "old plain cookie": "129scdsdf23i"
(2) JWT token: JWT data/token which is saved in the cookie: "1122abde"
How do you verity the data/token is a "valid authentication":
(1) plain old cookie: compare "129scdsdf23i" with data saved in database/server, check if they are the "identical"
(2) JWT token: step a: VERIFY "1122abde", "1122abde" itself is valid because (1 + 2 + a )= d and (1+2+b) = e. This is just an example.
step b: DECODE "1122abde" to "{user: user1, email: "user1#gmail.com"}", as you can see, now you get the user and email.
So "1122abde" is created by sever and a secret random number is involved during the creation. A hacker can never create a valid JWT token without knowing the "secret".
"I'm confused, because if the token is stored inside a cookie, the user will always be validated, making the use of a token worthless."
=> cookie is just a place to save your data, it has nothing to do with your data itself. If you have "1x22abde" in the cookie, it is a bad token which will fail the authentication.
Related
I am receiving below cookie from my source system
ExternalAccess=unixtime=1593603710&oracletime=01-jul-20
12:41:50_Hash_thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0
At destination system [PERL based], using below code to read the cookie
my $extSysCookie = $Query->cookie('ExternalAccess');
i am getting below output
External Access cookie = unixtime=1593603710
and not able to read full value.All characters after & are getting omitted. Can anyone help?
First of all, that's not a valid cookie. Spaces are not allowed in the value of cookies. Ref.
Secondly, that's not a correctly formatted cookie for CGI.pm's ->cookie. ->cookie is designed to handle cookies created using CGI.pm's ->cookie. The cookie value in question was not created with that method, and the cookie can't be handled (correctly) by that method.
To get the desired string from ->cookie, either construct the cookie using ->cookie, or otherwise create a cookie with the URI-encoding the value you wish ->cookie to return.
For example, the desired string will be returned for a cookie with the value
unixtime%3D1593603710%26oracletime%3D01-jul-20%2012%3A41%3A50_Hash_thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0
CGI's approach allows cookies to have multiple values, and gets around the problem of spaces being forbidden in the values of cookies.
I'm working on an application that parses a CSRF token from a cookie header. I'd like to know whether CSRF tokens are base64 encoded with URL-safe characters (cf. https://simplycalc.com/base64url-encode.php) so that I can match them with the regular expression
[.a-zA-Z0-9_-]+
I was able to find documentation on JSON web tokens (JWTs) indicating that they consist of base64url-encoded portions separated by periods ('.'), but I wasn't able to find similar documentation on CSRF tokens.
Are CSRF tokens also generally limited to a certain character set, or can they contain any characters?
A CSRF token is an opaque "nonce" that doesn't contain any info -- the token in the form submission and the token in the cookie or header simply have to match is all. If you see them base64-encoded, it's just for convenience of transmission, but it won't decode to anything useful, just random bytes most of the time. Nothing like the JSON structure of JWT.
Looking at my current framework (Laravel), its CSRF tokens are just random strings (they're derived from base64, but not valid base64). Chances are that's the case for most other frameworks too.
Imagine I have 2 routes in my application:
POST /login -> {token: some_token}
route for authentication that returns token for accessing second function
POST /divide -> {result: x / y}
route for simulate function divide(x: int, y: int), that protected by token bearer from first route. Also in this function I have some validators, i.e. x and y must be integers, y must be not equal 0 and it returns 400: BadRequest if one of those criteria is failed
So, my question is, if user didn't provide token bearer and parameters for route /divide, should I return 401 or 400?
There're two things that concerns me
return 400: user can figure out my API structure by sending
empty body and parse response, like send empty body and get {x: must be provided, y:
must be provided}, then send x=abc,y=bca and get {x: must be integer,
y: must be integer}, etc...
return 401: user can DDoS my application by sending a lot of
random tokens, so for each request application should check storage if token valid or not
What is the best practice in that case?
Thanks.
Without authorization you should in no way process any of the other content. Else, why have authentication/authorization at all? If you do process the content while the user is unauthorized you basically have a security breach. Obviously for the example function that does not seem like much of an issue, but that is the gist of it.
So you should return 401.
In case of the DDoS problem, that is not solved by processing in different order, you would still have to check all the tokens. And even if you did not someone could DDoS your service/API. There are other (API Management) solutions for that, like throttling, white-listing, rate-limiting etc.
Well, it looks like "opinion" question but i'll answer.
You need to return 401, becouse authorization is first thing you should do. Only if user can access resource, we can continue process.
Are mojolicious session tokens created in a "standard" way (in a generic sense), or is this up to the individual application? If it is the former, then what is the format?
What I saw so far is a base64 encoded JSON fragment (which by itself is syntactically incomplete), followed by "---", followed by a random looking 40-digit hex-string.
I'm especially interested in the random looking token. Is it randomly generated, or is it the encoding/encryption of something?
Mojolicious session have base64 string (in the begin, first part) and sign (in the end, second part) which separated by "---".
Sign is main part of session which prevent from changes.
So, make a test:
Add to session some value. Make request which get this value in the session.
Get session and transform first part of them (make base64_decode and change value then make base64_encode and put it before "--" in cookies).
Make query to server with new cookie/session. Your new data must be invalid in session.
So, sign it is IMPORTANT part of session.
Read source code to learn more about it
Read this to know how to set secret key for sign cookies
I am reading facebook api and ran into a little confusion, and hope that you might help. I am using the Javascript SDK specifically, and on getting the request.session back from the login callback, I wonder if the field 'sig' is the same as the 'auth_token'? I know the descriptions of both are different, but I wonder if they are the same in reality. If anyone knows, I will be much appreciated. Thanks in advance.
auth_token is a token that Facebook generates for desktop applications that you must send back to Facebook again immediately when logging in.
sig on the other hand is a md5 hash of all session data combined with your application's private key. You can reconstruct the sig from the session data and compare it with the sig passed in, and if it matches the response can be considered authentic.
Consider the following keys stored as a cookie:
a=1
b=2
sig=8a80b0b971da5be75e7197576331b24e
Assume the application's private key is "hello". We can try to reconstruct the sig as:
md5("a=1" + "b=1" + "hello"); // 8a80b0b971da5be75e7197576331b24e
which equals the value of sig in this case. We constructed this by concatenating all key=value pairs in alphabetical order by key ("a" comes before "b"), then concatenate the private key and finally get the md5 of the resulting string.
I wrote a blog post for verifying the cookie set by Facebook in Rails (PHP example is already given on Facebook's website).