(* * Demo PLC program — pump-station control (IEC 61131-3 Structured Text). * * Deliberately vulnerable, for the compliance-scanner PLC control-logic demo. * Each issue below is flagged by pipeline::plc::rules. *) FUNCTION_BLOCK PumpStationCtrl VAR_INPUT OperatorCmd : INT; (* HMI command index — untrusted *) FlowSetpoint : REAL; END_VAR VAR_OUTPUT PumpSpeed : REAL; Fault : BOOL; END_VAR VAR HmiPassword : STRING := 'admin123'; (* hardcoded + default credential *) ApiKey : STRING := 'sk_live_9c1f2a'; (* hardcoded secret *) PumpProfiles : ARRAY[0..7] OF REAL; Safety_Enable : BOOL := TRUE; Watchdog_Kick : INT := 1; MeasuredFlow : REAL; ScaleFactor : REAL; i : INT; END_VAR (* Operator can index the profile table with an unvalidated command. *) PumpSpeed := PumpProfiles[OperatorCmd]; (* Divisor is a live process value that can read zero on a stopped line. *) ScaleFactor := FlowSetpoint / MeasuredFlow; (* Safety interlock disabled straight from application logic. *) IF OperatorCmd = 99 THEN Safety_Enable := FALSE; Watchdog_Kick := 0; END_IF; (* Unauthenticated Modbus/TCP link on the cleartext OT port. *) Modbus_TCP_Connect(IP := '10.10.5.20', PORT := 502, AUTH := FALSE, PASSWORD := 'plc'); (* Unstructured jump around the fault handler. *) IF MeasuredFlow > 1000.0 THEN JMP trip; END_IF; (* A correctly guarded division — must NOT be flagged. *) IF ScaleFactor <> 0.0 THEN PumpSpeed := PumpSpeed / ScaleFactor; END_IF; RETURN; trip: Fault := TRUE; PumpSpeed := 0.0; END_FUNCTION_BLOCK