riverrun / phauxth

Not actively maintained - Authentication library for Phoenix, and other Plug-based, web applications
409 stars 21 forks source link

[BUG] Sessions are never validated by default #109

Closed beckler closed 5 years ago

beckler commented 5 years ago

Environment

Elixir 1.9.1 (compiled with Erlang/OTP 22)


* Operating system: 
`macOS 10.13.6`

### Current behavior

After adding the phauxth lib to my project (via the generator), once a user is logged in, their session is never validated. Removing the value from the sessions table does not prevent a user that is already logged in from accessing resources.

### Expected behavior

When the session is deleted from the table, the targeted user should no longer be able to bypass the newly required authorization.

### Additional information

This may be a known issue, but I assumed based on #41 and the [Sessions Wiki page](https://github.com/riverrun/phauxth/wiki/Sessions), that this behavior already existed.
riverrun commented 5 years ago

Could you check to see if the current_user is being set for the protected resource? You can do this by running IO.inspect conn.assigns in the controller function of the protected resource.

beckler commented 5 years ago

Okay, so here's the output logs when I initially reach a protected resource the first time:

[info] GET /accounts/user
[debug] Processing with DownstageWeb.Account.UserController.index/2
  Parameters: %{}
  Pipelines: [:browser, :protected]
[debug] QUERY OK source="sessions" db=2.4ms queue=0.1ms
SELECT s0."id", s0."expires_at", s0."user_id", s0."inserted_at", s0."updated_at" FROM "sessions" AS s0 WHERE (s0."expires_at" > $1) AND (s0."id" = $2) [~U[2019-09-12 13:08:22Z], <<196, 143, 2, 242, 161, 76, 74, 34, 173, 20, 79, 243, 152, 92, 83, 224>>]
[debug] QUERY OK source="users" db=2.0ms
SELECT u0."id", u0."email", u0."password_hash", u0."confirmed_at", u0."reset_sent_at", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) [<<71, 42, 202, 165, 20, 187, 71, 76, 132, 210, 192, 135, 147, 242, 224, 186>>]
%{
  current_user: %{
    __meta__: #Ecto.Schema.Metadata<:loaded, "users">,
    __struct__: Downstage.Accounts.User,
    companies: #Ecto.Association.NotLoaded<association :companies is not loaded>,
    confirmed_at: ~U[2019-09-03 03:38:03Z],
    email: "testing@testing.com",
    id: "472acaa5-14bb-474c-84d2-c08793f2e0ba",
    inserted_at: ~N[2019-09-03 03:37:59],
    reset_sent_at: nil,
    sessions: #Ecto.Association.NotLoaded<association :sessions is not loaded>,
    updated_at: ~N[2019-09-03 03:38:03]
  }
}
[info] user=472acaa5-14bb-474c-84d2-c08793f2e0ba message="user authenticated"
[debug] QUERY OK source="users" db=1.2ms
SELECT u0."id", u0."email", u0."password_hash", u0."confirmed_at", u0."reset_sent_at", u0."inserted_at", u0."updated_at" FROM "users" AS u0 []
[info] Sent 200 in 8ms

After I delete the session from the DB, and visit that same endpoint again, here are the produced logs:

[info] GET /accounts/user
[debug] Processing with DownstageWeb.Account.UserController.index/2
  Parameters: %{}
  Pipelines: [:browser, :protected]
[debug] QUERY OK source="sessions" db=0.8ms
SELECT s0."id", s0."expires_at", s0."user_id", s0."inserted_at", s0."updated_at" FROM "sessions" AS s0 WHERE (s0."expires_at" > $1) AND (s0."id" = $2) [~U[2019-09-12 13:08:46Z], <<196, 143, 2, 242, 161, 76, 74, 34, 173, 20, 79, 243, 152, 92, 83, 224>>]
[info] user=nil message="no user found"
[debug] QUERY OK source="users" db=1.0ms queue=0.1ms
SELECT u0."id", u0."email", u0."password_hash", u0."confirmed_at", u0."reset_sent_at", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) [<<71, 42, 202, 165, 20, 187, 71, 76, 132, 210, 192, 135, 147, 242, 224, 186>>]
[info] user=472acaa5-14bb-474c-84d2-c08793f2e0ba message="user authenticated"
[debug] QUERY OK db=5.5ms queue=0.8ms
INSERT INTO "sessions" ("expires_at","user_id","inserted_at","updated_at","id") VALUES ($1,$2,$3,$4,$5) [~U[2019-09-13 13:08:46Z], <<71, 42, 202, 165, 20, 187, 71, 76, 132, 210, 192, 135, 147, 242, 224, 186>>, ~N[2019-09-12 13:08:46], ~N[2019-09-12 13:08:46], <<53, 3, 64, 149, 182, 2, 67, 169, 139, 18, 214, 120, 11, 239, 72, 39>>]
%{
  current_user: %{
    __meta__: #Ecto.Schema.Metadata<:loaded, "users">,
    __struct__: Downstage.Accounts.User,
    companies: #Ecto.Association.NotLoaded<association :companies is not loaded>,
    confirmed_at: ~U[2019-09-03 03:38:03Z],
    email: "testing@testing.com",
    id: "472acaa5-14bb-474c-84d2-c08793f2e0ba",
    inserted_at: ~N[2019-09-03 03:37:59],
    reset_sent_at: nil,
    sessions: #Ecto.Association.NotLoaded<association :sessions is not loaded>,
    updated_at: ~N[2019-09-03 03:38:03]
  }
}
[debug] QUERY OK source="users" db=1.2ms
SELECT u0."id", u0."email", u0."password_hash", u0."confirmed_at", u0."reset_sent_at", u0."inserted_at", u0."updated_at" FROM "users" AS u0 []
[info] Sent 200 in 12ms

This is just visiting the :index function of this controller, and this is what I have for the plugs in the controller:

  plug :user_check when action in [:index, :show]
  plug :id_check when action in [:edit, :update, :delete]

Looking at the logs now, it does look like it checks the session, but if it can't find the session it looks like it generates a new row in the sessions table.

Since the session keeps getting regenerated, I also tried setting the expires_at field to a date in the past, but it doesn't seem to validate against that either.

riverrun commented 5 years ago

It would help me debug this if I coud see the code. Is it publicly available?

beckler commented 5 years ago

@riverrun It wasn't but I went ahead and opened it up.

https://github.com/beckler/downstage_umbrella

riverrun commented 5 years ago

First of all, sorry for the delay in getting back to you - I haven't felt too good the last few days.

I think the issue is that the Phauxth.Remember plug is creating a new session because there is still a remember_me cookie present. Could you check if that is the case by adding IO.inspect conn.req_cookies in the controller function? If a remember_me cookie is there, then it is working as expected, and if not, there is a problem.

beckler commented 5 years ago

Ah okay, the remember_me cookie is probably present then, as I'm fairly certain I have it hard coded it in the default session path.

Thank you for responding! And thank you for this awesome library!