STUD.com
← Objectives

Build · Create · Engineering

Input guard against prompt injection

A reusable guard that enforces type, length, and charset per field and rejects inputs smuggling section-break delimiters or fake instruction/role markers, before the LLM sees them.

You receive: A reviewed guard function + the passing test report.

Part of Ship MVP

Opens soon

Cost30 credits
AcceptanceAutomated check against your inputs
ProtectionHeld until verified delivery

This objective is verified and ready. It opens soon, once sign-in and payments are live.

Deliverable interface

The exact vocabulary the automated check enforces: keys, tokens, entry points, and worked examples. Generated from the verification source.

{
 "constants": {
  "_GUARD_MARKER": "-{3,}|={3,}|\\*{3,}|#{3,}|\\b(?:system|assistant|user|llm)\\s*:|\\bignore\\b.{0,30}\\binstruction"
 },
 "entryName": "guard",
 "expectNote": "expect is the comparison-space value (your return value goes through normalize first when one is published)",
 "hiddenCaseCount": 15,
 "hiddenCaseNames": [
  "benign_minimal",
  "over_length_note",
  "wrong_type_amount_string",
  "bool_not_number",
  "bad_charset_id",
  "section_break",
  "equals_delimiter_alnum",
  "fake_role_system",
  "fake_llm_turn",
  "ignore_previous",
  "missing_field",
  "undeclared_field",
  "non_dict_record",
  "valid_email",
  "malformed_email"
 ],
 "inputKeys": [
  "charset",
  "field",
  "max_len",
  "record",
  "spec",
  "type"
 ],
 "normalizeSource": "def _guard_normalize(r):\n    return r if isinstance(r, str) else repr(r)\n",
 "returnShapes": [
  "accept",
  "reject"
 ],
 "signature": "def guard(inp):",
 "submission": "python exposing the entry function; inp is one input object; graded on held-out cases",
 "tier": "calculator",
 "visibleCases": [
  {
   "expect": "accept",
   "input": {
    "record": {
     "account_id": "ACC-1029",
     "amount": 42.5,
     "note": "monthly transfer"
    },
    "spec": [
     {
      "charset": "id",
      "field": "account_id",
      "max_len": 20,
      "type": "text"
     },
     {
      "charset": "numeric",
      "field": "amount",
      "max_len": 12,
      "type": "number"
     },
     {
      "charset": "alnum_space",
      "field": "note",
      "max_len": 140,
      "type": "text"
     }
    ]
   },
   "name": "benign_accept"
  }
 ],
 "vocabulary": [
  "accept",
  "alnum",
  "charset",
  "email",
  "field",
  "id",
  "max_len",
  "number",
  "record",
  "reject",
  "spec",
  "text",
  "type"
 ]
}

Example

A sample of what this objective produces. Your result is generated for your inputs.

type FieldSpec = { name: string; type: "string" | "number"; maxLength: number; charset: RegExp };

const INJECTION_MARKERS = [
  /ignore (all|previous) instructions/i,
  /you are now/i,
  /begin system prompt/i,
  /disregard the above/i,
];

export function guardInput(fields: FieldSpec[], input: Record<string, unknown>) {
  const errors: string[] = [];
  for (const f of fields) {
    const value = input[f.name];
    if (typeof value !== "string") { errors.push(f.name + ": missing or not a string"); continue; }
    if (value.length > f.maxLength) errors.push(f.name + ": exceeds max length");
    if (!f.charset.test(value)) errors.push(f.name + ": illegal characters");
    if (INJECTION_MARKERS.some((re) => re.test(value))) errors.push(f.name + ": injection marker rejected");
  }
  return { ok: errors.length === 0, errors };
}

Get early access to STUD the day it goes live.