Varnish/Drupal caching for logged in users
You have two options:

Solution 1: Disallow caching in the browser

In order to prevent a browser from storing and reusing a page, you have to make sure that Cache-Control:no-cache, must-revalidate, post-check=0, pre-check=0 is on the respective (HTML) pages.

You can force this header in sub vcl_deliver. Just make sure that you do not put that header on static assets (like images, CSS and JavaScript files):

sub vcl_deliver {
  set req.http.Cache-Control = "no-cache, must-revalidate, post-check=0, pre-check=0";
}


Solution 2: Ensure that Vary: Cookie is on the response

If you want to force the browser to invalidate its cache whenever the cookies change (i.e. a session is opened), you have to ensure that the Vary: Cookie header is on the response.

sub vcl_deliver {
  if (resp.http.Vary !~ "Cookie") {
    set resp.http.Vary = resp.http.Vary + ", Cookie";
    set resp.http.Vary = regsub(resp.http.Vary, "^,\s*", "");
  }
}


Again, the cache is more effective if you restrict this fragment the page / filetypes which have different contents depending on whether a user is logged in or not.

Safari (at least v5 which is the last one for Windows and the one on iPad 1 and some older iPhones) has a nasty bug. I recommend to add the following snipped in order to deactivate the Safari browser cache:

sub vcl_deliver {
  if (resp.http.X-Generator ~ "Drupal" &amp;&amp; req.http.user-agent ~ "Safari" &amp;&amp; req.http.user-agent !~ "Chrome") {
    set resp.http.Cache-Control = "no-cache, must-revalidate, post-check=0, pre-check=0";
  }
}


Note: This is a little bit different from the solutions proposed in the comments of the bug report. By placing the snipped into vcl_deliver instead of vcl_fetch we avoid having to separate the bins. Also note that by matching on X-Generator ~ "Drupal" we avoid disabling the browser cache for static assets.

Today (November 2013) I reproduced this misbehavior on Safari 5.1.1 (Windows), 6.1 (Mac OS X 10.8 / Mountain Lion) and 7.0 (iOS 7).