Add redaction module: JFR in-process data redaction (JEP 536) on JDK 27
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CifR2BE7PBvRy5hT8TS9oz
This commit is contained in:
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared helpers. Source this; do not run it.
|
||||
#
|
||||
# run_case <jdk-home> <recording.jfr> <extra JVM flags...>
|
||||
# Runs the Workload with the SAME planted secrets every time, under a clean
|
||||
# environment (env -i), so only the fake secrets below can ever end up in a
|
||||
# recording. Your real shell environment is never passed through.
|
||||
HERE="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
BUILD="$HERE/build"
|
||||
|
||||
# The planted secrets. Each one has a name that tells you where it hides.
|
||||
SECRETS=(LEAK-ENV-TOKEN-1 LEAK-PROP-PASSWORD-2 LEAK-ARG-DBPASSWORD-3 LEAK-URL-PW-4
|
||||
LEAK-ENV-CONN-5 LEAK-PROP-DBPASS-6 LEAK-ARG-DBPASS-7)
|
||||
|
||||
compile() { # <jdk-home>
|
||||
mkdir -p "$BUILD"
|
||||
"$1/bin/javac" --release 21 -d "$BUILD" "$HERE/src/Workload.java" "$HERE/src/Scan.java" 2>&1 | grep -v '^Picked up' || true
|
||||
}
|
||||
|
||||
run_jvm() { # <jdk-home> [flags...] (no recording flag: caller decides)
|
||||
local jdk="$1"; shift
|
||||
env -i PATH=/usr/bin:/bin HOME=/nonexistent \
|
||||
ACCESS_TOKEN=LEAK-ENV-TOKEN-1 DB_CONN=LEAK-ENV-CONN-5 DEPLOY_REGION=eu-west-1 \
|
||||
"$jdk/bin/java" "$@" \
|
||||
-Xmx256m \
|
||||
-Djavax.net.ssl.keyStorePassword=LEAK-PROP-PASSWORD-2 \
|
||||
-Ddb-pass=LEAK-PROP-DBPASS-6 \
|
||||
-Dapp.region=mumbai \
|
||||
-cp "$BUILD" Workload \
|
||||
--dbpassword LEAK-ARG-DBPASSWORD-3 \
|
||||
--db-pass LEAK-ARG-DBPASS-7 \
|
||||
https://john:[email protected]/login \
|
||||
--verbose
|
||||
}
|
||||
|
||||
run_case() { # <jdk-home> <jfr-out> [flags...] (recording from JVM start)
|
||||
local jdk="$1" out="$2"; shift 2
|
||||
run_jvm "$jdk" -XX:StartFlightRecording:filename="$out" "$@"
|
||||
}
|
||||
|
||||
scan() { "$1/bin/java" -cp "$BUILD" Scan "$2" "${SECRETS[@]}" 2>&1 | grep -v '^Picked up'; }
|
||||
|
||||
print_events() { # <jdk-home> <jfr>
|
||||
"$1/bin/jfr" print --events InitialSystemProperty,JVMInformation,InitialEnvironmentVariable "$2" 2>&1 | grep -v '^Picked up'
|
||||
}
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerates every file under redaction/output/.
|
||||
# Usage: JDK27=/path/to/jdk-27 JDK25=/path/to/jdk-25 redaction/scripts/run-all.sh
|
||||
# Each case plants the same seven fake secrets (see common.sh), records, then
|
||||
# greps the recording for them. Recordings go to a scratch dir, not the repo.
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/common.sh"
|
||||
: "${JDK27:?set JDK27 to a JDK 27 home}" "${JDK25:?set JDK25 to a JDK 25 home}"
|
||||
OUT="$HERE/output"; TMP=/tmp/jfr-redaction; rm -rf "$TMP"; mkdir -p "$OUT" "$TMP"
|
||||
cd "$HERE"
|
||||
unset JAVA_TOOL_OPTIONS # keep proxy banners out of committed output
|
||||
compile "$JDK27"
|
||||
vers() { "$1/bin/java" -version 2>&1 | grep -v '^Picked up'; }
|
||||
hdr() { echo "### $*"; }
|
||||
|
||||
{ hdr "JDK 25: no redaction exists. What is in the recording?"
|
||||
vers "$JDK25"
|
||||
run_case "$JDK25" "$TMP/jdk25.jfr" >/dev/null
|
||||
scan "$JDK25" "$TMP/jdk25.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
echo; hdr "jfr print"; print_events "$JDK25" "$TMP/jdk25.jfr"
|
||||
} > "$OUT/01-jdk25-leak.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27 with NO redaction flags at all"
|
||||
vers "$JDK27"
|
||||
run_case "$JDK27" "$TMP/default.jfr" >/dev/null
|
||||
scan "$JDK27" "$TMP/default.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
echo; hdr "jfr print"; print_events "$JDK27" "$TMP/default.jfr"
|
||||
} > "$OUT/02-jdk27-defaults.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27 with redact-argument=none,redact-key=none (the opt-out)"
|
||||
run_case "$JDK27" "$TMP/none.jfr" -XX:FlightRecorderOptions:redact-argument=none,redact-key=none >/dev/null
|
||||
scan "$JDK27" "$TMP/none.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
} > "$OUT/03-jdk27-opt-out.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27, first attempt: conn* and a +prefix"
|
||||
F="-XX:FlightRecorderOptions:redact-key=+db-pass;conn*,redact-argument=+--db-pass *;https://*:*@*"
|
||||
echo "flags: $F"
|
||||
run_case "$JDK27" "$TMP/wrongglob.jfr" "$F" >/dev/null
|
||||
scan "$JDK27" "$TMP/wrongglob.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
echo; hdr "jfr print (JVMInformation and the DB_CONN variable)"
|
||||
print_events "$JDK27" "$TMP/wrongglob.jfr" | awk '/jdk.JVMInformation/,/^}/ {print} /key = "DB_CONN"/ {print; getline; print}'
|
||||
hdr "fixed: *conn* instead of conn*"
|
||||
F="-XX:FlightRecorderOptions:redact-key=+db-pass;*conn*,redact-argument=+--db-pass *;https://*:*@*"
|
||||
echo "flags: $F"
|
||||
run_case "$JDK27" "$TMP/fixed.jfr" "$F" >/dev/null
|
||||
scan "$JDK27" "$TMP/fixed.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
echo; hdr "jfr print (JVMInformation)"
|
||||
print_events "$JDK27" "$TMP/fixed.jfr" | awk '/jdk.JVMInformation/,/^}/ {print}'
|
||||
} > "$OUT/04-jdk27-custom-inline.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27, filters loaded from files with @, plus -Xlog:jfr+redact=debug"
|
||||
echo "keys.txt:"; sed 's/^/ /' "$HERE/filters/keys.txt"
|
||||
echo "args.txt:"; sed 's/^/ /' "$HERE/filters/args.txt"
|
||||
echo
|
||||
F="-XX:FlightRecorderOptions:redact-key=+@$HERE/filters/keys.txt,redact-argument=+@$HERE/filters/args.txt"
|
||||
run_case "$JDK27" "$TMP/files.jfr" "$F" -Xlog:jfr+redact=debug 2>&1 \
|
||||
| grep -E 'jfr,redact' | sed "s#$HERE#<module>#g"
|
||||
echo; scan "$JDK27" "$TMP/files.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
} > "$OUT/05-jdk27-filter-files-and-debug-log.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27, a filter file that does not exist"
|
||||
env -i PATH=/usr/bin:/bin "$JDK27/bin/java" -XX:FlightRecorderOptions:redact-key=@/no/such/keys.txt -version 2>&1 | grep -v '^Picked up'
|
||||
echo "exit=${PIPESTATUS[0]}"
|
||||
} > "$OUT/06-jdk27-missing-filter-file.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27, redact-key=db-pass WITHOUT the + prefix replaces the defaults"
|
||||
run_case "$JDK27" "$TMP/noplus.jfr" -XX:FlightRecorderOptions:redact-key=db-pass 2>&1 | grep -E 'jfr,redact'
|
||||
scan "$JDK27" "$TMP/noplus.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
} > "$OUT/07-jdk27-no-plus-replaces-defaults.txt" 2>&1
|
||||
|
||||
{ hdr "JDK 27, recording started later with jcmd JFR.start (JVM launched without any JFR flag)"
|
||||
run_jvm "$JDK27" -Dworkload.sleep.ms=8000 >/dev/null &
|
||||
sleep 2
|
||||
PID=$(pgrep -f 'Workload' | head -1)
|
||||
"$JDK27/bin/jcmd" "$PID" JFR.start name=late filename="$TMP/late.jfr" 2>&1 | grep -v '^Picked up' | sed "s#$TMP#<tmp>#g"
|
||||
sleep 1
|
||||
"$JDK27/bin/jcmd" "$PID" JFR.stop name=late 2>&1 | grep -v '^Picked up' | sed "s#$TMP#<tmp>#g"
|
||||
wait
|
||||
scan "$JDK27" "$TMP/late.jfr"; echo "exit=${PIPESTATUS[0]}"
|
||||
} > "$OUT/08-jdk27-jcmd-late-recording.txt" 2>&1
|
||||
|
||||
echo "regenerated:"; ls -1 "$OUT"
|
||||
Reference in New Issue
Block a user