Funny thing happened at work the other day...

1 reply [Last post]
Kayin
Offline
SX Retired
Joined: 2008/10/09

My boss and I were demoing a web application to a client the other day. Part of the application involves filling out a form. We wanted the application to "remember" all previous form submissions throughout a session and auto-fill any form fields that the user may need to fill out later. This is a pretty common thing.

User fills out a form -> user clicks submit -> form does it's magic -> user goes to another form -> form is already filled out using the previous form submission.

Simple right?

Well out of good practice I decided to implement a "Session Helper" object that would encapsulate all the session-handling functionality to achieve the desired functionality that I described above. I used a singleton object to achieve uniformity and easy API

See below:

<pre>
       public class SessionHelper
        {
                private static List<IWhitePaperRequest> _papers;
                public static List<IWhitePaperRequest> WhitePaperRequests
                {
                        get
                        {
                                if (_papers == null)
                                {
                                        if (HttpContext.Current.Session["WhitePaperRequests"] == null)
                                        {
                                                _papers = new List<IWhitePaperRequest>();
                                                HttpContext.Current.Session["WhitePaperRequests"] = _papers;
                                                return _papers;
                                        }
                                        return (List<IWhitePaperRequest>)HttpContext.Current.Session["WhitePaperRequests"];
                                }
                                else
                                {
                                        return _papers;
                                }
                        }
                }

                private static List<IServiceRequest> _services;
                public static List<IServiceRequest> ServiceRequests
                {
                        get
                        {
                                if (_services == null)
                                {
                                        if (HttpContext.Current.Session["ServiceRequests"] == null)
                                        {
                                                _services = new List<IServiceRequest>();
                                                HttpContext.Current.Session["ServiceRequests"] = _services;
                                                return _services;
                                        }
                                        return (List<IServiceRequest>)HttpContext.Current.Session["ServiceRequests"];
                                }
                                else
                                {
                                        return _services;
                                }
                        }
                }
        }
</pre>

Upon demoing this, my boss and I noticed something rather funny. The client would submit a form, then we would go to the website and attempt to fill in a form and see the client's session data!

Turns out in ASP.NET (and I think all web applications) static memory is unique to the application. It's shared by all sessions on the web server meaning it's not unique per HTTP Request.

The more I got to thinking about it the more obvious this was. I mean what is Session Memory anyway? It's just static memory that's referenced by the session id. My mistake in the code was that I was sticking session-specific information in static memory and then exposing that memory to everyone. Big nasty security flaw.

This got me thinking about Web Proxies. It would be incredibly easy for a programmer to store the proxy session information in static memory to be accessed by a "back door" for easy logging/viewing purposes. Incredibly stinking easy. Easier than it would be to build a logger into the application. Just look at my code above. I don't have to code anything extra to eavesdrop, just a foreach loop on the static list.

This may be old news to some of you guys, but I found it interesting. It was my mistake afterall.

-K