Well, the scenario you describe is actually a perfectly acceptable one. There's no way for anyone to change session state unless you explicitly let them, say through input or something, thus any security problem is in how you'd accept the information rather than how you chose to store and use it. For instance, if the Session info is based on say, TextBox input, the question would be: who cares if they give different input before the transfer? And if it's based on some calculation or the result of some processing, the question is: why are you giving the client access to such things?
That said, there are a few ways to address your concerns, the first of which would be to use Server.Transfer instead of Response.Redirect so it doesn't matter if they try to block the transfer on the client because it would happen on the server. If you do that, however, you'll want to use Context instead of Session to store the information so you still keep it on the server, but don't have to worry about cleanup (Context info is dumped after each request).
You also have the option of blocking changes to the Session if a value is already present, perhaps accessing the Session object by proxy through a SessionManager object that handles duplicate checks in a consistant way and knows when to clean itself (say by exposing a Get(string name, bool removeAfterGet) function that takes a bool indicating whether or not to remove the objects from session).
Yet another alternative would be to store a hash of the content in your storage mechanism (similar to what ASP.NET does with the Forms Authentication Cookie) so that you can see if the information has been tampered with, but you'd need to make sure you don't let your code just recalculate a new hash when new information comes in.