# 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. ```mermaid flowchart TB subgraph TA["Track A · Device platform — built by the hardware OEM / vendor"] direction LR A1["Yocto / OpenEmbedded
BSP + RT kernel"] --> A2["Bake in the CODESYS
Control for Linux runtime"] --> A3["bitbake → device image
.wic / .tar + manifest"] end subgraph TB2["Track B · Control application — built by the machine builder / customer"] direction LR B1["CODESYS IDE
ST / LD / FBD / SFC + WebVisu"] --> B2["Reference CODESYS +
vendor libraries"] --> B3["Compile → download
to device (gateway 11740)"] end A3 --> DEV(["Running soft-PLC device
SoC + Linux + runtime + control app
Modbus · OPC UA · EtherNet/IP · WebVisu"]) B3 --> DEV subgraph CERT["What Certifai scans — one layer per artifact"] direction LR S1["Firmware layer
FirmwareStatic · SBOM · CVE"] S2["Control-logic layer
PLC SAST — ST + FBD/LD"] S3["Control-app SBOM
libraries + runtime → CVE"] S4["Running layer
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**. ### Option B — Git repository (recommended) 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: ```text 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/@`) 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. :::