skip to content

Holding It in Memory

Reading a credential once at start against re-reading it when it changes, and keeping it out of argument lists, crash dumps and child processes. Asked because processes outlive their credentials.

on this pageshow

questions

4

A batch job is launched with its database password as a command-line argument — who on that host can read it?

level: juniorimportance: must knowfreq 60%

answer

  1. not private process memory
  2. the host publishes it
  3. any local account can list it
  4. copies outlive the run
  5. pass a path, not the value

basics

~20 s

Any local account that can list processes, because the argument list is host-visible bookkeeping rather than private process memory. Copies also survive the run, in whatever records program executions and in the job definition that issued the line.

solid answer

~50 s

A process's arguments are not part of its private memory. The system records the command line as part of the process's own bookkeeping, and on most general-purpose systems any local account that can list processes can read it — including processes it does not own, under common default configurations. So a second service, a helper beside the workload, or anyone with a shell on that host can read the password for as long as the job runs. Worse, the copy outlives the run: hosts that record executions record the arguments too, and the scheduler entry or wrapper that issued the line holds the value permanently. The fix is to pass a **reference** rather than the value — a path the program opens, a handle it reads, or the name of an entry it resolves for itself.

go deeper

for a junior

Recall the one fact: arguments are visible to anything that can list processes on that host, while private memory is not. Passing a path or a name instead of the value is the standard fix.

for a middle

Explain why the argument list is a different surface from memory, and name the copies that outlive the run — the execution record and the job definition that issued the line.

for a senior

Show you would audit what starts things on a host, not just the application code, and say what you do when a program accepts a credential only as a flag: narrow scope, short life, recorded decision.

for a principal

Frame it as a platform standard rather than a review comment — how jobs receive credentials across the estate, and what it costs to make reference-passing the only supported shape.

## What the argument list actually is When a process starts, the system records the program name and the arguments it was given. That record is part of the process's bookkeeping, not part of its private address space, and that distinction is the whole answer. Private memory is protected: another account cannot read a running process's heap without privilege it usually does not have. The argument list is not protected in the same way. On most general-purpose systems, reading the arguments of a running process is what an ordinary process listing does, and on common default configurations that listing includes processes belonging to other users. Some systems can be configured to hide other users' processes; that is a hardening option, not the state you should assume. A credential passed as an argument has therefore been copied out of the process's private space into a place the host publishes. ## Where the copies live | copy | who can read it | how long it lasts | |---|---|---| | the process's private memory | the process itself, and anything privileged enough to inspect it | the life of the process | | the argument list | typically any local account that can list processes | the life of the process | | an execution record, where the host keeps one | whoever reads those records | as long as that record is retained | | the job definition or wrapper that issued the line | whoever can read that definition | until someone edits it | The first row is the one people picture; the other three are what the question is really about. Note that only the first is memory. The rest are on-host artefacts that exist because of **how the value was passed**, not because of what the program did with it afterwards. ## Who reads it in practice - **Another local account.** A second service, a helper process beside the workload, a build agent, a person with a shell. None of them need privilege — only the ability to list processes. - **Whatever watches processes for a living.** Inventory and monitoring agents commonly record running command lines, and those recordings travel off the host. - **Execution records.** Where a host records every program that ran, the recorded line carries the arguments, and it survives the process by whatever the retention is. - **The thing that started the job.** A scheduler entry, a job template or a wrapper script usually stores the exact command it issues, which means the credential is also sitting wherever that definition is stored and version-controlled. ## "It only runs for two seconds" This is the most common wrong defence, and it inverts which copy matters. The run is the *shortest-lived* copy of the four. Anything polling the process table catches it while it runs; the execution record and the job definition are permanent by comparison and need no timing at all. A short run shrinks the window on exactly one of the copies and leaves the others untouched. The second wrong defence is obfuscation: encoding the value, splitting it across two arguments, quoting it. Arguments are recorded exactly as passed. Encoding is not secrecy — the reader sees precisely what the program will see, and decodes it the same way the program does. ## What to pass instead 1. **Pass a reference, not the value.** A path the program opens, or the name of the entry it resolves against the store itself. A path in the argument list discloses *where*, not *what*, and that is usually not sensitive. 2. **Feed it on standard input**, where the program accepts that. What is written to a pipe is not published as the process's bookkeeping. 3. **Wrap the program**, but only in a way that actually removes the value — a wrapper that resolves the credential and then passes it as a flag has moved the copy, not removed it, and the process listing is identical. 4. **If the program genuinely accepts a credential only as a flag**, treat that credential as host-visible and change what it is worth: scope it to exactly what the job does and keep its life short, so the value someone reads is narrow and expires. You are now relying on blast radius instead of secrecy, and that should be a recorded decision. ## What an interviewer is listening for "It shows up in a process listing" is the answer. "And in whatever records executions, and in the job definition that holds the line" is the answer that matters operationally, because the process listing disappears when the job ends and the other two do not. The weak answers have a recognisable shape: they treat the argument list as if it were memory, they treat encoding as protection, or they treat a short run as a short exposure.

  • The program takes the credential only as a flag and cannot read a file. What do you do?
    Accept that the value is host-visible and shrink what it is worth: scope that credential to exactly what the job does, keep its life short, and make sure its use is recorded so misuse is visible. You are trading secrecy for blast radius, which is a legitimate trade as long as it is a written decision rather than an accident nobody noticed.
  • Does moving the credential into a wrapper script instead of the scheduler entry help?
    Only if the wrapper stops the value reaching the child's argument list. A wrapper that resolves the value and then passes it as a flag has relocated one copy and produced an identical process listing. A wrapper that writes the value to a file the program opens, or feeds it on standard input, does remove it from the listing.

saying these in an interview costs you the question

  • Thinks only a privileged account can read another process's arguments
  • Says encoding or quoting the value hides it from a process listing
  • Believes the only copy disappears when the job exits
  • Treats a two-second run as too short to be an exposure
  • Forgets the scheduler entry or wrapper that stores the command line
  • Assumes an internal host makes a readable credential acceptable
open as a page

A worker reads its credential from the secret store once at start-up and never again — what does replacing that value then require?

level: middleimportance: must knowfreq 56%

basics

~20 s

A restart, unless something inside the worker re-resolves the value and rebuilds every client constructed from it. Writing a new value into the store changes nothing inside a process that already holds a copy, and the old value must stay accepted until the last holder has moved.

open as a page

A message consumer that read its broker password six weeks ago still runs a day after that password was replaced — why?

level: seniorimportance: should knowfreq 47%

basics

~20 s

The password was checked when the connection was opened, and an established channel is not re-checked per message. The consumer still holds the six-week-old copy in memory, so it fails only at its next reconnect — which may be days after the change.

open as a page

A service composes its database password into one connection string at start-up — what does that composite cost at replacement time?

level: middleimportance: nice to knowfreq 26%

basics

~20 s

Replacement becomes a rebuild rather than an assignment: the string is fixed at the moment it is composed, and every pool, client and retry path constructed from it holds its own copy of the old password until each one is remade.

open as a page