Skip to content

Commit

Permalink
home: rm user's data from session token
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Mar 1, 2021
1 parent 91403d0 commit 6f4a6c9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ and this project adheres to
## [v0.105.2] - 2021-03-04
-->

### Changed

- Session token doesn't contain user's information anymore ([#2470]).

[#2470]: https://github.com/AdguardTeam/AdGuardHome/issues/2470

### Fixed

- Incomplete OpenWRT detection ([#2757]).
Expand Down
43 changes: 24 additions & 19 deletions internal/home/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package home

import (
"crypto/rand"
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"math"
"math/big"
"net/http"
"strings"
"sync"
Expand All @@ -20,8 +17,12 @@ import (
)

const (
cookieTTL = 365 * 24 // in hours
// cookieTTL is given in hours.
cookieTTL = 365 * 24
sessionCookieName = "agh_session"

// sessionTokenSize is the length of session token in bytes.
sessionTokenSize = 16
)

type session struct {
Expand Down Expand Up @@ -285,16 +286,19 @@ type loginJSON struct {
Password string `json:"password"`
}

func getSession(u *User) ([]byte, error) {
maxSalt := big.NewInt(math.MaxUint32)
salt, err := rand.Int(rand.Reader, maxSalt)
// newSessionToken returns cryptographically secure randomly generated slice of
// bytes of sessionTokenSize length.
//
// TODO(e.burkov): Think about using byte array instead of byte slice.
func newSessionToken() (data []byte, err error) {
randData := make([]byte, sessionTokenSize)

_, err = rand.Read(randData)
if err != nil {
return nil, err
}

d := []byte(fmt.Sprintf("%s%s%s", salt, u.Name, u.PasswordHash))
hash := sha256.Sum256(d)
return hash[:], nil
return randData, nil
}

func (a *Auth) httpCookie(req loginJSON) (string, error) {
Expand All @@ -303,21 +307,22 @@ func (a *Auth) httpCookie(req loginJSON) (string, error) {
return "", nil
}

sess, err := getSession(&u)
sess, err := newSessionToken()
if err != nil {
return "", err
}

now := time.Now().UTC()

a.addSession(sess, &session{
userName: u.Name,
expire: uint32(now.Unix()) + a.sessionTTL,
})

expire := now.Add(cookieTTL * time.Hour)
expstr := expire.Format(time.RFC1123)
expstr = expstr[:len(expstr)-len("UTC")] // "UTC" -> "GMT"
expstr += "GMT"

s := session{}
s.userName = u.Name
s.expire = uint32(now.Unix()) + a.sessionTTL
a.addSession(sess, &s)
expfmt := expire.Format(time.RFC1123)
// "UTC" -> "GMT"
expstr := expfmt[:len(expfmt)-len("UTC")] + "GMT"

return fmt.Sprintf("%s=%s; Path=/; HttpOnly; Expires=%s",
sessionCookieName, hex.EncodeToString(sess), expstr), nil
Expand Down
33 changes: 28 additions & 5 deletions internal/home/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package home

import (
"bytes"
"crypto/rand"
"encoding/hex"
"net/http"
"net/url"
Expand All @@ -11,6 +13,7 @@ import (

"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMain(m *testing.M) {
Expand All @@ -24,14 +27,34 @@ func prepareTestDir() string {
return dir
}

func TestNewSessionToken(t *testing.T) {
// Successful case.
token, err := newSessionToken()
require.Nil(t, err)
assert.Len(t, token, sessionTokenSize)

// Break the rand.Reader.
prevReader := rand.Reader
t.Cleanup(func() {
rand.Reader = prevReader
})
rand.Reader = &bytes.Buffer{}

// Unsuccessful case.
token, err = newSessionToken()
require.NotNil(t, err)
assert.Empty(t, token)
}

func TestAuth(t *testing.T) {
dir := prepareTestDir()
defer func() { _ = os.RemoveAll(dir) }()
t.Cleanup(func() { _ = os.RemoveAll(dir) })
fn := filepath.Join(dir, "sessions.db")

users := []User{
{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
}
users := []User{{
Name: "name",
PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2",
}}
a := InitAuth(fn, nil, 60)
s := session{}

Expand All @@ -41,7 +64,7 @@ func TestAuth(t *testing.T) {
assert.Equal(t, checkSessionNotFound, a.checkSession("notfound"))
a.RemoveSession("notfound")

sess, err := getSession(&users[0])
sess, err := newSessionToken()
assert.Nil(t, err)
sessStr := hex.EncodeToString(sess)

Expand Down

0 comments on commit 6f4a6c9

Please sign in to comment.