Tiny Cubes and the CNC Injection Vulnerability: A Cautionary Tale in KCL Design

Jessie Frazelle

Jessie Frazelle

You know what's the absolute worst? Surprises. Especially when they're tiny cubes multiplying silently in your CAD models, like some evil nano-scale gremlins. But hey, that's what we inadvertently almost allowed in our KCL library design. Enter the "CNC Injection Vulnerability"—a term we1 proudly coined after discovering the absolute horror of what might happen if we didn't design our library system correctly.

How the Heck Did We Get Here?

It started innocently enough:

// coolshape.kcl
cube(size=10)

export fn foo() {
  // some totally innocent function
}

Then in another file:

import { foo } from "coolshape.kcl"
// Do something with foo

The burning question: does the cube render or nah?2

Lee was open to allowing immediate rendering upon import, whereas Jon strongly preferred zero rendering without explicit calls—wanting clear separation and purity. I was in agreement with Lee, it should render.

In a moment of levity, I joked, "Lee's going to make the library that just adds infinitely tiny cubes to the background of models unseen by the naked eye but when they go to send to manufacturers they are like wtf are these small ass cubes."

So What's the Problem?

Turns out, allowing stuff to execute at import time is like inviting chaos to your party. Imagine writing a harmless-looking library, which secretly populates anyone who imports its beautiful models with millions of microscopic cubes. Your engineer friends try to manufacture the thing, and suddenly:

Your model            CNC Machine
+-------------+      +----------------+
| tiny cube   |----> | WTF is this?   |
| infestation |      | A billion cubes|
+-------------+      +----------------+

Now you're angry and rage emailing us and we are drowning in support tickets asking why tiny invisible cubes are appearing everywhere. Congrats, you've created the left-pad of CAD.

Enter: CNC Injection Vulnerability

We dubbed this "CNC Injection Vulnerability" because it felt exactly like a "command injection" but for CNC machines:

User imports innocent_lib.kcl
    |
    +--> Library silently injects 10,000 cubes
            |
            +--> User sends to CNC
                    |
                    +--> Manufacturer: "bruh, WTF?"

Not cool. In fact, very evil.

Our Grand Solution: Pure Libraries

Inspired by Go's philosophy of avoiding hidden side effects (because seriously, hidden side effects are the devil's playground), we decided on pure libraries:

  • Zero rendering or execution at import time.
  • You explicitly invoke rendering. If you don't call it, it doesn’t happen.

This avoids sneaky surprises and keeps your libraries pure and beautiful—no gremlin cubes allowed.

Now, of course, you can still have a library thats says a function does one thing and it does another. But at least you are explicitly calling said function.

We are thinking about ways to catch at runtime if a function is doing something unexpected. But that is a future problem. In any language you want to make sure that libraries you import are doing what you expect.

But Jess, What About Tiny Cubes?

Don't worry. For history's sake (and because evil is sometimes fun), we're immortalizing this chaos in our infamous Tiny Cubes Library:3

// tinycubes.kcl

// This gives the cubes maximum amount of chance to
// be free and have a long life
fn random(i) {
  x = 0.123456789
  return reduce([1..i], x, fn(i, acc) {
    r = 3.9999
    return r * acc * (1 - acc)
  })
}

fn liberateTheCubes() {
  return reduce([1..20], 1, fn(i, result_so_far) {
      center = [i % 100 + (random(i + 1) * 100), i / 100 + (random(i) * 100)]
      size = 0.01
      startSketchOn(XY)
          |> startProfileAt([center[0] - size, center[1] - size], %)
          |> line(endAbsolute = [center[0] + size, center[1] - size])
          |> line(endAbsolute = [center[0] + size, center[1] + size])
          |> line(endAbsolute = [center[0] - size, center[1] + size])
          |> close()
          |> extrude(length = size) 
      return result_so_far + 1
  })
}

// Get to work gang
liberateTheCubes()

// no export, purely evil intentions

Imagine the user warning:

⚠️ WARNING: Importing 'tinycubes.kcl' injects 100,000 microscopic cubes into your model. Proceed at your own peril.

Final Words

At the end of the day, our goal is clarity and safety (and to avoid waking up to a tsunami of support tickets). So, say goodbye to CNC Injection Vulnerabilities, and hello to a sane, secure KCL library system. But hey, at least we got a sweet blog post out of it.

You’re welcome,

Jess, Jon, Lee, and the Tiny Cubes Liberation Front4

Footnotes

  1. Jon dubbed the term officially.

  2. This was at 10PM on a Friday night mind you.

  3. If you run this code it will be indistingishable from dirt on your screen. Lee wrote it, we all knew he had it in him.

  4. TINY CUBES, MORTY! They're everywhere, Morty! Invisible, insidious, multiplying in the background! You think you're safe, Morty? You're not! It's a cube apocalypse, Morty! Tiny cubes—burp—taking over your precious CAD models!