How to stop cookie manipulation for HTML to JSP page redirection? - html

I am trying to redirect my user from a html page to a jsp page which has been deployed on tomcat/webapps using .war file.
While doing so, I am also sending the session information of the user as an hidden parameter via POST method.
With the help of burpsuite tool(security testing tool) one can easily manipulate the cookie and change the username of the user logged in. How will I be able to block such kind of cookie manipulation?

You cannot control/prevent what the browser/client is sending, so do not consider the data received as fact/true. Your application shouldn't just look at the username and say "oh, it's the admin user, I show the whole admin area".
To prevent tampering the data originated from the server or at least detect changes, you use encryption or digital signatures. With encrypted data, it is not possible to change the data. You don't know how to decrypt the data and encrypt the changed data correctly since you don't have the encryption key to do so. With signed data you can still read the data but the signature makes sure that you can detect, if the data has been changed.
In your case, you can use a JWT instead of just the username. The JWT contains a digital signature which is used to check if the data has been changed. Your "testing team" can change the data but your server can see immediately that it has been changed and reject the received (changed) information.

Related

PluggableAuth extension how to receive $_POST hidden data without show form to user?

I created a simple authentication extension that works in conjunction with PluggableAuth for the user to login automatically. Currently, I need two parameters: a username and a token. These parameters are generated by an external system that sends the data by hidden input. I can get the url data and authenticate correctly. But for security reasons I want to pass this data via $_POST and not via $_GET. But I cannot receive this data and store it in the session so that I can retrieve it in my authentication class. Basically, the user receives a link from a wiki page and Pluggableauth does the checks. But I can't find what code I can use to save the post in the session and retrieve it later. Does anyone have any examples of how to do this? Thanks!
Edit: For example, the user needs to go to www.minhawiki.com/something, the external system sends the post data with username and password to this example page, but because of pluggableauth it redirects to Special:UserLogin, then to PluggableAuthLogin and then to my authentication extension. I've tried to get the data on all these redirects but none of them work. The only way that worked to get the data was to direct the post directly to Special:UserLogin but that way I can't redirect to the login page.

Login Security using jsonwebtoken

I am currently working on a website using React where I want to be able to have user login. Right now my strategy is to send form data to the server (express) on submit, and if the info matches a user in my DB, the server sends back a signed JWT with no sensitive information (just the username).
Once the client receives the JWT, I am adding it to localStorage as well as adding the decoded data of it to my redux store. I plan to have my redux store holding the currently logged in user.
I believe there may be a security issue in my site because currently I have it so when the user first arrives at the site, If there is a JWT, it is added to my axios headers and the decoded JWT is set to be the current user. The code looks like this:
if(localStorage.jwtToken) { // If token present, most likely a user is signed in
setAuthorizationToken(localStorage.jwtToken) // Set that token to head all api calls
store.dispatch(setCurrentUser(jwt.decode(localStorage.jwtToken))) // Set user in redux store
}
Currently I've found that if someone just goes into my localStorage, copies my JWT and adds it to their localStorage then bam, they are me. I'm unsure if this is really a security flaw because the only way I've recreated this myself is by physically copying the token from one browser to another. But in general this seems very unsafe that just taking my token steals my identity.
If anyone knows a way to make this more secure or if there is a better strategy, or at least tell me what I'm doing wrong that would be highly appreciated.
How can another person get your token? Give expire time to token needed. Maybe try different way for securing token, especially give more security in API side. When logging in, store log activity in database and create unique field to identificate it such ip address or user-agent, or maybe detect is that user have been hit login endpoint before or not.

Why should I leave JSON Web Token payload nonencrypted?

I'm reading on JWT, there are so many tutorials and so many approaches, it's confusing.
I have couple of questions regarding proper usage of JWTs:
1) I keep seeing inconsistent means of transporting JWTs to and from the server. For example, here: one transport method for retrieving the token (via JSON-encoded object in POST body), another method for submitting it (via HTTP header). Why such inconsistency? Of course, it's up to the implementer to choose the methods, but wouldn't it be good practice at least to be consistent and use either only header or only body?
2) The JWT payload contains the information of state because the server is not maintaining it. It is obvious one should keep the size of the payload as small as possible, because the size of JWT is added to every request and response. Perhaps just a user id and cached permissions. When the client needs any information, it can receive it via (typically JSON-encoded) HTTP body and store it in the local storage, there seems to be no need to access the read-only JWT payload for the same purpose. So, why should one keep the JWT payload nonencrypted? Why mix the two ways of getting application data to the client and use both JWT payload and normal data-in-response-body? Shouldn't the best practice be to keep JWT always encrypted? It can be updated only on the server side anyway.
1) I keep seeing inconsistent means of transporting JWTs to and from the server. [...] wouldn't it be good practice at least to be consistent and use either only header or only body?
This may depend on the Client. While a web app can get a higher degree of security by storing the JWT in cookie storage, native apps may prefere local storage in order to access the JWT information. [1]
2) The JWT payload contains the information of state because the server is not maintaining it. It is obvious one should keep the size of the payload as small as possible, because the size of JWT is added to every request and response. Perhaps just a user id and cached permissions. When the client needs any information, it can receive it via (typically JSON-encoded) HTTP body and store it in the local storage, there seems to be no need to access the read-only JWT payload for the same purpose.
The JWT keeps the Backend state, not the client state. The Backend state may be that User 128 is logged in as administrator. This is (in my example) stored in the JWT in the fields Subject and Scopes. Instead of the client sending an ID of a Backend session that contains this information, the info is in the JWT directly. The backend does thus not have to keep a session that stores the logged in state of user 128. If the Client requests information of User 2, the BE may decide that this info is forbidden if the JWT tells that the logged in user has ID 1.
So, why should one keep the JWT payload nonencrypted?
The state is normally not secret to the client. the client cannot trust the information in the JWT since it does not have access to the secret key that is used to validate the JWT, but it can still adjust the GUI etc from the information in the JWT. (Like showing a button for the admin GUI or not.)
Why mix the two ways of getting application data to the client and use both JWT payload and normal data-in-response-body?
See above, the main purpose of the JWT is to keep information the the Backend, not the Client. Once the user loggs in, the Backend ask "Hey, can you hold this info for me and attach it to every request so that I can forget about you in the meantime?" Like if your manager asks you to wear a name sticker on your skirt so that he/she don't have to remember your name. :-) (And he/she signs it so that you cannot alter it without him/her noticing.
Shouldn't the best practice be to keep JWT always encrypted? It can be updated only on the server side anyway.
It doesn't really bring any security unless you store secret information in the JWT, and that bay be better to do server side. The decryption is a bit more cumbersome to decrypt compared to just verifying a signature.
[1] Local Storage vs Cookies

Correct HATEOAS response when creating a user account

I have a REST api written in node which uses HATEOAS. The user is required to have an account before they can access the bulk of it.
They register an account with login details, then login to obtain an access token, and then use that token in order to access any endpoints that aren't register or login.
Issuing a get to the root responds with a directory with available actions.
Q: What is the correct response from register, to tell the client what it can do next (i.e. login)?
register technically creates a new resource on the server so a 201 CREATED and a Location header would seem appopriate. However the login reference isn't the location of the newly created resource.
Should I return 201 Created with a Location pointing to the newly created user (e.g. /myaccount or /users/{id} and then include a login link in the response body?
{
_links: {
self: { href: "what goes here?" },
x:login: { href: "/login" }
}
}
Do I not tell the client at all, and require them to do a get on the application root in order to fetch a list of available endpoints. This should include login anyway. Assuming the client had to do that in the first place to get the register link it should already have login.
Expecting the client already to already have the login link feels uncomfortable as it relies on an assumption of the client's prior activity.
Requiring the client to issue another request to the root directory after registering seems mean, inefficient and unnecessary. If the client has just created a resource it seems only fair that the server should respond with what it can do with it next.
I like to have my api's act no differently than a webpage. If you want the UX of your application to be the user is taken to login after they register, then 302 them from a successful register to the login resource. And upon successful login, 302 to them to the appropriate destination (IE, if they tried to access something with no token, then take them to login, with a destination of the original requested resource). That's and important part to your #3. Having a link off the root that leads to login, but you need to protect all the other links such that they indicate (and link to) a login being required to access the resource. The client app should expect to get this login required response at any time as tokens can (and do) expire at any time.
Following on this, it might make sense to do the JWT as a cookie instead of as an Authorization Header, it would make it a bit easier for the client (they just have to setup a cookie jar)..if the client is say a native mobile app that maintains a single connection setup. If it's server to server, then auth header makes sense. I'd go about supporting both to cover both scenarios.
Continuing on the idea of thinking of the api as a web site. Why have them login after registration at all? Why not have the registering of an account end up with the login token being sent? they just set their user/pass, why make them enter it again? I realize with some more exotic architectures the register service can not perform the login action (perhaps it doesn't have the private key to sign the token), but if it is possible i'd consider it.
If you really want to stick to the 201 header (which is fine, just make sure the docs of your register relationship indicate that), then option 2 is the closest in my opinion. A location header to the URL of the account just created a 201 is pretty standard for creating a user. But, i'd not return what you've supposed there. You're kind of returning a account-created resource (the thing with the login link), but do you really need this custom resource? If you want to give some messaging back to the client (like "Account Created") in that resource then absolutely yes, but you could also just give them back the root resource.
tl;dr; Decide what you want your UX to be and then make your API implement your UX.

Include Additional HTTPS Request Header Information in Form

Is there a way to include additional request headers in form data, other than action and method? I am hoping to send some authentication credentials cross domain without making the user re-enter their login credentials. ie I want to build an Authentication header directly from form submission.
The domain is SSL enabled, so I considered including credentials in the URL, but as explained here this is a bad idea, as those credentials may be secure over the connection, but can be accessed through the browser by other apps potentially.
Larger Picture
I have access to the cross domain username and password through an AJAX request to the client server (home domain). I want to take those credentials and submit them through a non-AJAX request, so a user can download a document securely without the URL being publicly accessible.
To the specific question, I believe the answer is no - you can't control sending any extra headers from the form itself. There are some other things you can send with a form, but they are not useful to what you want to do: W3 Form Tag Specification
What you could do is do a form POST, which is the standard way to communicate when sessions cookies are out of the question and a query string won't do; just use a hidden field with some sort of token/hash of the credentials. Avoid clear-text of passwords like the plague, and really try to avoid reversible encryption of them too. This is just one of those areas you have to be extra careful to avoid creating an easily exploitable security vulnerability.
But generally speaking it works just fine, and anything that can do an AJAX GET should be able to do an AJAX POST.