how do you set session attributes with java.net.URLConnection or its subclasses?
In other words, what is the equivalent of HttpSession.setAttribute(String, Object) in Java.net.URLConnection? URLConnection does have setRequestProperty(String, String), but it does not help me as I need similar functionality as session.setAttribute(String, Object) for setting a timestamp.
In other words, how do you express following call with URLConnection?
HttpSession.setAttribute("timestamp", timestamp);
I cant change the contract with the third party, that is my request must have an timestamp attribute with a java.util.Date value.
Any help appreciated.
You can't. The session is kept, privately, at server-side, and is not available from the client. It's not part of the HTTP protocol at all, but is just something that nearly all server-side webapp APIs offer to allow keeping state associated to one particular user of the application.
Basically, what you're asking is the equivalent of "what can I put in my email to store some text in the C:\session.txt file on the hard drive of the recipient?":
there is perhaps no C:\session.txt file
you can't access the hard drive of a recipient by writing something in an email. It would constitute a big security problem
Related
I'm using Yubico demo to implement a webauthn server : https://developers.yubico.com/WebAuthn/WebAuthn_Walk-Through.html
I have implemented the CredentialRepository class to replace In Memory with access to a database.
Currently I am facing a problem:
I want to be able to use this server so that a client can connect with a Yubikey (or Andorid phone) to several websites. I would like the customer to register his key for each site. The problem is that the Yubico server does not want us to register the same key several times on the server while keeping the same username.
Would there be a way around this problem by making the registration of a key depend on the origin of the site where the key must be registered and not on the username?
(I don't want to replace the username with a different value for comprehension issues in the database)
All ideas are welcome.
Thank you.
What is preventing you from enrolling an authenticator multiple times for the same account lies within the PublicKeyCreationOptions that is being sent by the relying party. Within the PublicKeyCreationOptions is a field, excludeCredentials (line 22 in the screenshot link below).
PublicKeyCreationOptions Example
If you attempt to register a credential that has a credential ID that matches any of the items in the list, then the WebAuthn ceremony will not complete the request.
Why is this being done?
Users not familiar with how WebAuthn works may not realize that they only need to register an authenticator once, and that they can use that same authenticator across multiple devices. A confused user may attempt to register a security key on multiple devices, and may create the perception of a more cumbersome user experience. This is why we utilize the excludeList in our general guidance.
Here is some background as to how this list is being built.
How is the server creating this list?
When the relying party is built, you pass in the userStorage which allows the rp object to talk to your database where you're storing the credentials. When you begin your registration request, you pass in the userID when you are building the PublicKeyCredentialCreationOptions object needed by the RegistrationRequest object. If you observe the rp.startRegistration method you will see that the excludeList is built by searching userStorage for every credential that matches the userID of the user who made the request.
It's worth mentioning that the our example is typically acting as a relying party for a single origin/application, while yours is handling multiple.
With that context you have a few options
Here are some recommendations:
Provide guidance to your users noting that they can use the same
account/authenticator to enter into your multiple websites. This will only be applicable if your relying party is acting as a single origin authentication service, then routing the user back to the website they are coming from; example, Users in website1.com, website2.com and website3.com are all routed to my-relyingparty.com, authenticated, and routed back to their original site
As noted the java-webauthn-server is looking for registrations by username. You will first need to leverage multiple rp objects as they contain a reference to a specific origin (each registration you create with this rp object will correspond to the identity/origin you set). You can either create multiple instances of the java-webauthn-server for each origin, or create logic in your single instance to 1) Create multiple rp objects for each origin and 2) dynamically choose the rp object to use based on the origin of the users request. You could choose to leverage the same credential repository across multiple server instances or rp by overloading the startRegistrations method to search by both userID and rp ID/origin - While this is technically possible, it'll be a fair amount of rework.
Opt not to send existing credentials in the excludeCredentials list,
but this may be confusing to some users
Hope this helps
Thank you #CodySalas for your interesting answer.
This is what I did before you gave me an answer: I made the client send me back the origin of the client for the startRegistration and startAuthentication steps.
I added a trackedOrigin variable in InMemoryRegistrationStorage and I set trackedOrigin with userStorage.setTrackedOrigin(origin) for the two steps.
So when the Relying Party wants to search for excluded credentials (excludeCredentials) with "getCredentialIdsForUsername()" it will check the trackedOrigin to be able to make a request in the database according to the origin. Username is therefore no longer a uniqueness constraint since excludeCredentials will only have the credentials of keys with the same username AND the same origin.
Now that I saw your answer, I think reconsidered the solution I found because I discovered that the RP ID must be exactly the same as the domain of the client while the sites that will use the webauthn server will not have at all the same domain... Which is problematic but that's another question.
I'll probably open another question for that.
I have a REST api built for creating orders. The behavior is such that the person who creates an order received an email back saying "You created an order XXX". This email is triggered all the time.
The api appears like this
http://api.mytestevnt.com/ordering/orders - POST with request body as the order entity json.
Now i want to give a feature to the api caller to indicate if the email notification is necessary or not. What's the best way to do this?
I think it depends on whether email notification is data or metadata. If it's part of the order, then definitely add it to the request body. If it's metadata, you have two choices. If you think there will be lots of metadata, you can either edit the order to have a metadata section or you can POST the metadata separately. If there will only be a limited amount of metadata, I would suggest using a query parameter.
You should avoid using a header unless you control the entire path from the client to the server, because proxies or load balancers are allowed to strip non-standard headers.
Include in the POST body a send_email=1 or send_email=0 param. You'll extract that, and see what the user wants to do.
Search "how to get POST variables in JAVA".
Accessing post variables using Java Servlets
You can do like this:
Add a new Java attribute(like boolean emailEnabled) in your Java Request Object for your REST service.
Client side which invokes your REST service need to provide that parameter you added in your server side, you can set a default value for that too.
Assume I have a single servlet in a web app, and all users need to be logged in before they can do anything. So in the get and post methods there is an if block to test if the user is logged by trying to extract a session attribute in to process request, and else to redirect to login page if not logged in.
Given this scenario, is there a way an intruder can manipulate the system to gain entry without knowing the password? Assume the password is hard-coded into the servlet. If yes, where would he start?
I would look at http://docs.oracle.com/javaee/5/tutorial/doc/bncbe.html#bncbj and the section linked from that section about specifying authentication mechanisms.
See also (on Stackoverflow) Looking for a simple, secure session design with servlets and JSP and How do servlets work? Instantiation, sessions, shared variables and multithreading
In short, you don't need to do much yourself about checking for a session attribute if you use the mechanisms described on those pages. Your login form can be used in the 'form-login' configuration requiring authentication.
The key of security is around your comment extract a session attribute -- how are you doing this? Are they sending you a query string param? Are they sending you credentials in the method headers?
To #Hogan's point, unless this is over HTTPS the answer is: "No, it is not secure. A man-in-the-middle (MITM) can get the password from your submission and simply re-use it to mask its own nefarious requests".
If the communication IS done over HTTPS, then you should be fine. Having a single hard-coded password is fine, but consider the case where the password gets compromised; now every single client/user/etc. has to change their code.
A better design is to issue clients a key they can send along with their requests that you can use to identify who they are and if a key gets compromise, re-issue a new one to that user/client/etc.
This assumes traffic is over HTTPS
If traffic is not, a lot of this breaks down and you need to look at things like HMAC's. I wrote this article on designing secure APIs -- it should give you a good introduction to how all this nightmare of security works.
If your eyes are rolling into the back of your head and you are thinking "My god, I just wanted a YES/NO", then my recommendation is:
Require all traffic to be over HTTPS
Issue individual passwords to each client so if one gets compromised, every single one isn't compromised.
That should get you pretty far down the road.
Hope that help. This topic is super hairy and I know you didn't want a history lesson and just want to solve this question and move forward. Hope I gave you enough to do that.
I have a list of users across various companies who are using one of the functionality that our website provides. Whenever they contact our business group , we need to send a url via email to the requestor in order for them to upload some data. All these external users do not have any dedicated account. However we do not want a static link to be provided to them as this can be accessed by anyone over the internet. We want dynamic links to be generated. Is this something that is usually done? Is there an industry accepted way of doing this? Should we ensure that the dynamic link expires after a certain amount of time - if so , are there any design options?
Thanks a lot!
Usually, parameters to urls and not the actual urls are what's dynamic. Basically you generate params that are stored somewhere, typically on the database, and send email with the url and the parameter(s). This url is valid for only a limited period of time and possibly only for one request.
Answers to questions:
yes, this is something that is quite commonly used in, for example, unsubscribing from a mailing list or validating an account with a working email address
I'm not aware of any single way that is "industry accepted", there are many ways of doing it, but the idea is not that complex - you just need to decide on a suitable token format
normally you should ensure that the link expires after a certain amount of time. Depending on the use case that can be some days, a week or something else. In practice, you'd remove or disable the generated parameters in your database. However, if this data is something that might be needed for extended periods of time, you might want to think up a functionality so that it can be retrieved later on.
You may have a static URL taking a token as parameter. Eg. http://www.mycompany.com/exchange/<UUID> or http://www.mycompany.com/exchange?token=<UUID>.
The UUID could have a validity in a time range or be limited to a single use (one access or one upload).
Other variant is to use exists cookies on that site in web browser (of course, if they are).
But there are some drawbacks in this solution:
User can open link in different machine, different browser. User can clean all cookies or they can expire after it was visited your site last time when user try to go on granted URL. In these cases user won't access your page.
I got the answer for If I disabled the cookies then using URL ReDirect I can pass the JSESSIONID but my URL is already very long as I use the GET method it has constraint. Then how
should I use my sessions.I want my application to be very security intensive.
This is one of the question asked to my friend in GOOGLE interview.
Apart from using one-letter parameter names (e.g. ?a=value1&b=value2&c=value3 or using RESTFul-like URL's (i.e. just the pathinfo, no query parameters, e.g. /value1/value2/value3, which is accessible by HttpServletRequest#getPathInfo() in the servlet) instead of ?name1=value1&name2=value2&name3=value3, you can also consider to Gzip and Base64-encode the query string so that it becomes shorter. Both JavaScript and Java are capable of (de)compressing and (d)e(n)coding it. You can eventually format the query string in JSON before compressing/encoding, it will be shorter in case of arrays/collections/maps.
That said, are you sure that the request URL's are often that unfriendly long (assuming that it's over 255 characters)? Why would you need to pass that much information in? Are they supposed to maintain the client state? If so, you shouldn't use the URL for this, but the HttpSession instance in the server side which is already associated with the jsessionid cooke. Use HttpSession#setAttribute() to store some information in session and use HttpSession#getAttribute() to retrieve it.
As far as I understand, your main problem with JSESSIONID in the URL is the total length.
Perhaps you should have a closer look at why the length of the URLs are too long in the first place. Since you allready have a session, it is not unlikely you can move some GET parameters to the session. There are also lots of different way to make shorter URLs for pages (a la mod_rewrite).
With regards to security, JSESSIONID is just as vunerable with HTTP GET as HTTP POST. The base64 encoding HTTP POST does is not a security measure at all. The best way to gain a bit more security is to encrypt the transport channel through TLS/SSL, in effect enable HTTPS. This will make sure that eavesdropping (or man in the middle attacks) will not have access to the plain text.
If you want your application to be security intensive why are you using GET. Use POST. This will also reduce the URL length.
As such, as per the HTTP protocol there is no max length limit to URL length. Most of the time its the browser that puts in the max length limit. Try different browsers
You should put forward the above points to the interviewer. They might be more interested in your ability to assess the system as a whole and identify any fundamental flaws.
If the URL is too long then you have to store that data somewhere else. Most sites would put the session ID in a cookie.