MCPcopy Create free account
hub / github.com/dagger/dagger / TestWorkspacePathTraversal

Method TestWorkspacePathTraversal

core/integration/workspace_test.go:411–478  ·  view source on GitHub ↗

TestWorkspacePathTraversal verifies that a module cannot use Workspace to escape the workspace root and access arbitrary host paths.

(ctx context.Context, t *testctx.T)

Source from the content-addressed store, hash-verified

409// TestWorkspacePathTraversal verifies that a module cannot use Workspace to
410// escape the workspace root and access arbitrary host paths.
411func (WorkspaceSuite) TestWorkspacePathTraversal(ctx context.Context, t *testctx.T) {
412 c := connect(ctx, t)
413
414 base := workspaceBase(t, c).
415 WithNewFile("legit.txt", "legit")
416
417 t.Run("directory traversal with ..", func(ctx context.Context, t *testctx.T) {
418 ctr := base.With(initStandaloneDangModule("escape-dir", `
419type EscapeDir {
420 pub source: Directory!
421
422 new(source: Workspace!) {
423 self.source = source.directory("../..")
424 self
425 }
426
427 pub ls: [String!] {
428 source.entries
429 }
430}
431`))
432 _, err := ctr.With(daggerCall("ls")).Stdout(ctx)
433 require.Error(t, err)
434 requireErrOut(t, err, "resolves outside root")
435 })
436
437 t.Run("file traversal with ..", func(ctx context.Context, t *testctx.T) {
438 ctr := base.With(initStandaloneDangModule("escape-file", `
439type EscapeFile {
440 pub content: String!
441
442 new(source: Workspace!) {
443 self.content = source.file("../../etc/hostname").contents
444 self
445 }
446
447 pub read: String! {
448 content
449 }
450}
451`))
452 _, err := ctr.With(daggerCall("read")).Stdout(ctx)
453 require.Error(t, err)
454 requireErrOut(t, err, "resolves outside root")
455 })
456
457 t.Run("absolute path resolves from workspace boundary", func(ctx context.Context, t *testctx.T) {
458 ctr := base.
459 WithNewFile("sub/inner.txt", "inner").
460 With(initStandaloneDangModule("abs-rel", `
461type AbsRel {
462 pub source: Directory!
463
464 new(source: Workspace!) {
465 self.source = source.directory("/sub")
466 self
467 }
468

Callers

nothing calls this directly

Calls 11

workspaceBaseFunction · 0.85
initStandaloneDangModuleFunction · 0.85
daggerCallFunction · 0.85
requireErrOutFunction · 0.85
connectFunction · 0.70
RunMethod · 0.65
ContainsMethod · 0.65
WithNewFileMethod · 0.45
WithMethod · 0.45
StdoutMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected