Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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"
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)
)
19 changes: 19 additions & 0 deletions docs/operator-manual/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,25 @@ 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.

!!! warning
Please be aware that not all security logs are comprehensively tagged yet and these examples are not necessarily implemented.

### 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