Hacker News new | ask | show | jobs
by graycat 4730 days ago
Thanks, I needed that!

I've done a lot of programming, some quite advanced, and likely for longer than 99% of the HN audience. But this is my first effort with a Web site, HTML, CSS, etc. So, I believe I can write good code and think through design issues well enough, but I am missing some information about mobile devices and browsers.

My little session state store code is working great. It was fast, fun, and easy to write, and it's been working flawlessly as I use it while developing more code.

My main alternative was to use what Microsoft's ASP.NET offered. First they offered storing session state in the same application (whatever that is, maybe just an address space). That alternative would give problems once my site is busy enough to need more than one Web server unless I had some front end box, maybe from Cisco, implement something like session affinity. The second alternative was using SQL Server. I'm trying to keep down the use of SQL Server, especially for something as light as a session state store where relational database, with ACID, etc. is gross overkill.

Thanks for the information on cookies: I don't want to assume or ask that a user's Web browser accept cookies.

When my site goes live, there will be no reason for users to have a user ID or password or log in -- later there will be. So, when I have some users log in, there is some question just how to handle that in a way both secure enough and also really easy for the users. If the user lets their Web browser store the user ID and password (not in a cookie) and a user wants to use that facility, so far fine with me -- that browser functionality is an industry standard and, thus, not to be too embarrassed about. Maybe I can get some actual documentation of that browser feature in pages for programmers at Web sites of the Web browsers -- Firefox, IE, Chrome, etc.

For using a GUID as a random key, I don't see what's wrong. I just ask for a new GUID whenever I need one. I use GUIDs for so many things inside my server code that no user can see a sequence of GUIDs from one of my servers. So, all a user could see would be just a few GUID values and should have one heck of a time guessing GUID values for other users. But, a well regarded generator of random strings would be easy to use also. I'm familiar with high quality random number generation, mostly would want assembler code for the arithmetic, don't want to try to write Intel x86 assembler to be called from Microsoft's Visual Basic .NET, would not want to use such a random number generator for session ID, and am not thrilled about writing my own random string generator. That's why for now I used GUIDs for session IDs. But I could ask ASP.NET to encrypt the GUIDs. Then a user could grab the encrypted string and maybe reuse it but would have to decrypt to see a GUID to guess the GUID sequence and extrapolate to a GUID of another connected user and then encrypt! Seems a bit much! Besides, they'd also have to guess the IP address of the other connected user and fake the IP/TCP/HTTP or whatever headers that report IP address. Maybe the NSA, some guys in a big basement in China, or some brilliant, bored wacko in Belarus wouldn't have anything better to do!

For what is stored in session state, I add to that right along as I write the rest of my Web pages. So I have a class, marked as

  <Serializable()> 
and add properties to it as I want something persistent during the user's logical session.

I read somewhere that Web browsers on smart phones don't support cookies. Good to learn that this is not correct.

Since cookies are now a privacy concern, I'm still reluctant to ask my users to have cookies enabled for my site. For persistence a session ID, I don't need a cookie and can use just a GUID (or a random string) in a hidden field. For persistence for user ID and password, my site doesn't use those yet!

Thanks for the answers!

1 comments

You're welcome. I had a look at your comment history and I sincerely apologize for calling you confused, I'm probably more confused than you in a lot of things. Also I appreciate your "long form" style of commenting :)

As for using either in process or SQL Server way of storing the session tokens - there is also a third way and that is writing your own session storage provider, it should be relatively easy and have all the advantages of rolling your own solution and ASP.NET session ID strength http://msdn.microsoft.com/en-us/library/ms178587(v=vs.100).a...

I don't believe you need to do anything special for the password storing (in browser) to work - just keep the same name or id on the HTML elements which accept the username and password and the URL of the login page.

An attacker can just fire as many requests as your simplest page can handle with incrementing GUIDs (not necessarily incrementing by one, GUIDs are made of some machine identification and current time so there is probably even smarter way). If any of the requests doesn't result in "Session expired" page, the attacker has just defeat your session ID because of using GUID. If you go with the custom session storage you can avoid this problem.

When you store stuff in the HttpSessionState, it gets stored (by default) in the memory of the process, it will use the custom session storage provider, if you write one.

I believe that 100% of users accept cookies. But it's true that for storing session id you don't really need it. Also in the EU we now have this stupid law requiring websites to inform users that they use cookies... http://econsultancy.com/nl/blog/9202-eu-cookie-law-three-app...

Good luck with the website - you sound like you're just the right amount of crazy for changing the world :)

"Confused" is not the worst I've been called, and at times it's, i.e., "confused", been correct!

Thanks for the feedback.

For the link to MSDN, checking my collection of such Web pages, I downloaded that page on 3/15/2012 as file number 739 from MSDN in my collection of documentation for ASP.NET, TCP/IP, etc. of the 4000+ Web pages of documentation I have so far!

Reading some of that Web page again, it looks complicated, more work to make use of their provider framework than just write my own code.

For using my code for session state store, in a Web page just write early in the execution of the Web page code

    result_code = SSS_retrieve( )
make whatever use want of

     Public users_session_state As New SPP_session
for an instance of my class

     SPP_session
and near the end of the execution of the Web page write

    result_code = SSS_store( )
Simple.

My code for making session state persistent enough, still available anywhere in my server farm with no issues about concurrency or locking, and nicely fast is really simple: So, the session state store is just a little program in Visual Basic .NET (apparently as good as anything else at making use of the common language runtime, CLR, and .NET Framework).

The program runs as just a console application started just from a command line, actually from a short scripting program (in ObjectRexx, my favorite scripting language until I convert over to Power Shell).

The program implements just a key-value store. To this program, each key is just an array of type byte; similarly for each value. The implementation is just via an instance of a .NET collection class, hopefully AVL trees or red-black trees. There is a second instance of that collection class used for handling session time outs, as I recall, hard coded at 40 minutes. We're taking simple, dirt simple, here!

The program just listens on a dedicated (hard coded!) IP port number for a connection request. Since the program is single threaded, there are no problems with concurrency or locking. That is, the program serves just one customer at a time!

From timings, on a single core, 3.0 GHz processor, the program should be able to do the work needed for a site to send 1000+ Web pages a second. If my Web site needs more capacity, then just do sharding, that is, in the code for a Web page, given a session ID, do a look up and find the IP address and port number of the executing instance of the session state store program that handles that session ID.

Keep 512 such instances busy, and could have a really busy Web site! With 16 threads and instances per processor, that would be 32 processors which would fit easily in just two standard racks. A big Web site and session state handled with just two racks! Nice!

Microsoft has a collection class in storage with scope the 'application', i.e., all Web pages in one instance of IIS, and I tried to use that storage for my session state store. The first bad news was that during development something got confused raising an exception "invalid cast". So each time I changed the code for a Web page I had to issue Microsoft command

     iisreset /restart
to get everything working again.

It is true that my way of handling session state makes my Web page code look different.

So far I'm happy with how I'm handling session state.

Thanks for the detail on how the next GUID is generated -- just add 1, which is less obscure than I had hoped.

So, maybe for a GUID start with the MAC address of a network adapter, use some time and/or date, and then increment or some such.

If a malicious user wants to break into my site, then they will have to guess both the GUID of the session ID of a current user and also that user's IP address. If that is not secure enough, then I can just ask ASP.NET to encrypt the data in the hidden field. Then a malicious user would have to decrypt to find a legal GUID, generate some trial GUIDs, encrypt, guess an IP address, and post the data back to my server. And at that point, all they have managed to do is to have my server send some confused response to the IP address of the real user with that session ID. No biggie. Besides, my Web site is not for a bank or trading Bitcoins, etc.!

For "crazy", it can look that way to others. To me I just saw an unsolved problem, turned it into a math problem, got a math solution, and wrote some code. I believe that the problem is important and my solution good. We will see, at least see if users like my solution.