Skip to content

Commit 3dc98f3

Browse files
Prevent writing outside allowed directories list from a config payload with actions (#766)
* added AllowedDirectories to agent details, added tests for allowed directories
1 parent ef9524a commit 3dc98f3

File tree

19 files changed

+659
-348
lines changed

19 files changed

+659
-348
lines changed

Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,11 @@ $(TEST_BUILD_DIR):
176176

177177
# Unit tests
178178
unit-test: $(TEST_BUILD_DIR) test-core test-plugins test-sdk test-extensions ## Run unit tests
179-
echo 'mode: atomic' > $(TEST_BUILD_DIR)/coverage.out
180-
tail -q -n +2 $(TEST_BUILD_DIR)/*_coverage.out >> $(TEST_BUILD_DIR)/coverage.out
181-
go tool cover -html=$(TEST_BUILD_DIR)/coverage.out -o $(TEST_BUILD_DIR)/coverage.html
182-
@printf "\nTotal code coverage: " && go tool cover -func=$(TEST_BUILD_DIR)/coverage.out | grep 'total:' | awk '{print $$3}'
179+
@tail -q -n +2 $(TEST_BUILD_DIR)/*_coverage.out >> $(TEST_BUILD_DIR)/tmp_coverage.out
180+
@echo 'mode: atomic' > $(TEST_BUILD_DIR)/coverage.out
181+
@cat $(TEST_BUILD_DIR)/tmp_coverage.out | grep -v ".pb.go" | grep -v ".gen.go" | grep -v ".pb.validate.go" | grep -v "fake_" | grep -v "_mock.go" | grep -v "_stub.go" >> $(TEST_BUILD_DIR)/coverage.out
182+
@go tool cover -html=$(TEST_BUILD_DIR)/coverage.out -o $(TEST_BUILD_DIR)/coverage.html
183+
@printf "\nTotal code coverage: " && $(GOTOOL) cover -func=$(TEST_BUILD_DIR)/coverage.out | grep 'total:' | awk '{print $$3}'
183184

184185
test-core: $(TEST_BUILD_DIR) ## Run core unit tests
185186
GOWORK=off CGO_ENABLED=0 go test -count=1 -coverprofile=$(TEST_BUILD_DIR)/core_coverage.out -covermode count ./src/core/...

docs/proto/proto.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ Represents agent details. This message is sent from the management server to the
215215
| tags | [string](#string) | repeated | List of tags |
216216
| alias | [string](#string) | | Alias name for the agent |
217217
| server | [Server](#f5-nginx-agent-sdk-Server) | | Server setting for the agent |
218+
| allowed_directories | [string](#string) | repeated | List of allowed directories that the Agent can write to |
218219

219220

220221

sdk/proto/agent.pb.go

Lines changed: 144 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/proto/agent.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ message AgentDetails {
8282
string alias = 4 [(gogoproto.jsontag) = "alias"];
8383
// Server setting for the agent
8484
Server server = 5 [(gogoproto.jsontag) = "server"];
85+
// List of allowed directories that the Agent can write to
86+
repeated string allowed_directories = 6 [(gogoproto.jsontag) = "allowed_directories"];
8587
}
8688

8789
message Server {

src/core/config/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ type Config struct {
3838
QueueSize int `mapstructure:"queue_size" yaml:"queue_size,omitempty"`
3939
}
4040

41+
func (c *Config) AllowedDirectories() []string {
42+
values := []string{}
43+
44+
// Iterate through the map and append keys to the slice
45+
for key := range c.AllowedDirectoriesMap {
46+
values = append(values, key)
47+
}
48+
return values
49+
}
50+
4151
func (c *Config) IsGrpcServerConfigured() bool {
4252
return c.Server.Host != "" && c.Server.GrpcPort != 0
4353
}

src/core/environment_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,16 @@ func TestWriteFilesNotAllowed(t *testing.T) {
732732
Contents: []byte("multi"),
733733
Permissions: "0644",
734734
},
735+
{
736+
Name: "etc/shadow/multiple1.conf",
737+
Contents: []byte("shadowfile2"),
738+
Permissions: "0644",
739+
},
740+
{
741+
Name: "/hello.conf",
742+
Contents: []byte("rootfile"),
743+
Permissions: "0644",
744+
},
735745
}
736746
backup, err := sdk.NewConfigApplyWithIgnoreDirectives("", nil, []string{})
737747
assert.NoError(t, err)

src/core/nginx.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,11 @@ func (n *NginxBinaryType) writeConfigWithWithFileActions(
502502
return nil, err
503503
}
504504

505+
confDir := filepath.Dir(details.ConfPath)
506+
if err := ensureFilesAllowed(confFiles, n.config.AllowedDirectoriesMap, confDir); err != nil {
507+
return configApply, err
508+
}
509+
505510
for _, file := range confFiles {
506511
rootDirectoryPath := filepath.Dir(details.ConfPath)
507512
fileFullPath := file.Name
@@ -519,6 +524,10 @@ func (n *NginxBinaryType) writeConfigWithWithFileActions(
519524
}
520525
}
521526

527+
if err := ensureFilesAllowed(auxFiles, n.config.AllowedDirectoriesMap, confDir); err != nil {
528+
return configApply, err
529+
}
530+
522531
for _, file := range auxFiles {
523532
rootDirectoryPath := config.GetZaux().GetRootDirectory()
524533
fileFullPath := file.Name

src/plugins/registration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ func (r *OneTimeRegistration) registerAgent() {
229229
MaxElapsedTime: r.config.Server.Backoff.MaxElapsedTime.Milliseconds(),
230230
},
231231
},
232+
AllowedDirectories: r.config.AllowedDirectories(),
232233
},
233234
},
234235
Details: details,

test/integration/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go

Lines changed: 144 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/vendor/github.com/nginx/agent/v2/src/core/config/types.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/vendor/github.com/nginx/agent/v2/src/core/nginx.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)