contrib/os

Those integration are enabled by having the following import in the project’s orchestrion.tool.go file:

import (
	_ "github.com/DataDog/orchestrion"

	_ "github.com/DataDog/dd-trace-go/v2/contrib/os" // integration
	//...
)

Protection from Local File Inclusion (LFI) and Command Injection (CMDi) Attacks

All known functions that open files are susceptible to Local File Inclusion (LFI) attacks. This aspect protects against LFI attacks by wrapping the os.OpenFile function with a security operation that will block the operation if it is deemed unsafe.

Instrumenting only the os.OpenFile function is sufficient to protect against LFI attacks, as all other functions in the os package that open files ultimately call os.OpenFile (as of Go 1.23).

Likewise, all known functions that execute commands are susceptible to Command Injection (CMDi) attacks. This aspect protects against CMDi attacks by wrapping the os.StartProcess function with a security operation that will block the operation if it is deemed unsafe.

Instrumenting only the os.StartProcess function is sufficient to protect against CMDi attacks, as all other functions in the os and os/exec packages that spawn processes ultimately call os.StartProcess (as of Go 1.23).

OpenFile

Join Point
All of
  • Import path os
  • Function body
    • Function declaration
      • Function name OpenFile
Advice
Prepend statements produced by the following template:
// Using the following synthetic imports:
import (
	dyngo "github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/dyngo"
	events "github.com/DataDog/dd-trace-go/v2/appsec/events"
	ossec "github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/emitter/ossec"
)
__dd_parent_op, _ := dyngo.FromContext(nil)
if __dd_parent_op != nil {
		__dd_op := &ossec.OpenOperation{
				Operation: dyngo.NewOperation(__dd_parent_op),
		}

		var __dd_block bool
		dyngo.OnData(__dd_op, func(_ *events.BlockingSecurityEvent) {
				__dd_block = true
		})

		dyngo.StartOperation(__dd_op, ossec.OpenOperationArgs{
				Path: {{ .Function.Argument 0 }},
				Flags: {{ .Function.Argument 1 }},
				Perms: {{ .Function.Argument 2 }},
		})

		defer dyngo.FinishOperation(__dd_op, ossec.OpenOperationRes[*File]{
				File: &{{ .Function.Result 0 }},
				Err: &{{ .Function.Result 1 }},
		})

		if __dd_block {
				return
		}
}

StartProcess

Join Point
All of
  • Import path os
  • Function body
    • Function declaration
      • Function name StartProcess
Advice
Prepend statements produced by the following template:
// Using the following synthetic imports:
import (
	dyngo "github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/dyngo"
	events "github.com/DataDog/dd-trace-go/v2/appsec/events"
	ossec "github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/emitter/ossec"
)
__dd_parent_op, _ := dyngo.FromContext(nil)
if __dd_parent_op != nil {
		__dd_op := &ossec.RunCommandOperation{
				Operation: dyngo.NewOperation(__dd_parent_op),
		}

		var __dd_block bool
		dyngo.OnData(__dd_op, func(_ *events.BlockingSecurityEvent) {
				__dd_block = true
		})

		dyngo.StartOperation(__dd_op, ossec.RunCommandOperationArgs{
				Name: {{ .Function.Argument 0 }},
				Commands: {{ .Function.Argument 1 }},
		})

		defer dyngo.FinishOperation(__dd_op, ossec.RunCommandOperationRes[*Process]{
				Process: &{{ .Function.Result 0 }},
				Err: &{{ .Function.Result 1 }},
		})

		if __dd_block {
				return
		}
}