From 8210cd09200d370b101072649fddd1ad9a7f32a9 Mon Sep 17 00:00:00 2001 From: hackerman <3372410+aeneasr@users.noreply.github.com> Date: Fri, 17 Mar 2023 12:34:04 +0100 Subject: [PATCH] feat: add token prefixes to session and logout tokens (#3132) This feature adds token prefixes to Ory session and logout tokens: * `ory_st_`: Ory session token prefix * `ory_lt_`: Logout token prefix --- .github/workflows/ci.yaml | 4 +- .../068f6bb6-d15f-436d-94f7-b3fd0489c9ef.json | 44 +++++++++++++++++++ persistence/sql/migratest/migration_test.go | 2 +- .../testdata/20230313141439_testdata.sql | 6 +++ ...00_session_token_length.cockroach.down.sql | 5 +++ ...141439000000_session_token_length.down.sql | 2 + ...000000_session_token_length.mysql.down.sql | 2 + ...39000000_session_token_length.mysql.up.sql | 2 + ...0000_session_token_length.sqlite3.down.sql | 29 ++++++++++++ ...000000_session_token_length.sqlite3.up.sql | 27 ++++++++++++ ...13141439000000_session_token_length.up.sql | 2 + ...141439000001_session_token_length.down.sql | 2 + ...0001_session_token_length.sqlite3.down.sql | 2 + ...13141439000001_session_token_length.up.sql | 1 + quickstart-crdb.yml | 2 +- script/testenv.sh | 2 +- session/session.go | 6 ++- test/e2e/run.sh | 2 +- x/token_prefixes.go | 7 +++ 19 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 persistence/sql/migratest/fixtures/session/068f6bb6-d15f-436d-94f7-b3fd0489c9ef.json create mode 100644 persistence/sql/migratest/testdata/20230313141439_testdata.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.cockroach.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.up.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.up.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000000_session_token_length.up.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000001_session_token_length.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000001_session_token_length.sqlite3.down.sql create mode 100644 persistence/sql/migrations/sql/20230313141439000001_session_token_length.up.sql create mode 100644 x/token_prefixes.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index aa83b577faea..c06f0dc3bc58 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -53,7 +53,7 @@ jobs: steps: - run: | docker create --name cockroach -p 26257:26257 \ - cockroachdb/cockroach:v22.1.3 start-single-node --insecure + cockroachdb/cockroach:v22.2.6 start-single-node --insecure docker start cockroach name: Start CockroachDB - run: | @@ -145,7 +145,7 @@ jobs: node-version: 16 - run: | docker create --name cockroach -p 26257:26257 \ - cockroachdb/cockroach:v20.2.5 start-single-node --insecure + cockroachdb/cockroach:v22.2.6 start-single-node --insecure docker start cockroach name: Start CockroachDB - uses: browser-actions/setup-chrome@latest diff --git a/persistence/sql/migratest/fixtures/session/068f6bb6-d15f-436d-94f7-b3fd0489c9ef.json b/persistence/sql/migratest/fixtures/session/068f6bb6-d15f-436d-94f7-b3fd0489c9ef.json new file mode 100644 index 000000000000..8c641a193e30 --- /dev/null +++ b/persistence/sql/migratest/fixtures/session/068f6bb6-d15f-436d-94f7-b3fd0489c9ef.json @@ -0,0 +1,44 @@ +{ + "id": "068f6bb6-d15f-436d-94f7-b3fd0489c9ef", + "active": false, + "expires_at": "2013-10-07T08:23:19Z", + "authenticated_at": "2013-10-07T08:23:19Z", + "authenticator_assurance_level": "aal2", + "authentication_methods": [ + { + "method": "password", + "aal": "", + "completed_at": "0001-01-01T00:00:00Z" + }, + { + "method": "totp", + "aal": "", + "completed_at": "0001-01-01T00:00:00Z" + } + ], + "issued_at": "2013-10-07T08:23:19Z", + "identity": { + "id": "5ff66179-c240-4703-b0d8-494592cefff5", + "schema_id": "default", + "schema_url": "https://www.ory.sh/schemas/ZGVmYXVsdA", + "state": "active", + "traits": { + "email": "bazbar@ory.sh" + }, + "verifiable_addresses": [ + { + "id": "45e867e9-2745-4f16-8dd4-84334a252b61", + "value": "foo@ory.sh", + "verified": false, + "via": "email", + "status": "pending", + "created_at": "2013-10-07T08:23:19Z", + "updated_at": "2013-10-07T08:23:19Z" + } + ], + "metadata_public": null, + "created_at": "2013-10-07T08:23:19Z", + "updated_at": "2013-10-07T08:23:19Z" + }, + "devices": [] +} diff --git a/persistence/sql/migratest/migration_test.go b/persistence/sql/migratest/migration_test.go index 1e54469d4cbf..ea7c940b7044 100644 --- a/persistence/sql/migratest/migration_test.go +++ b/persistence/sql/migratest/migration_test.go @@ -88,7 +88,7 @@ func TestMigrations(t *testing.T) { connections["mysql"] = dockertest.ConnectToTestMySQLPop(t) }, func() { - connections["cockroach"] = dockertest.ConnectToTestCockroachDBPop(t) + connections["cockroach"] = dockertest.ConnectPop(t, dockertest.RunTestCockroachDBWithVersion(t, "v22.2.6")) }, }) } diff --git a/persistence/sql/migratest/testdata/20230313141439_testdata.sql b/persistence/sql/migratest/testdata/20230313141439_testdata.sql new file mode 100644 index 000000000000..780229208de1 --- /dev/null +++ b/persistence/sql/migratest/testdata/20230313141439_testdata.sql @@ -0,0 +1,6 @@ +INSERT INTO sessions (id, nid, issued_at, expires_at, authenticated_at, created_at, updated_at, token, identity_id, + active, logout_token, aal, authentication_methods) +VALUES ('068f6bb6-d15f-436d-94f7-b3fd0489c9ef', '884f556e-eb3a-4b9f-bee3-11345642c6c0', '2013-10-07 08:23:19', + '2013-10-07 08:23:19', '2013-10-07 08:23:19', '2013-10-07 08:23:19', '2013-10-07 08:23:19', + 'ory_lo_5e5aad0f7a4143452df3d23733a68e3', '5ff66179-c240-4703-b0d8-494592cefff5', true, 'ory_st_5e5aad0f7a4143452df3d23733a68e2', 'aal2', + '[{"method":"password"},{"method":"totp"}]'); diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.cockroach.down.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.cockroach.down.sql new file mode 100644 index 000000000000..8d8a4d027c58 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.cockroach.down.sql @@ -0,0 +1,5 @@ +-- Downsizing is not yet supported in CockroachDB. Since this migration has no real-world impact on the application, we can safely +-- not execute it. +-- +-- ALTER TABLE sessions ALTER COLUMN token TYPE varchar(32); +-- ALTER TABLE sessions ALTER COLUMN logout_token TYPE varchar(32); diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.down.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.down.sql new file mode 100644 index 000000000000..809c038e7047 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sessions ALTER COLUMN token TYPE varchar(32); +ALTER TABLE sessions ALTER COLUMN logout_token TYPE varchar(32); diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.down.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.down.sql new file mode 100644 index 000000000000..6cd7e101faae --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sessions MODIFY COLUMN token varchar(32) NULL; +ALTER TABLE sessions MODIFY COLUMN logout_token varchar(32) NULL; diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.up.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.up.sql new file mode 100644 index 000000000000..2adcb7ce80a5 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.mysql.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sessions MODIFY COLUMN token varchar(39) NULL; +ALTER TABLE sessions MODIFY COLUMN logout_token varchar(39) NULL; diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.down.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.down.sql new file mode 100644 index 000000000000..967a41890f8a --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.down.sql @@ -0,0 +1,29 @@ +DROP INDEX sessions_token_uq_idx; +DROP INDEX sessions_logout_token_uq_idx; +DROP INDEX sessions_token_nid_idx; + +ALTER TABLE sessions RENAME COLUMN token TO old_token; +ALTER TABLE sessions RENAME COLUMN logout_token TO old_logout_token; + +ALTER TABLE sessions + ADD COLUMN token varchar(32) NULL; +ALTER TABLE sessions + ADD COLUMN logout_token varchar(32) NULL; + +UPDATE sessions +SET token = old_token +WHERE true; + +UPDATE sessions +SET logout_token = old_logout_token +WHERE true; + +ALTER TABLE sessions + DROP COLUMN old_token; + +ALTER TABLE sessions + DROP COLUMN old_logout_token; + +CREATE UNIQUE INDEX sessions_token_uq_idx ON sessions (logout_token); +CREATE UNIQUE INDEX sessions_logout_token_uq_idx ON sessions (token); +CREATE INDEX sessions_token_nid_idx ON sessions (nid, token); diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.up.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.up.sql new file mode 100644 index 000000000000..92b88cc26e70 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.sqlite3.up.sql @@ -0,0 +1,27 @@ +DROP INDEX sessions_token_uq_idx; +DROP INDEX sessions_logout_token_uq_idx; +DROP INDEX sessions_token_nid_idx; + +ALTER TABLE sessions RENAME COLUMN token TO old_token; +ALTER TABLE sessions RENAME COLUMN logout_token TO old_logout_token; +ALTER TABLE sessions + ADD COLUMN token varchar(39) NULL; +ALTER TABLE sessions + ADD COLUMN logout_token varchar(39) NULL; + +UPDATE sessions +SET token = old_token +WHERE true; + +UPDATE sessions +SET logout_token = old_logout_token +WHERE true; + +ALTER TABLE sessions + DROP COLUMN old_token; +ALTER TABLE sessions + DROP COLUMN old_logout_token; + +CREATE UNIQUE INDEX sessions_token_uq_idx ON sessions (logout_token); +CREATE UNIQUE INDEX sessions_logout_token_uq_idx ON sessions (token); +CREATE INDEX sessions_token_nid_idx ON sessions (nid, token); diff --git a/persistence/sql/migrations/sql/20230313141439000000_session_token_length.up.sql b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.up.sql new file mode 100644 index 000000000000..c78bf9b3bc1d --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000000_session_token_length.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sessions ALTER COLUMN token TYPE varchar(39); +ALTER TABLE sessions ALTER COLUMN logout_token TYPE varchar(39); diff --git a/persistence/sql/migrations/sql/20230313141439000001_session_token_length.down.sql b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.down.sql new file mode 100644 index 000000000000..db28543f6986 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.down.sql @@ -0,0 +1,2 @@ +UPDATE sessions SET token = LEFT(token, 32) WHERE TRUE; +UPDATE sessions SET logout_token = LEFT(logout_token, 32) WHERE TRUE; diff --git a/persistence/sql/migrations/sql/20230313141439000001_session_token_length.sqlite3.down.sql b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.sqlite3.down.sql new file mode 100644 index 000000000000..d0707dd681b8 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.sqlite3.down.sql @@ -0,0 +1,2 @@ +UPDATE sessions SET token = substr(token, 0, 32) WHERE TRUE; +UPDATE sessions SET logout_token = substr(logout_token, 0, 32) WHERE TRUE; diff --git a/persistence/sql/migrations/sql/20230313141439000001_session_token_length.up.sql b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.up.sql new file mode 100644 index 000000000000..4ba280517af5 --- /dev/null +++ b/persistence/sql/migrations/sql/20230313141439000001_session_token_length.up.sql @@ -0,0 +1 @@ +-- diff --git a/quickstart-crdb.yml b/quickstart-crdb.yml index ba90f3d4bb18..c94c946b0587 100644 --- a/quickstart-crdb.yml +++ b/quickstart-crdb.yml @@ -10,7 +10,7 @@ services: - DSN=cockroach://root@cockroachd:26257/defaultdb?sslmode=disable&max_conns=20&max_idle_conns=4 cockroachd: - image: cockroachdb/cockroach:v21.2.4 + image: cockroachdb/cockroach:v22.2.6 ports: - "26257:26257" command: start-single-node --insecure diff --git a/script/testenv.sh b/script/testenv.sh index 7a21c61e4e5a..4a01e5b3e714 100755 --- a/script/testenv.sh +++ b/script/testenv.sh @@ -3,7 +3,7 @@ docker rm -f kratos_test_database_mysql kratos_test_database_postgres kratos_test_database_cockroach kratos_test_hydra || true docker run --platform linux/amd64 --name kratos_test_database_mysql -p 3444:3306 -e MYSQL_ROOT_PASSWORD=secret -d mysql:8.0.23 docker run --platform linux/amd64 --name kratos_test_database_postgres -p 3445:5432 -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=postgres -d postgres:11.8 postgres -c log_statement=all -docker run --platform linux/amd64 --name kratos_test_database_cockroach -p 3446:26257 -p 3447:8080 -d cockroachdb/cockroach:v21.2.6 start-single-node --insecure +docker run --platform linux/amd64 --name kratos_test_database_cockroach -p 3446:26257 -p 3447:8080 -d cockroachdb/cockroach:v22.2.6 start-single-node --insecure docker run --platform linux/amd64 --name kratos_test_hydra -p 4444:4444 -p 4445:4445 -d -e DSN=memory -e URLS_SELF_ISSUER=http://localhost:4444/ -e URLS_LOGIN=http://localhost:4446/login -e URLS_CONSENT=http://localhost:4446/consent oryd/hydra:v2.0.2 serve all --dev source script/test-envs.sh diff --git a/session/session.go b/session/session.go index b072c8240b38..9638f410ae1c 100644 --- a/session/session.go +++ b/session/session.go @@ -12,6 +12,8 @@ import ( "strings" "time" + "github.com/ory/kratos/x" + "github.com/ory/x/httpx" "github.com/ory/x/pagination/keysetpagination" "github.com/ory/x/stringsx" @@ -214,8 +216,8 @@ func NewActiveSession(r *http.Request, i *identity.Identity, c lifespanProvider, func NewInactiveSession() *Session { return &Session{ ID: uuid.Nil, - Token: randx.MustString(32, randx.AlphaNum), - LogoutToken: randx.MustString(32, randx.AlphaNum), + Token: x.OrySessionToken + randx.MustString(32, randx.AlphaNum), + LogoutToken: x.OryLogoutToken + randx.MustString(32, randx.AlphaNum), Active: false, AuthenticatorAssuranceLevel: identity.NoAuthenticatorAssuranceLevel, } diff --git a/test/e2e/run.sh b/test/e2e/run.sh index bfa80ed77f27..073197014e32 100755 --- a/test/e2e/run.sh +++ b/test/e2e/run.sh @@ -79,7 +79,7 @@ prepare() { docker rm -f kratos_test_database_mysql kratos_test_database_postgres kratos_test_database_cockroach || true docker run --platform linux/amd64 --name kratos_test_database_mysql -p 3444:3306 -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.7 docker run --name kratos_test_database_postgres -p 3445:5432 -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=postgres -d postgres:9.6 postgres -c log_statement=all - docker run --name kratos_test_database_cockroach -p 3446:26257 -d cockroachdb/cockroach:v20.2.4 start-single-node --insecure + docker run --name kratos_test_database_cockroach -p 3446:26257 -d cockroachdb/cockroach:v22.2.6 start-single-node --insecure export TEST_DATABASE_MYSQL="mysql://root:secret@(localhost:3444)/mysql?parseTime=true&multiStatements=true" export TEST_DATABASE_POSTGRESQL="postgres://postgres:secret@localhost:3445/postgres?sslmode=disable" diff --git a/x/token_prefixes.go b/x/token_prefixes.go new file mode 100644 index 000000000000..577723e6f7ee --- /dev/null +++ b/x/token_prefixes.go @@ -0,0 +1,7 @@ +// Copyright © 2023 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +package x + +const OrySessionToken = "ory_st_" +const OryLogoutToken = "ory_lo_"