snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
115
oryx/jsonnetsecure/cmd.go
Normal file
115
oryx/jsonnetsecure/cmd.go
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package jsonnetsecure
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/ory/x/landlockx"
|
||||
)
|
||||
|
||||
const (
|
||||
GiB uint64 = 1024 * 1024 * 1024
|
||||
// Generous limit on virtual memory including the peak memory allocated by the Go runtime, the Jsonnet VM,
|
||||
// and the Jsonnet script.
|
||||
// This number was acquired by running:
|
||||
// Found by trial and error with:
|
||||
// `ulimit -Sv 1048576 && echo '{"Snippet": "{user_id: std.repeat(\'a\', 1000)}"}' | kratos jsonnet -0`
|
||||
// NOTE: Ideally we'd like to limit RSS but that is not possible on Linux with `ulimit/setrlimit(2)` - only with cgroups.
|
||||
virtualMemoryLimitBytes = 2 * GiB
|
||||
)
|
||||
|
||||
func NewJsonnetCmd() *cobra.Command {
|
||||
var null bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "jsonnet",
|
||||
Short: "Run Jsonnet as a CLI command",
|
||||
Hidden: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Lock the worker down to its already-open stdio: the
|
||||
// only I/O it does is read snippets/parameters from stdin
|
||||
// and write JSON to stdout/stderr. Denying all path-based
|
||||
// filesystem access prevents a malicious snippet from
|
||||
// touching the operator's file system even if the
|
||||
// jsonnet VM ever exposed a path-import primitive.
|
||||
if err := landlockx.ApplyEmpty(nil); err != nil {
|
||||
return errors.Wrap(err, "failed to apply empty landlock sandbox")
|
||||
}
|
||||
|
||||
// This could fail because current limits are lower than what we tried to set,
|
||||
// so we still continue in this case.
|
||||
SetVirtualMemoryLimit(virtualMemoryLimitBytes)
|
||||
|
||||
if null {
|
||||
return scan(cmd.OutOrStdout(), cmd.InOrStdin())
|
||||
}
|
||||
|
||||
input, err := io.ReadAll(cmd.InOrStdin())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read from stdin")
|
||||
}
|
||||
|
||||
json, err := eval(input)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to evaluate jsonnet")
|
||||
}
|
||||
|
||||
if _, err := io.WriteString(cmd.OutOrStdout(), json); err != nil {
|
||||
return errors.Wrap(err, "failed to write json output")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVarP(&null, "null", "0", false,
|
||||
`Read multiple snippets and parameters from stdin separated by null bytes.
|
||||
Output will be in the same order as inputs, separated by null bytes.
|
||||
Evaluation errors will also be reported to stdout, separated by null bytes.
|
||||
Non-recoverable errors are written to stderr and the program will terminate with a non-zero exit code.`)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func scan(w io.Writer, r io.Reader) error {
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Split(splitNull)
|
||||
for scanner.Scan() {
|
||||
json, err := eval(scanner.Bytes())
|
||||
if err != nil {
|
||||
json = fmt.Sprintf("ERROR: %s", err)
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "%s%c", json, 0); err != nil {
|
||||
return errors.Wrap(err, "failed to write json output")
|
||||
}
|
||||
}
|
||||
return errors.Wrap(scanner.Err(), "failed to read from stdin")
|
||||
}
|
||||
|
||||
func eval(input []byte) (json string, err error) {
|
||||
var params processParameters
|
||||
if err := params.Decode(input); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
vm := MakeInProcessVM()
|
||||
|
||||
for _, it := range params.ExtCodes {
|
||||
vm.ExtCode(it.Key, it.Value)
|
||||
}
|
||||
for _, it := range params.ExtVars {
|
||||
vm.ExtVar(it.Key, it.Value)
|
||||
}
|
||||
for _, it := range params.TLACodes {
|
||||
vm.TLACode(it.Key, it.Value)
|
||||
}
|
||||
for _, it := range params.TLAVars {
|
||||
vm.TLAVar(it.Key, it.Value)
|
||||
}
|
||||
|
||||
return vm.EvaluateAnonymousSnippet(params.Filename, params.Snippet)
|
||||
}
|
||||
Reference in New Issue
Block a user