Files
compliance-scanner-agent/docs/guide/plc.md
T
sharang c6a84b327f
CI / Check (push) Waiting to run
CI / Detect Changes (push) Waiting to run
CI / Deploy Agent (push) Blocked by required conditions
CI / Deploy Dashboard (push) Blocked by required conditions
CI / Deploy Docs (push) Blocked by required conditions
CI / Deploy MCP (push) Blocked by required conditions
docs(plc): soft-PLC architecture + CODESYS/Yocto lifecycle diagram (#184)
2026-07-16 22:00:17 +00:00

7.6 KiB

PLC / SPS Projects (CODESYS)

Certifai analyzes industrial control logic (IEC 61131-3) for PLC/SPS targets such as CODESYS projects. A single PLC/SPS target is treated as a composite device: the control application and the device it runs on.

What you provide What Certifai does
PLC project (PLCopen XML / ST, or a .projectarchive) Control-logic SAST — semantic security rules over ST and graphical FBD/LD
A .projectarchive Control-app SBOM — the referenced CODESYS libraries + the runtime version, matched against known CVEs
A device firmware image Firmware SBOM / CVE (opt-in)
A reachable endpoint (WebVisu, OPC UA) DAST / pentest (opt-in)

Anatomy: a soft PLC is a SoC + Linux + runtime

A CODESYS controller is not a monolithic appliance like a classic Siemens S7. It is PC-based ("soft") control — commodity silicon running a general-purpose Linux, with a software PLC runtime as just another process:

Classic PLC (e.g. Siemens S7) Soft PLC (CODESYS-on-Yocto, OpenPLC-on-Raspbian)
Proprietary hardware + firmware Commodity SoC (x86 / ARM)
Proprietary OS General-purpose Linux (a Yocto image, or Raspbian)
Proprietary runtime Software runtime (CODESYS Control, or OpenPLC)
STEP7 / TIA project IEC 61131-3 control app (ST / LD / FBD / SFC)

Because of this, the device is built along two independent tracks, by different people, on different timelines, and shipped separately. It also inherits the entire Linux / IT attack surface on top of the OT / control one — which is exactly why a PLC/SPS target is treated as a composite: Certifai ingests one artifact per layer and scans each with the right pipeline.

flowchart TB
    subgraph TA["Track A · Device platform — built by the hardware OEM / vendor"]
        direction LR
        A1["Yocto / OpenEmbedded<br/>BSP + RT kernel"] --> A2["Bake in the CODESYS<br/>Control for Linux runtime"] --> A3["bitbake → device image<br/>.wic / .tar + manifest"]
    end
    subgraph TB2["Track B · Control application — built by the machine builder / customer"]
        direction LR
        B1["CODESYS IDE<br/>ST / LD / FBD / SFC + WebVisu"] --> B2["Reference CODESYS +<br/>vendor libraries"] --> B3["Compile → download<br/>to device (gateway 11740)"]
    end

    A3 --> DEV(["Running soft-PLC device<br/>SoC + Linux + runtime + control app<br/>Modbus · OPC UA · EtherNet/IP · WebVisu"])
    B3 --> DEV

    subgraph CERT["What Certifai scans — one layer per artifact"]
        direction LR
        S1["Firmware layer<br/>FirmwareStatic · SBOM · CVE"]
        S2["Control-logic layer<br/>PLC SAST — ST + FBD/LD"]
        S3["Control-app SBOM<br/>libraries + runtime → CVE"]
        S4["Running layer<br/>ICS probe · DAST (WebVisu)"]
    end

    A3 -. firmware image .-> S1
    B1 -. PLCopen XML / ST via git .-> S2
    B2 -. projectarchive (zip) .-> S3
    DEV -. live URL / provisioned .-> S4

    classDef yocto fill:#fde68a,stroke:#b45309,color:#111
    classDef codesys fill:#bfdbfe,stroke:#1d4ed8,color:#111
    classDef dev fill:#e9d5ff,stroke:#7e22ce,color:#111
    classDef cert fill:#bbf7d0,stroke:#15803d,color:#111
    class A1,A2,A3 yocto
    class B1,B2,B3 codesys
    class DEV dev
    class S1,S2,S3,S4 cert

::: tip Where Yocto fits Yocto is Track A — the build system for the device platform. It produces the Linux image and bakes in the CODESYS runtime, so it is the firmware layer, entirely separate from the control application. Hand it to Certifai as its own firmware image artifact (scanned by the firmware pipeline, not the PLC pipeline). The device OS need not be Yocto — Raspbian/Debian/Buildroot, or even an RTOS / bare-metal, are all possible — but Yocto is the common, product-grade industrial choice. :::

Two ways to deliver the project

You can either upload the project when onboarding, or point Certifai at a git repository (recommended — every scan is just a git pull, no re-upload).

Option A — Upload

On the onboarding wizard, choose target type PLC / SPS, then attach a PLC project artifact and pick its format:

  • PLCopen XML (.xml) — export from CODESYS via Project → Export PLCopenXML.
  • Structured Text (.st) — a raw ST file.
  • Project archive (.projectarchive) — File → Project Archive → Save/Send Archive… with "Referenced libraries" ticked. This is the only form that also yields the library + runtime SBOM.

Attach a Git repository artifact to the PLC/SPS target. Certifai clones it and runs the control-logic scan over the exported source in the repo.

Best-case git repository layout

Because the binary .project does not diff or merge in git, commit textual exports for review-friendly SAST, and include the .projectarchive so the library/runtime SBOM is available too:

my-plc-project/
├── src/
│   ├── PLC_PRG.xml          # PLCopen XML export (ST or FBD/LD) — one per POU
│   ├── PumpController.xml
│   ├── SafetyInterlock.xml
│   └── GVL.xml              # global variable lists, also as PLCopen XML
├── PumpStation.projectarchive   # optional but recommended → library + runtime SBOM
└── README.md

Guidelines

  • Export to PLCopen XML (Project → Export PLCopenXML), one file per POU, and commit those. ST, and graphical FBD/LD, are both analyzed.
  • Alternatively commit raw .st / .exp / .scl files — also analyzed.
  • Do not commit only the binary .project — it cannot be parsed (and does not diff). If you want the library SBOM, commit the .projectarchive as well.
  • CODESYS's built-in Git integration, which stores an exported representation, works too — as long as the committed form is PLCopen XML / textual.

::: tip What unlocks what

  • Control-logic SAST needs textual source in the repo (PLCopen XML or .st).
  • Library + runtime SBOM needs a .projectarchive — PLCopen XML exports do not carry the referenced libraries. :::

What the scanner finds

The control-logic rules are CWE-mapped and include: hardcoded credentials (CWE-798), default/weak passwords (CWE-1393), safety interlock / watchdog bypass (CWE-1384), unchecked array indexing (CWE-129), division-by-zero (CWE-369, guard-aware), cleartext/insecure communication (CWE-319), insecure protocol ports (CWE-319, e.g. Modbus 502, FTP 21, Telnet 23), and unstructured jumps (CWE-691).

The SBOM view lists the CODESYS libraries (pkg:codesys/<name>@<version>) and the runtime; matching runtime components (e.g. the Cmp* / 3SLicense libraries) surface real CODESYS advisories as CVE alerts.

Dynamic testing — ICS protocol probe

Beyond the static analysis, Certifai can probe the running device over industrial protocols. Attach a Live URL artifact (the device host / WebVisu URL) to the PLC/SPS target and enable the ICS Probe scan.

The probe is read-only — it never writes to the live process. It currently speaks Modbus/TCP (port 502): it confirms whether the device answers unauthenticated Modbus requests and reads its device identity (vendor / product / revision). Because Modbus/TCP has no authentication or encryption in the protocol, a reachable endpoint that answers is reported as an exposed control interface (CWE-306). OPC UA and EtherNet/IP probes are planned.

::: warning The ICS probe connects to the live device. It is opt-in (off by default) and should only be run against targets you are authorized to test. It performs reads only, never writes. :::