Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add security logging and cwe fields #10256

Merged
merged 3 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,14 @@ const (
// Keep alive is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors
GRPCKeepAliveTime = 2 * GRPCKeepAliveEnforcementMinimum
)

// Security severity logging
const (
SecurityField = "security"
SecurityCWEField = "cwe"
notfromstatefarm marked this conversation as resolved.
Show resolved Hide resolved
SecurityEmergency = 5 // Indicates unmistakably malicious events that should NEVER occur accidentally and indicates an active attack (i.e. brute forcing, DoS)
SecurityCritical = 4 // Indicates any malicious or exploitable event that had a side effect (i.e. secrets being left behind on the filesystem)
SecurityHigh = 3 // Indicates likely malicious events but one that had no side effects or was blocked (i.e. out of bounds symlinks in repos)
SecurityMedium = 2 // Could indicate malicious events, but has a high likelihood of being user/system error (i.e. access denied)
SecurityLow = 1 // Unexceptional entries (i.e. successful access logs)
)
18 changes: 18 additions & 0 deletions docs/operator-manual/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,24 @@ at three minute intervals, just fast-tracked by the webhook event.

## Logging

### Security field

Security-related logs are tagged with a `security` field to make them easier to find, analyze, and report on.

| Level | Friendly Level | Description | Example |
|-------|----------------|---------------------------------------------------------------------------------------------------|---------------------------------------------|
| 1 | Low | Unexceptional, non-malicious events | Successful access |
| 2 | Medium | Could indicate malicious events, but has a high likelihood of being user/system error | Access denied |
| 3 | High | Likely malicious events but one that had no side effects or was blocked | Out of bounds symlinks in repo |
| 4 | Critical | Any malicious or exploitable event that had a side effect | Secrets being left behind on the filesystem |
| 5 | Emergency | Unmistakably malicious events that should NEVER occur accidentally and indicates an active attack | Brute forcing of accounts |

Where applicable, a `cwe` field is also added specifying the [Common Weakness Enumeration](https://cwe.mitre.org/index.html) number.

Please be aware that all security logs are not comprehensively tagged yet and these examples are not necessarily implemented.
notfromstatefarm marked this conversation as resolved.
Show resolved Hide resolved

### API Logs

Argo CD logs payloads of most API requests except request that are considered sensitive, such as
`/cluster.ClusterService/Create`, `/session.SessionService/Create` etc. The full list of method
can be found in [server/server.go](https://github.com/argoproj/argo-cd/blob/abba8dddce8cd897ba23320e3715690f465b4a95/server/server.go#L516).
Expand Down
15 changes: 9 additions & 6 deletions reposerver/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"k8s.io/apimachinery/pkg/api/resource"

"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/io/files"

"github.com/Masterminds/semver/v3"
Expand Down Expand Up @@ -324,9 +325,10 @@ func (s *Service) runRepoOperation(
oobError := &argopath.OutOfBoundsSymlinkError{}
if errors.As(err, &oobError) {
log.WithFields(log.Fields{
"chart": source.Chart,
"revision": revision,
"file": oobError.File,
common.SecurityField: common.SecurityHigh,
"chart": source.Chart,
"revision": revision,
"file": oobError.File,
}).Warn("chart contains out-of-bounds symlink")
return fmt.Errorf("chart contains out-of-bounds symlinks. file: %s", oobError.File)
} else {
Expand Down Expand Up @@ -354,9 +356,10 @@ func (s *Service) runRepoOperation(
oobError := &argopath.OutOfBoundsSymlinkError{}
if errors.As(err, &oobError) {
log.WithFields(log.Fields{
"repo": repo.Repo,
"revision": revision,
"file": oobError.File,
common.SecurityField: common.SecurityHigh,
"repo": repo.Repo,
"revision": revision,
"file": oobError.File,
}).Warn("repository contains out-of-bounds symlink")
return fmt.Errorf("repository contains out-of-bounds symlinks. file: %s", oobError.File)
} else {
Expand Down
20 changes: 16 additions & 4 deletions util/gpg/gpg.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ func writeKeyToFile(keyData string) (string, error) {
defer func() {
err = f.Close()
if err != nil {
log.Errorf("error closing file %q: %v", f.Name(), err)
log.WithFields(log.Fields{
common.SecurityField: common.SecurityMedium,
common.SecurityCWEField: 775,
}).Errorf("error closing file %q: %v", f.Name(), err)
}
}()
return f.Name(), nil
Expand Down Expand Up @@ -270,7 +273,10 @@ func InitializeGnuPG() error {
defer func() {
err = f.Close()
if err != nil {
log.Errorf("error closing file %q: %v", f.Name(), err)
log.WithFields(log.Fields{
common.SecurityField: common.SecurityMedium,
common.SecurityCWEField: 775,
}).Errorf("error closing file %q: %v", f.Name(), err)
}
}()

Expand All @@ -294,7 +300,10 @@ func ImportPGPKeysFromString(keyData string) ([]*appsv1.GnuPGPublicKey, error) {
defer func() {
err = f.Close()
if err != nil {
log.Errorf("error closing file %q: %v", f.Name(), err)
log.WithFields(log.Fields{
common.SecurityField: common.SecurityMedium,
common.SecurityCWEField: 775,
}).Errorf("error closing file %q: %v", f.Name(), err)
}
}()
return ImportPGPKeys(f.Name())
Expand Down Expand Up @@ -419,7 +428,10 @@ func SetPGPTrustLevel(pgpKeys []*appsv1.GnuPGPublicKey, trustLevel string) error
defer func() {
err = f.Close()
if err != nil {
log.Errorf("error closing file %q: %v", f.Name(), err)
log.WithFields(log.Fields{
common.SecurityField: common.SecurityMedium,
common.SecurityCWEField: 775,
}).Errorf("error closing file %q: %v", f.Name(), err)
}
}()

Expand Down