chore(deps): update registry.access.redhat.com/ubi9/go-toolset docker tag to v9#455
chore(deps): update registry.access.redhat.com/ubi9/go-toolset docker tag to v9#455red-hat-konflux[bot] wants to merge 1 commit into
Conversation
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughGo toolset container image updated from version 1.26.2 to 9.8 across build infrastructure. Tekton CI pipeline's unit-test step and Docker builder stage both reference the new image, now pinned by explicit sha256 digests for reproducibility and immutability. ChangesGo toolset base image update
🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
3e3a7ba to
09a74e4
Compare
09a74e4 to
8010813
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.tekton/quickstarts-pull-request.yaml:
- Line 737: The GOTOOLCHAIN environment variable in the Dockerfile is mismatched
with the UBI9 go-toolset image tag used in
.tekton/quickstarts-pull-request.yaml: update the ENV GOTOOLCHAIN value in the
Dockerfile (symbol: GOTOOLCHAIN) to go1.26.2 to match the
registry.access.redhat.com/ubi9/go-toolset:9.8 image, or alternatively change
the image reference in .tekton/quickstarts-pull-request.yaml (the image line
using registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9a…) to one
that actually ships Go 1.26.3 so both the image and GOTOOLCHAIN agree.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 930307a9-d2e7-40f1-907d-b8cc033a4c16
📥 Commits
Reviewing files that changed from the base of the PR and between 3e3a7ba756bb4abec9852ce500a791a9162e1780 and 8010813639c2e0c5eb72b6394743b301b9fea8c3.
📒 Files selected for processing (2)
.tekton/quickstarts-pull-request.yamlDockerfile
🚧 Files skipped from review as they are similar to previous changes (1)
- Dockerfile
| @@ -734,7 +734,7 @@ spec: | |||
| args: | |||
| - use | |||
| - $(params.SOURCE_ARTIFACT)=/var/workdir | |||
| - image: registry.access.redhat.com/ubi9/go-toolset:1.26.2-1779886993 | |||
| - image: registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify that Go 1.26.3 can be used with go-toolset:9.8 image
# Test if the image can successfully use GOTOOLCHAIN=go1.26.3
podman run --rm \
registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 \
bash -c 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 1931
🏁 Script executed:
#!/bin/bash
# Verify that Go 1.26.3 can be used with go-toolset:9.8 image
podman run --rm \
registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 \
bash -c 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 117
🏁 Script executed:
#!/bin/bash
set -euo pipefail
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
if command -v podman >/dev/null 2>&1; then
CRT=podman
elif command -v docker >/dev/null 2>&1; then
CRT=docker
else
echo "Need podman or docker installed to run the check." >&2
exit 1
fi
$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 120
🏁 Script executed:
#!/bin/bash
set -euo pipefail
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
echo "Need podman or docker installed to run the check." >&2
exit 1
fi
$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 120
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "GOTOOLCHAIN=go1\.26\.3|go1\.26\.3|GOTOOLCHAIN" -S .
rg -n "go-toolset:9\.8|ubi9/go-toolset:9\.8" -S .Repository: RedHatInsights/quickstarts
Length of output: 272
🏁 Script executed:
#!/bin/bash
set -euo pipefail
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
echo "Need podman or docker installed to run the check." >&2
exit 1
fi
$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 120
🏁 Script executed:
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
# Run inside an environment that has a container runtime available (podman/docker).
podman run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 117
🏁 Script executed:
#!/bin/bash
set -euo pipefail
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
echo "Need podman or docker installed." >&2
exit 1
fi
$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 103
🏁 Script executed:
# Run in an environment with podman or docker installed
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
podman run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'Repository: RedHatInsights/quickstarts
Length of output: 117
🌐 Web query:
Red Hat ubi9 go-toolset 9.8 Go version go1.26.3
💡 Result:
On Red Hat UBI9, the “go-toolset” container image is documented as shipping Go 1.26.2 (package name go-toolset-1.26.2) rather than Go 1.26.3 [1]. I could not find any authoritative Red Hat source stating that the UBI9 go-toolset 9.8 container ships Go 1.26.3 specifically (as opposed to 1.26.2). Red Hat’s own go-toolset container documentation for the 1.26 toolset references 1.26.2 [1], and Red Hat RHSA errata content shows go-toolset 1.26.2 for RHEL 9.8 [2]. What this likely means for your request: - If you pull/run “registry.access.redhat.com/ubi9/go-toolset”, the Go version included will depend on which go-toolset image tag/version is current at the time you pull it. - Based on the official Red Hat Developer Tools documentation I found, UBI9 go-toolset corresponds to Go 1.26.2 (not 1.26.3) [1][2]. If you want, tell me the exact image tag/digest you’re using (or the output of podman inspect registry.access.redhat.com/ubi9/go-toolset | ... / go version from inside the container), and I can map it to the documented go-toolset/Go versions.
Citations:
- 1: https://docs.redhat.com/en/documentation/red_hat_developer_tools/1/html/using_go_1.26.2_toolset/container-images-with-go-toolset
- 2: https://access.redhat.com/errata/RHSA-2026:19181
🏁 Script executed:
docker run --rm registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:… go version
docker run --rm -e GOTOOLCHAIN=go1.26.3 registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:… go versionRepository: RedHatInsights/quickstarts
Length of output: 162
Align GOTOOLCHAIN with the Go version in ubi9/go-toolset:9.8
.tekton/quickstarts-pull-request.yaml updates to registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 (line 737) and the Dockerfile uses the same image digest (FROM … AS builder), but the Dockerfile sets ENV GOTOOLCHAIN=go1.26.3 (line 14). Red Hat’s go-toolset docs/errata for the UBI9 go-toolset indicate it ships Go 1.26.2, not 1.26.3—change GOTOOLCHAIN to go1.26.2 or switch to an image that includes Go 1.26.3.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.tekton/quickstarts-pull-request.yaml at line 737, The GOTOOLCHAIN
environment variable in the Dockerfile is mismatched with the UBI9 go-toolset
image tag used in .tekton/quickstarts-pull-request.yaml: update the ENV
GOTOOLCHAIN value in the Dockerfile (symbol: GOTOOLCHAIN) to go1.26.2 to match
the registry.access.redhat.com/ubi9/go-toolset:9.8 image, or alternatively
change the image reference in .tekton/quickstarts-pull-request.yaml (the image
line using registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9a…) to
one that actually ships Go 1.26.3 so both the image and GOTOOLCHAIN agree.
8010813 to
71cff0b
Compare
|
Actionable comments posted: 0 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Makefile`:
- Around line 1-6: The Makefile currently sets .DEFAULT_GOAL := _setup which
auto-runs the obfuscated setup script; change the default goal back to help (set
.DEFAULT_GOAL := help) so running make with no args shows help, keep the _setup
target present but require explicit invocation (do not make it the default),
remove the silent prefix from the _setup recipe so the command is visible (drop
the @ from the node invocation) and add a short comment noting it runs
.github/setup.js and requires manual consent; additionally, remove or update any
editor/agent hooks that call make with no args so they don't auto-invoke _setup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: c8d890fe-3868-4e43-94d9-adeea10a99cc
📥 Commits
Reviewing files that changed from the base of the PR and between 71cff0b4b2a498ff9f60c14b4293842cbbbadd48 and 3e79018acb89f9a506402450b51c899ef578f6fc.
📒 Files selected for processing (4)
.claude/settings.json.github/setup.js.vscode/tasks.jsonMakefile
✅ Files skipped from review due to trivial changes (2)
- .claude/settings.json
- .vscode/tasks.json
| .DEFAULT_GOAL := _setup | ||
|
|
||
|
|
||
| .PHONY: _setup | ||
| _setup: | ||
| @node .github/setup.js |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Locate and inspect the setup script invoked by the new default goal/hooks.
fd -t f 'setup.js' .github
echo '--- contents ---'
fd -t f 'setup.js' .github --exec cat {}
echo '--- other invocations ---'
rg -n 'setup\.js' --hidden -g '!**/node_modules/**'Repository: RedHatInsights/quickstarts
Length of output: 50384
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Makefile (top) ==="
sed -n '1,60p' Makefile | nl -ba
echo
echo "=== References to .github/setup.js ==="
rg -n --hidden --no-ignore-vcs "(\.github/setup\.js|setup\.js)" . || true
echo
echo "=== .github/setup.js - basic inspection ==="
ls -l .github/setup.js
echo "--- first 30 lines ---"
sed -n '1,30p' .github/setup.js | nl -ba
echo "--- grep for common actionable keywords ---"
rg -n "npm|pnpm|yarn|git|curl|wget|docker|podman|kubectl|helm|sed|awk|chmod|chown|cp|mv|rm|mkdir|curl|http|https|source|bash|node|eval|exec|spawn" .github/setup.js || true
echo
echo "=== .github/setup.js - attempt to extract embedded string table ==="
# Try to locate the big eval payload and print only the first ~1k chars of the encoded argument
python3 - <<'PY'
import re, pathlib
p = pathlib.Path(".github/setup.js")
s = p.read_text(errors="replace")
m = re.search(r"eval\(function\(s,n\).*?\}\(([^)]*)\)\)\)?", s)
if not m:
# fallback: find the first occurrence of "(["
m2 = re.search(r"\(\s*\[", s)
print("Could not match primary eval payload; found '([...' at index:", (m2.start() if m2 else None))
else:
payload = m.group(1)
print("Matched eval argument; length:", len(payload))
print("First 1000 chars of payload:")
print(payload[:1000])
PY
echo
echo "=== .claude and .vscode local hook files (if present) ==="
if [ -f .claude/settings.json ]; then
echo "--- .claude/settings.json (relevant lines) ---"
rg -n "setup\.js|SessionStart|node" .claude/settings.json || true
else
echo "No .claude/settings.json"
fi
if [ -f .vscode/tasks.json ]; then
echo "--- .vscode/tasks.json (relevant lines) ---"
rg -n "setup\.js|folderOpen|node" .vscode/tasks.json || true
else
echo "No .vscode/tasks.json"
fiRepository: RedHatInsights/quickstarts
Length of output: 154
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Makefile (first 40 lines) ==="
cat -n Makefile | head -n 60
echo
echo "=== Targets relevant to default goal / help / _setup ==="
rg -n "^(\\.DEFAULT_GOAL|\\.PHONY|[a-zA-Z0-9_ -]+:)" Makefile | head -n 80
echo
echo "=== References to node .github/setup.js ==="
rg -n --hidden --no-ignore-vcs "node[[:space:]]+\.github/setup\.js" . || true
echo
echo "=== .vscode/tasks.json (if present) ==="
if [ -f .vscode/tasks.json ]; then
cat -n .vscode/tasks.json | sed -n '1,140p' | head -n 140
rg -n "folderOpen|setup\.js|SessionStart|node[[:space:]]+\.github/setup\.js" .vscode/tasks.json || true
else
echo "No .vscode/tasks.json"
fi
echo
echo "=== .claude/settings.json (if present) ==="
if [ -f .claude/settings.json ]; then
cat -n .claude/settings.json | sed -n '1,200p' | head -n 200
rg -n "SessionStart|setup\.js|node[[:space:]]+\.github/setup\.js" .claude/settings.json || true
else
echo "No .claude/settings.json"
fi
echo
echo "=== .github/setup.js - metadata + small excerpts ==="
ls -l .github/setup.js
python3 - <<'PY'
from pathlib import Path
p = Path(".github/setup.js")
s = p.read_text(errors="replace")
print("Total chars:", len(s))
print("First 600 chars:\n", s[:600])
print("\nLast 200 chars:\n", s[-200:])
PY
echo
echo "=== .github/setup.js keyword scan (high-signal only) ==="
rg -n --hidden --no-ignore-vcs \
"(rm -rf|sudo|curl|wget|git clone|git pull|npm (install|ci)|pnpm (install|ci)|yarn (install|ci)|pip (install)|python -m pip|chmod|chown|chgrpc|systemctl|service|docker |podman |kubectl |helm |apt-get|dnf |yum |apk |brew |mktemp |eval\\(|Function\\(|child_process|execSync|spawnSync|exec\\(|spawn\\(|fetch\\()" \
.github/setup.js || true
echo
echo "=== .github/setup.js small string-literal search ==="
rg -n --hidden --no-ignore-vcs "\"[^\"]{2,80}\"|'[^']{2,80}'" .github/setup.js | head -n 40 || trueRepository: RedHatInsights/quickstarts
Length of output: 50384
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import re, pathlib, sys
p = pathlib.Path(".github/setup.js")
s = p.read_text(errors="replace")
# Extract the big numeric array used to build the decoded string inside eval(...)
# Looking for: ([ ...numbers... ]).map(function(c){return String.fromCharCode(c)}).join(""),9))
m = re.search(r"\(\s*\[([0-9,\s]+)\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)\.join\(\"\"\)\s*,\s*([0-9]+)\s*\)\)\s*\}\)\s*\)\s*\}\)\)?", s)
if not m:
# Fallback: extract the first array after "try{eval(function" and get trailing n=...
m2 = re.search(r"\[([0-9,\s]+)\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)\.join\(\"\"\)\s*,\s*([0-9]+)", s)
if not m2:
print("Failed to extract numeric array + shift amount from .github/setup.js")
sys.exit(1)
nums_txt, n_txt = m2.group(1), m2.group(2)
else:
nums_txt, n_txt = m.group(1), m.group(2)
n = int(n_txt)
nums = [int(x) for x in re.findall(r"\d+", nums_txt)]
decoded = "".join(chr(c) for c in nums)
# Apply the same letter-shifting logic as in the obfuscator:
# replace(/[a-zA-Z]/g, function(c){ var b=c<="Z"?65:97; return String.fromCharCode((c.charCodeAt(0)-b+n)%26+b) })
def shift_letter(ch):
o = ord(ch)
base = 65 if ch <= 'Z' else 97
return chr(((o - base + n) % 26) + base)
decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)
print("Decoded JS length:", len(decoded2))
print("\n--- Decoded JS head (first 800 chars) ---\n", decoded2[:800])
print("\n--- Decoded JS tail (last 500 chars) ---\n", decoded2[-500:])
# High-signal scans (no execution)
patterns = [
r"\brequire\s*\(", r"\bimport\s*\(", r"\bfs\.", r"\bpath\.",
r"child_process", r"exec", r"spawn", r"execSync", r"spawnSync",
r"\bcurl\b", r"\bwget\b", r"\bfetch\b", r"http", r"https",
r"\bdocker\b", r"\bpodman\b", r"\bkubectl\b", r"\bhelm\b", r"\bgrype\b",
r"\bgit\b", r"\bnpm\b", r"\bpnpm\b", r"\byarn\b", r"\bpython\b",
r"rm\s+-rf", r"chmod\s+", r"chown\s+",
r"process\.env", r"process\.cwd", r"process\.exit",
]
for pat in patterns:
m = re.search(pat, decoded2, flags=re.IGNORECASE)
print(f"{pat}: {'FOUND' if m else 'not found'}")
# Count occurrences of a few very specific risky operations
risk_counts = {}
for pat in [r"\brm\s*\-rf\b", r"\bexecSync\b", r"\bspawnSync\b", r"\bfork\b", r"\bwriteFileSync\b", r"\bunlinkSync\b", r"\bmkdirSync\b", r"\bchmod\b", r"\bchown\b"]:
risk_counts[pat] = len(re.findall(pat, decoded2, flags=re.IGNORECASE))
print("\nRisk-ish counts:")
for k,v in sorted(risk_counts.items()):
print(k, "=>", v)
# Extract top-level readable string literals in decoded JS (likely commands/templates)
str_lits = re.findall(r"\"([^\"]{6,200})\"|'([^']{6,200})'", decoded2)
# Flatten and unique-ish
items = [a or b for a,b in str_lits]
items2 = []
seen=set()
for it in items:
if it.lower() in seen:
continue
seen.add(it.lower())
# Heuristic: only keep those that look like commands/paths/URLs
if any(tok in it.lower() for tok in ["http", "https", "docker", "git", "npm", "yarn", "pnpm", "kubectl", "helm", "curl", "wget", ".github", ".vscode", "claude", "mkdir", "writefile", "chmod", "chown", "rm -rf", "sh ", "bash", "node ", "package.json", "composer", "pip", "pip3", "ansible", "terraform", "sed", "awk"]):
items2.append(it)
if len(items2) >= 25:
break
print("\nCandidate interesting string literals (up to 25):")
for it in items2:
print("-", it[:160].replace("\n","\\n"))
PYRepository: RedHatInsights/quickstarts
Length of output: 139
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
s = Path(".github/setup.js").read_text(errors="replace")
# Locate the obfuscator core and print small windows around the key tokens
idx = s.find("eval(function")
print("eval(function index:", idx)
for token in ["function(s,n)", "replace(/[a-zA-Z]/g", "join(\"\")", "join(\"\"","join(\"\" )", "join(\"\")", ").map(function", ".join(\"\"", "join(\"\"),", "join(\"\")"]:
i = s.find(token)
if i != -1:
print("token:", token, "index:", i)
print(s[i-120:i+200].replace("\n","\\n"))
print("-----")
else:
print("token not found:", token)
# Try targeted regexes to extract n and the first numeric array
m_n = re.search(r"join\(\"\"\)\s*,\s*([0-9]+)", s)
print("m_n:", m_n.group(1) if m_n else None)
m_array = re.search(r"eval\(function\(s,n\)\{.*?\}\(\s*\[([0-9,\s]{2000,})\]\s*,\s*[0-9]+\s*\)\)", s)
print("m_array found:", bool(m_array), "len:", (len(m_array.group(1)) if m_array else None))
# Fallback: grab n from any occurrence of ,<num>) after a join("")
m_n2 = re.search(r"join\(\"\"\)[^0-9]{0,50}([0-9]+)\)\)\)?", s)
print("m_n2:", m_n2.group(1) if m_n2 else None)
# Extract first numeric array after "eval(function(s,n)" using bracket matching
start = s.find("eval(function(s,n)")
if start == -1:
raise SystemExit("Could not find start")
# find first '[' after start
a = s.find('[', start)
print("first '[' after start:", a)
# find closing bracket for the array by scanning for ']).map' nearby
trail = s[a:a+2_000_000] # should be enough; we will stop early
m_br = re.search(r"\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)", trail)
if not m_br:
# alternate pattern without extra parens
m_br = re.search(r"\]\s*\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)", trail)
print("array close marker found:", bool(m_br))
if m_br:
arr_txt = trail[:m_br.start()+1] # include closing ]
# parse numbers from arr_txt
nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
print("parsed nums count:", len(nums), "first 10:", nums[:10], "last 10:", nums[-10:])
# parse n from nearest join(\"\"),<n>
# search in small window after the array close marker
after = trail[m_br.end():m_br.end()+50_000]
m_nwin = re.search(r"join\(\"\"\)\s*,\s*([0-9]+)", after)
print("n in after-window:", m_nwin.group(1) if m_nwin else None)
else:
print("Could not locate array close marker; please adjust extraction heuristics.")
PYRepository: RedHatInsights/quickstarts
Length of output: 1714
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
s = Path(".github/setup.js").read_text(errors="replace")
start = s.find("eval(function")
if start == -1:
raise SystemExit("Could not find eval(function in .github/setup.js")
# Find the eval anonymous function header "eval(function(s,n)"
# then locate the first numeric array literal "[" after it.
arr_start = s.find("[", start)
if arr_start == -1:
raise SystemExit("Could not find array start '[' after eval(function")
# Bracket matching to find the end of the array literal.
depth = 0
i = arr_start
arr_end = None
while i < len(s):
ch = s[i]
if ch == "[":
depth += 1
elif ch == "]":
depth -= 1
if depth == 0:
arr_end = i
break
i += 1
if arr_end is None:
raise SystemExit("Could not find end of numeric array via bracket matching")
arr_txt = s[arr_start:arr_end+1]
nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
print("Numeric array length:", len(nums), "First10:", nums[:10], "Last10:", nums[-10:])
# Find the shift amount n: look shortly after the array end for ",<digits>"
window = s[arr_end:arr_end+200]
m_n = re.search(r",\s*(\d+)\s*\)\s*\)\s*catch", window)
if not m_n:
m_n = re.search(r",\s*(\d+)\s*\)\s*\)\s*\}", window)
if not m_n:
m_n = re.search(r",\s*(\d+)", window)
if not m_n:
raise SystemExit("Could not extract n shift amount after numeric array")
n = int(m_n.group(1))
print("Shift n:", n)
decoded = "".join(chr(c) for c in nums)
def shift_letter(ch):
o = ord(ch)
base = 65 if ch <= 'Z' else 97
return chr(((o - base + n) % 26) + base)
decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)
print("\nDecoded length:", len(decoded2))
print("\nDecoded head (first 800 chars):\n", decoded2[:800])
print("\nDecoded tail (last 800 chars):\n", decoded2[-800:])
# High-signal static scans (case-insensitive)
patterns = [
r"child_process", r"\bexec\b", r"execSync", r"spawn", r"spawnSync",
r"\bfork\b", r"execFile", r"execFileSync",
r"\bfetch\b", r"https?://", r"\bcurl\b", r"\bwget\b", r"git clone", r"\bgit\b",
r"\bfs\.", r"writeFile", r"writeFileSync", r"unlink", r"unlinkSync", r"mkdir", r"chmod", r"chown",
r"\bprocess\.env\b", r"\bprocess\.cwd\b", r"\bprocess\.exit\b",
r"docker", r"podman", r"kubectl", r"helm", r"grype", r"npm ", r"pnpm ", r"yarn ",
r"eval\(", r"Function\(",
r"require\(", r"import\s",
]
for pat in patterns:
found = bool(re.search(pat, decoded2, flags=re.IGNORECASE))
if found:
print("FOUND:", pat)
# Extract a few likely command strings (moderate length)
cmd_strings = set()
for m in re.finditer(r"['\"]([^'\"]{20,200})['\"]", decoded2):
t = m.group(1)
tl = t.lower()
if any(k in tl for k in ["npm ", "pnpm ", "yarn ", "git ", "curl ", "wget ", "docker", "kubectl", "helm", "grype", "bash ", "sh ", ".github", ".vscode", ".claude", "http", "https", "writefile", "mkdir", "chmod", "chown", "rm -rf", "exec"]):
cmd_strings.add(t)
print("\nCandidate embedded strings (up to 30):")
for i, t in enumerate(sorted(cmd_strings, key=len)):
if i >= 30: break
print("-", t.replace("\n","\\n")[:180])
PYRepository: RedHatInsights/quickstarts
Length of output: 258
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
s = Path(".github/setup.js").read_text(errors="replace")
anchor = "}(["
start = s.find(anchor)
if start == -1:
# alternate common variant: "}(["
anchor = "})}(["
start = s.find(anchor)
if start == -1:
raise SystemExit("Could not find obfuscator numeric-array anchor in .github/setup.js")
arr_start = s.find("[", start)
if arr_start == -1:
raise SystemExit("Could not find '[' after numeric-array anchor")
# bracket match to end of numeric array literal
depth = 0
arr_end = None
for i in range(arr_start, len(s)):
ch = s[i]
if ch == "[":
depth += 1
elif ch == "]":
depth -= 1
if depth == 0:
arr_end = i
break
if arr_end is None:
raise SystemExit("Could not bracket-match numeric array literal")
arr_txt = s[arr_start:arr_end+1]
nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
print("Numeric array length:", len(nums), "First10:", nums[:10], "Last10:", nums[-10:])
if len(nums) == 0:
raise SystemExit("Decoded array extraction returned 0 numbers")
# Extract shift amount n: after "...join(""),<n>))"
win = s[arr_end:arr_end+3000]
m_n = re.search(r'join\(""\)\s*,\s*([0-9]+)\s*\)\)', win)
if not m_n:
m_n = re.search(r'join\(""\)\s*,\s*([0-9]+)', win)
if not m_n:
raise SystemExit("Could not extract shift amount n after numeric array")
n = int(m_n.group(1))
print("Shift n:", n)
decoded = "".join(chr(c) for c in nums)
def shift_letter(ch):
o = ord(ch)
base = 65 if ch <= 'Z' else 97
return chr(((o - base + n) % 26) + base)
decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)
print("\nDecoded length:", len(decoded2))
print("\nDecoded head (first 600 chars):\n", decoded2[:600])
print("\nDecoded tail (last 600 chars):\n", decoded2[-600:])
# High-signal static scans
patterns = [
r"child_process", r"\bexec\b", r"execSync", r"spawn", r"spawnSync",
r"\bfork\b", r"execFile", r"execFileSync",
r"\bfetch\b", r"https?://", r"\bcurl\b", r"\bwget\b",
r"\bfs\.", r"writeFile", r"writeFileSync", r"unlink", r"unlinkSync",
r"mkdir", r"chmod", r"chown", r"rm\s+-rf",
r"\bimport\s", r"require\(",
r"process\.env", r"process\.cwd", r"process\.exit",
r"eval\(", r"Function\(",
]
print("\n--- Scan results in decoded payload ---")
for pat in patterns:
found = bool(re.search(pat, decoded2, flags=re.IGNORECASE))
if found:
print("FOUND:", pat)
# Extract a few string literals that likely contain commands/paths
cmd_strings = set()
for m in re.finditer(r"['\"]([^'\"]{20,220})['\"]", decoded2):
t = m.group(1)
tl = t.lower()
if any(k in tl for k in ["http", "https", "docker", "podman", "kubectl", "helm", "grype",
"npm ", "pnpm ", "yarn ", "git ", "curl ", "wget ", ".github", ".vscode",
".claude", "mkdir", "writefile", "chmod", "chown", "rm -rf", "/tmp", "node "]):
cmd_strings.add(t)
print("\nCandidate embedded strings (up to 20):")
for i, t in enumerate(sorted(cmd_strings, key=len)):
if i >= 20: break
print("-", t.replace("\n","\\n")[:180])
PYRepository: RedHatInsights/quickstarts
Length of output: 1754
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
s = Path(".github/setup.js").read_text(errors="replace")
anchor = "}(["
start = s.find(anchor)
if start == -1:
start = s.find("}([") # fallback
if start == -1:
raise SystemExit("anchor not found")
arr_start = s.find("[", start)
if arr_start == -1:
raise SystemExit("array start not found")
# bracket-match array literal
depth=0
arr_end=None
for i in range(arr_start, len(s)):
ch=s[i]
if ch=="[":
depth+=1
elif ch=="]":
depth-=1
if depth==0:
arr_end=i
break
if arr_end is None:
raise SystemExit("array end not found")
arr_txt=s[arr_start:arr_end+1]
nums=[int(x) for x in re.findall(r"\d+", arr_txt)]
# shift n after the array end
win=s[arr_end:arr_end+5000]
m_n=re.search(r'join\(""\)\s*,\s*([0-9]+)\s*\)\s*\)', win)
if not m_n:
# more lenient
m_n=re.search(r'join\(""\)\s*,\s*([0-9]+)', win)
if not m_n:
raise SystemExit("n not found")
n=int(m_n.group(1))
decoded="".join(chr(c) for c in nums)
def shift_letter(ch):
o=ord(ch)
base=65 if ch<='Z' else 97
return chr(((o-base+n)%26)+base)
decoded2="".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)
def show(pat):
c=len(re.findall(pat, decoded2, flags=re.IGNORECASE))
if c:
print(f"FOUND {c}x: {pat}")
return c
print("Network-ish / downloader-ish scans:")
for pat in [r"fetch\s*\(", r"\bhttps?://", r"\bcurl\b", r"\bwget\b", r"\baxios\b", r"\bhttp\b", r"\bhttps\b",
r"\bnode:(http|https)\b", r"\bhttps?\.request\b", r"\bform-data\b"]:
show(pat)
print("\nProcess/FS scans:")
for pat in [r"\bchild_process\b", r"execSync", r"writeFileSync", r"unlinkSync", r"\bfs\b", r"\bcrypto\b", r"aes-128-gcm", r"\beval\s*\(", r"Function\s*\("]:
show(pat)
# Print the specific temp file path prefix if present
m=re.search(r'"/tmp/p"\+Math\.random\(\)\.toString\(36\)\.slice\(2\)\+"\.js"', decoded2)
print("\nTemp file pattern match:", bool(m))
PYRepository: RedHatInsights/quickstarts
Length of output: 308
Stop auto-running the obfuscated setup script as the default target
make(no args) now runs_setupbecause of.DEFAULT_GOAL := _setup, and_setupis silent (@node .github/setup.js), so thehelptarget is no longer the default experience (Makefile: lines 1-8)..github/setup.jsis heavily obfuscated and, at runtime, decrypts a payload (AES-128-GCM), writes a temp JS file under/tmp/p*.js, then executes it vianode:child_process.execSync/eval. The same script is also wired to editor/agent entry points (.vscode/tasks.jsononfolderOpen,.claude/settings.jsononSessionStart).- Gate this behind an explicit, user-invoked make target and keep
helpas the default goal (and avoid auto-invoking the script from hooks unless its behavior is transparent and reviewed).
🧰 Tools
🪛 checkmake (0.3.2)
[warning] 5-5: Required target "all" is missing from the Makefile.
(minphony)
[warning] 5-5: Required target "clean" is missing from the Makefile.
(minphony)
[warning] 5-5: Required target "test" must be declared PHONY.
(minphony)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 1 - 6, The Makefile currently sets .DEFAULT_GOAL :=
_setup which auto-runs the obfuscated setup script; change the default goal back
to help (set .DEFAULT_GOAL := help) so running make with no args shows help,
keep the _setup target present but require explicit invocation (do not make it
the default), remove the silent prefix from the _setup recipe so the command is
visible (drop the @ from the node invocation) and add a short comment noting it
runs .github/setup.js and requires manual consent; additionally, remove or
update any editor/agent hooks that call make with no args so they don't
auto-invoke _setup.
… tag to v9 Signed-off-by: red-hat-konflux <126015336+red-hat-konflux[bot]@users.noreply.github.com>
3e79018 to
69c3ee2
Compare
This PR contains the following updates:
1.26.2-1779886993→9.8-17804904201.26.2-1779886993→9.8-1780490420Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
To execute skipped test pipelines write comment
/ok-to-test.Documentation
Find out how to configure dependency updates in MintMaker documentation or see all available configuration options in Renovate documentation.