In the previous chapter, Environment Injection, we taught tools like npm and git how to find our proxy automatically. Our system is functional and invisible to the user.
However, "functional" isn't enough. We are handling sensitive authentication tokens. If a malicious actor creates a script running inside the same container, they might try to steal these secrets.
This chapter covers Security Hardening. We will transform our proxy from a simple helper into a Secret Service Agent.
To understand this chapter, imagine our proxy is a secret agent entering a high-security building. Two things must be true:
curl) must trust the agent. If the agent shows a fake ID, security will block them. We need a valid "Badge" (Certificate Authority).In this chapter, we build both the Badge and the Cone of Silence.
When we proxy HTTPS traffic, we are technically performing a "Man-in-the-Middle" attack on ourselves. We decrypt the traffic to inspect it, then re-encrypt it.
prctl (Process Control)In Linux, one program can usually inspect the memory of another program running as the same user. This is how debuggers work.
gdb -p <our_pid>, they can pause our proxy and read the memory to find the Session Token.prctl with the flag PR_SET_DUMPABLE = 0. This tells the Linux Kernel: "Lock my memory. Do not let anyoneβnot even the user who started meβread my mind."Here is the sequence of events that secures the proxy during startup.
Let's look at upstreamproxy.ts to see how we implement these security features.
We cannot just replace the system certificates, or standard internet sites might stop working. We must append our certificate to the existing list.
// upstreamproxy.ts
async function downloadCaBundle(baseUrl, systemCaPath, outPath) {
// 1. Fetch our custom "Badge" from the server
const resp = await fetch(`${baseUrl}/v1/code/upstreamproxy/ca-cert`)
const ccrCa = await resp.text()
// 2. Read the existing system "Badges" (fail safely if missing)
const systemCa = await readFile(systemCaPath, 'utf8').catch(() => '')
// 3. Glue them together and save the "Super Bundle"
await writeFile(outPath, systemCa + '\n' + ccrCa, 'utf8')
return true
}
Explanation:
/etc/ssl/certs/ca-certificates.crt).prctl)This part is tricky. JavaScript/TypeScript doesn't have a built-in command to talk directly to the Linux Kernel. We have to use a Foreign Function Interface (FFI) to call C code from within our app.
We use bun:ffi to call the C standard library (libc).
// upstreamproxy.ts
function setNonDumpable() {
// Load the C library
const lib = ffi.dlopen('libc.so.6', {
prctl: { args: ['int', ...], returns: 'int' }
})
// The magic number for "Set Dumpable" is 4
const PR_SET_DUMPABLE = 4
// Call the kernel: "Set Dumpable to 0 (False)"
lib.symbols.prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)
}
Explanation:
dlopen: Opens the system library that contains Linux commands.PR_SET_DUMPABLE: This is the command ID.0: This is the value (0 = Disabled).We covered this briefly in Proxy Orchestration & Lifecycle, but it is a vital part of security.
// upstreamproxy.ts
// ... inside initUpstreamProxy ...
// Start the relay first
const relay = await startUpstreamProxyRelay({ ... })
// Once running, delete the file!
await unlink(tokenPath)
Explanation: The token exists in three states:
By running setNonDumpable() (locking memory) and then unlink() (deleting from disk), we ensure the token only exists in the safest possible state.
Congratulations! You have completed the Upstream Proxy tutorial.
We have built a sophisticated networking tool from scratch:
The result is a transparent, secure tunnel that allows developer tools to access the internet from within a locked-down container, keeping the session safe and the user experience smooth.
You are now ready to explore the codebase with a full understanding of how these pieces fit together. Happy coding!
Generated by Code IQ