Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into hperl/saml-provider
Browse files Browse the repository at this point in the history
  • Loading branch information
hperl committed Dec 10, 2024
2 parents fbfced1 + 8cbb5bd commit 91e9ade
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 43 deletions.
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

**Table of Contents**

- [ (2024-12-03)](#2024-12-03)
- [ (2024-12-04)](#2024-12-04)
- [Breaking Changes](#breaking-changes)
- [Bug Fixes](#bug-fixes)
- [Code Refactoring](#code-refactoring)
Expand Down Expand Up @@ -339,7 +339,7 @@

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# [](https://github.com/ory/kratos/compare/v1.3.0...v) (2024-12-03)
# [](https://github.com/ory/kratos/compare/v1.3.0...v) (2024-12-04)

## Breaking Changes

Expand Down Expand Up @@ -523,6 +523,15 @@ https://github.com/ory-corp/cloud/issues/7176
- Fast add credential type lookups
([#4177](https://github.com/ory/kratos/issues/4177))
([eeb1355](https://github.com/ory/kratos/commit/eeb13552118504f17b48f2c7e002e777f5ee73f4))
- Gracefully handle failing password rehashing during login
([#4235](https://github.com/ory/kratos/issues/4235))
([3905787](https://github.com/ory/kratos/commit/39057879821b387b49f5d4f7cb19b9e02ec924a7)):

This fixes an issue where we would successfully import long passwords (>72
chars), but fail when the user attempts to login with the correct password
because we can't rehash it. In this case, we simply issue a warning to the
logs, keep the old hash intact, and continue logging in the user.

- Improve QueryForCredentials
([#4181](https://github.com/ory/kratos/issues/4181))
([ca0d6a7](https://github.com/ory/kratos/commit/ca0d6a7ea717495429b8bac7fd843ac69c1ebf16))
Expand Down
77 changes: 40 additions & 37 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,54 @@

# Ory Security Policy

## Overview
This policy outlines Ory's security commitments and practices for users across
different licensing and deployment models.

This security policy outlines the security support commitments for different
types of Ory users.
To learn more about Ory's security service level agreements (SLAs) and
processes, please [contact us](https://www.ory.sh/contact/).

[Get in touch](https://www.ory.sh/contact/) to learn more about Ory's security
SLAs and process.

## Apache 2.0 License Users
## Ory Network Users

- **Security SLA:** No security Service Level Agreement (SLA) is provided.
- **Release Schedule:** Releases are planned every 3 to 6 months. These releases
will contain all security fixes implemented up to that point.
- **Version Support:** Security patches are only provided for the current
release version.
- **Security SLA:** Ory addresses vulnerabilities in the Ory Network according
to the following guidelines:
- Critical: Typically addressed within 14 days.
- High: Typically addressed within 30 days.
- Medium: Typically addressed within 90 days.
- Low: Typically addressed within 180 days.
- Informational: Addressed as necessary.
These timelines are targets and may vary based on specific circumstances.
- **Release Schedule:** Updates are deployed to the Ory Network as
vulnerabilities are resolved.
- **Version Support:** The Ory Network always runs the latest version, ensuring
up-to-date security fixes.

## Ory Enterprise License Customers

- **Security SLA:** The following timelines apply for security vulnerabilities
based on their severity:
- Critical: Resolved within 14 days.
- High: Resolved within 30 days.
- Medium: Resolved within 90 days.
- Low: Resolved within 180 days.
- Informational: Addressed as needed.
- **Release Schedule:** Updates are provided as soon as vulnerabilities are
resolved, adhering to the above SLA.
- **Version Support:** Depending on the Ory Enterprise License agreement
multiple versions can be supported.
- **Security SLA:** Ory addresses vulnerabilities based on their severity:
- Critical: Typically addressed within 14 days.
- High: Typically addressed within 30 days.
- Medium: Typically addressed within 90 days.
- Low: Typically addressed within 180 days.
- Informational: Addressed as necessary.
These timelines are targets and may vary based on specific circumstances.
- **Release Schedule:** Updates are made available as vulnerabilities are
resolved. Ory works closely with enterprise customers to ensure timely updates
that align with their operational needs.
- **Version Support:** Ory may provide security support for multiple versions,
depending on the terms of the enterprise agreement.

## Ory Network Users
## Apache 2.0 License Users

- **Security SLA:** The following timelines apply for security vulnerabilities
based on their severity:
- Critical: Resolved within 14 days.
- High: Resolved within 30 days.
- Medium: Resolved within 90 days.
- Low: Resolved within 180 days.
- Informational: Addressed as needed.
- **Release Schedule:** Updates are automatically deployed to Ory Network as
soon as vulnerabilities are resolved, adhering to the above SLA.
- **Version Support:** Ory Network always runs the most current version.
- **Security SLA:** Ory does not provide a formal SLA for security issues under
the Apache 2.0 License.
- **Release Schedule:** Releases prioritize new functionality and include fixes
for known security vulnerabilities at the time of release. While major
releases typically occur one to two times per year, Ory does not guarantee a
fixed release schedule.
- **Version Support:** Security patches are only provided for the latest release
version.

## Reporting a Vulnerability

Please head over to our
[security policy](https://www.ory.sh/docs/ecosystem/security) to learn more
about reporting security vulnerabilities.
For details on how to report security vulnerabilities, visit our
[security policy documentation](https://www.ory.sh/docs/ecosystem/security).
5 changes: 3 additions & 2 deletions hash/hash_comparator.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,10 +551,11 @@ func compareCryptHelper(password []byte, hash string) error {
return errors.WithStack(ErrMismatchedHashAndPassword)
}

var regexSSHA = regexp.MustCompile(`\{([^}]*)\}`)

// decodeSSHAHash decodes SSHA[1|256|512] encoded password hash in usual {SSHA...} format.
func decodeSSHAHash(encodedHash string) (hasher string, salt, hash []byte, err error) {
re := regexp.MustCompile(`\{([^}]*)\}`)
match := re.FindStringSubmatch(string(encodedHash))
match := regexSSHA.FindStringSubmatch(string(encodedHash))

var index_of_salt_begin int
var index_of_hash_begin int
Expand Down
2 changes: 1 addition & 1 deletion selfservice/strategy/password/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *Strategy) Login(w http.ResponseWriter, r *http.Request, f *login.Flow,

if !s.d.Hasher(ctx).Understands([]byte(o.HashedPassword)) {
if err := s.migratePasswordHash(ctx, i.ID, []byte(p.Password)); err != nil {
return nil, s.handleLoginError(r, f, p, err)
s.d.Logger().Warnf("Unable to migrate password hash for identity %s: %s Keeping existing password hash and continuing.", i.ID, err)
}
}
}
Expand Down
64 changes: 63 additions & 1 deletion selfservice/strategy/password/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ package password_test
import (
"bytes"
"context"
"crypto/sha256"
_ "embed"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"slices"
"strings"
"testing"
"time"
Expand All @@ -21,6 +24,7 @@ import (

configtesthelpers "github.com/ory/kratos/driver/config/testhelpers"

"github.com/ory/x/randx"
"github.com/ory/x/snapshotx"

"github.com/ory/kratos/driver"
Expand Down Expand Up @@ -903,6 +907,63 @@ func TestCompleteLogin(t *testing.T) {
assert.Equal(t, identifier, gjson.Get(body, "identity.traits.email").String(), "%s", body)
})

t.Run("suite=password rehashing degrades gracefully during login", func(t *testing.T) {
identifier := x.NewUUID().String() + "@google.com"
// pwd := "Kd9hUV4Xkcq87VSca6A4fq1iBijrMScBFhkpIPEwBtvTDsBwfqJCqXPPr4TkhOhsd9wFGeB3MzS4bJuesLCAjJc5s1GKJ51zW7F"
pwd := randx.MustString(100, randx.AlphaNum) // longer than bcrypt max length
require.Greater(t, len(pwd), 72) // bcrypt max length
salt := randx.MustString(32, randx.AlphaNum)
sha := sha256.Sum256([]byte(pwd + salt))
hashed := "{SSHA256}" + base64.StdEncoding.EncodeToString(slices.Concat(sha[:], []byte(salt)))
iId := x.NewUUID()
require.NoError(t, reg.PrivilegedIdentityPool().CreateIdentity(context.Background(), &identity.Identity{
ID: iId,
SchemaID: "migration",
Traits: identity.Traits(fmt.Sprintf(`{"email":%q}`, identifier)),
Credentials: map[identity.CredentialsType]identity.Credentials{
identity.CredentialsTypePassword: {
Type: identity.CredentialsTypePassword,
Identifiers: []string{identifier},
Config: sqlxx.JSONRawMessage(`{"hashed_password":"` + hashed + `"}`),
},
},
VerifiableAddresses: []identity.VerifiableAddress{
{
ID: x.NewUUID(),
Value: identifier,
Verified: true,
CreatedAt: time.Now(),
IdentityID: iId,
},
},
}))

values := func(v url.Values) {
v.Set("identifier", identifier)
v.Set("method", identity.CredentialsTypePassword.String())
v.Set("password", pwd)
}

browserClient := testhelpers.NewClientWithCookies(t)

body := testhelpers.SubmitLoginForm(t, false, browserClient, publicTS, values,
false, false, http.StatusOK, redirTS.URL)

assert.Equal(t, identifier, gjson.Get(body, "identity.traits.email").String(), "%s", body)

// check that the password hash algorithm is unchanged
_, c, err := reg.PrivilegedIdentityPool().FindByCredentialsIdentifier(context.Background(), identity.CredentialsTypePassword, identifier)
require.NoError(t, err)
var o identity.CredentialsPassword
require.NoError(t, json.NewDecoder(bytes.NewBuffer(c.Config)).Decode(&o))
assert.Equal(t, hashed, o.HashedPassword)

// login still works
body = testhelpers.SubmitLoginForm(t, false, browserClient, publicTS, values,
false, true, http.StatusOK, redirTS.URL)
assert.Equal(t, identifier, gjson.Get(body, "identity.traits.email").String(), "%s", body)
})

t.Run("suite=password migration hook", func(t *testing.T) {
ctx := context.Background()

Expand Down Expand Up @@ -948,7 +1009,8 @@ func TestCompleteLogin(t *testing.T) {

require.NoError(t, reg.Config().Set(ctx, config.ViperKeyPasswordMigrationHook, map[string]any{
"config": map[string]any{"url": ts.URL},
"enabled": true}))
"enabled": true,
}))

for _, tc := range []struct {
name string
Expand Down

0 comments on commit 91e9ade

Please sign in to comment.