From b918a156da7d41a08c2023ef4721c0b227ed06fd Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 2 Jul 2019 17:44:38 -0400 Subject: [PATCH] Add bound cidr checking at login time for remaining auths (#7046) --- builtin/credential/aws/path_login.go | 11 +++++++++++ builtin/credential/github/path_login.go | 6 ++++++ builtin/credential/ldap/path_login.go | 6 ++++++ builtin/credential/okta/backend.go | 6 ++++++ builtin/credential/radius/path_login.go | 6 ++++++ builtin/credential/userpass/path_login.go | 10 +++++----- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/builtin/credential/aws/path_login.go b/builtin/credential/aws/path_login.go index 66fc8805d8..8a83685e8a 100644 --- a/builtin/credential/aws/path_login.go +++ b/builtin/credential/aws/path_login.go @@ -24,6 +24,7 @@ import ( uuid "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/helper/awsutil" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cidrutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/logical" @@ -605,6 +606,11 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, return logical.ErrorResponse(fmt.Sprintf("entry for role %q not found", roleName)), nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, roleEntry.TokenBoundCIDRs) { + return nil, logical.ErrPermissionDenied + } + if roleEntry.AuthType != ec2AuthType { return logical.ErrorResponse(fmt.Sprintf("auth method ec2 not allowed for role %s", roleName)), nil } @@ -1211,6 +1217,11 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request, return logical.ErrorResponse(fmt.Sprintf("entry for role %s not found", roleName)), nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, roleEntry.TokenBoundCIDRs) { + return nil, logical.ErrPermissionDenied + } + if roleEntry.AuthType != iamAuthType { return logical.ErrorResponse(fmt.Sprintf("auth method iam not allowed for role %s", roleName)), nil } diff --git a/builtin/credential/github/path_login.go b/builtin/credential/github/path_login.go index 6519850539..3080bb6cff 100644 --- a/builtin/credential/github/path_login.go +++ b/builtin/credential/github/path_login.go @@ -9,6 +9,7 @@ import ( "github.com/google/go-github/github" "github.com/hashicorp/errwrap" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cidrutil" "github.com/hashicorp/vault/sdk/helper/policyutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -148,6 +149,11 @@ func (b *backend) verifyCredentials(ctx context.Context, req *logical.Request, t return nil, logical.ErrorResponse("configuration has not been set"), nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, config.TokenBoundCIDRs) { + return nil, nil, logical.ErrPermissionDenied + } + if config.Organization == "" { return nil, logical.ErrorResponse( "organization not found in configuration"), nil diff --git a/builtin/credential/ldap/path_login.go b/builtin/credential/ldap/path_login.go index b171dde061..9c45848793 100644 --- a/builtin/credential/ldap/path_login.go +++ b/builtin/credential/ldap/path_login.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cidrutil" "github.com/hashicorp/vault/sdk/helper/policyutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -58,6 +59,11 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return logical.ErrorResponse("auth method not configured"), nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, cfg.TokenBoundCIDRs) { + return nil, logical.ErrPermissionDenied + } + username := d.Get("username").(string) password := d.Get("password").(string) diff --git a/builtin/credential/okta/backend.go b/builtin/credential/okta/backend.go index 0e384ae24b..36e6eaea65 100644 --- a/builtin/credential/okta/backend.go +++ b/builtin/credential/okta/backend.go @@ -8,6 +8,7 @@ import ( "github.com/chrismalek/oktasdk-go/okta" "github.com/hashicorp/vault/helper/mfa" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cidrutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -65,6 +66,11 @@ func (b *backend) Login(ctx context.Context, req *logical.Request, username stri return nil, logical.ErrorResponse("Okta auth method not configured"), nil, nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, cfg.TokenBoundCIDRs) { + return nil, nil, nil, logical.ErrPermissionDenied + } + client := cfg.OktaClient() type mfaFactor struct { diff --git a/builtin/credential/radius/path_login.go b/builtin/credential/radius/path_login.go index c0442935d5..d4462bd0b2 100644 --- a/builtin/credential/radius/path_login.go +++ b/builtin/credential/radius/path_login.go @@ -12,6 +12,7 @@ import ( . "layeh.com/radius/rfc2865" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/cidrutil" "github.com/hashicorp/vault/sdk/helper/policyutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -70,6 +71,11 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return logical.ErrorResponse("radius backend not configured"), nil } + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, cfg.TokenBoundCIDRs) { + return nil, logical.ErrPermissionDenied + } + username := d.Get("username").(string) password := d.Get("password").(string) diff --git a/builtin/credential/userpass/path_login.go b/builtin/credential/userpass/path_login.go index 1bda2fce44..1a81a70f6c 100644 --- a/builtin/credential/userpass/path_login.go +++ b/builtin/credential/userpass/path_login.go @@ -64,6 +64,11 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew // Get the user and validate auth user, userError := b.user(ctx, req.Storage, username) + // Check for a CIDR match. + if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, user.TokenBoundCIDRs) { + return nil, logical.ErrPermissionDenied + } + var userPassword []byte var legacyPassword bool // If there was an error or it's nil, we fake a password for the bcrypt @@ -103,11 +108,6 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return logical.ErrorResponse("invalid username or password"), nil } - // Check for a CIDR match. - if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, user.TokenBoundCIDRs) { - return logical.ErrorResponse("login request originated from invalid CIDR"), nil - } - auth := &logical.Auth{ Metadata: map[string]string{ "username": username,