Skip to content
Skillpedia
Misc35k · #6209

securing-historian-server-in-ot-environment

Audits and secures historian servers in industrial (OT) environments. Ensures integrity and secure access to process data.

What it does

This tool checks the security of industrial historical data servers (like OSIsoft PI, Honeywell PHD, GE Proficy, AVEVA Historian) in production environments. It verifies if network, access, and data protection settings are secure.

When to use it

  • ✓When setting up a new historian server for the first time.
  • ✓When reviewing the security of an existing historian server.
  • ✓When planning how to securely send data from the factory floor to the IT network.

Example of what to ask your AI

“Check the security of my OSIsoft PI historian server at address 192.168.1.100.”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/securing-historian-server-in-ot-environment/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/securing-historian-server-in-ot-environment/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

The tool connects to the server to check open ports and common security settings. It identifies risks like unnecessary exposed services or lack of encryption.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill securing-historian-server-in-ot-environment

Or download just the file:

curl -L https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/main/skills/securing-historian-server-in-ot-environment/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Securing Historian Server in OT Environment

When to Use

  • When deploying a new historian server in an OT environment and configuring it securely from the start
  • When hardening an existing historian after a security assessment identified it as a high-risk target
  • When designing historian data replication architecture through a DMZ for IT access to process data
  • When implementing access controls to prevent unauthorized modification of historical process data
  • When investigating suspected historian compromise or data integrity issues

Do not use for IT-only database security without OT data (see general database hardening), for real-time SCADA data transmission security (see detecting-attacks-on-scada-systems), or for historian selection and sizing decisions.

Prerequisites

  • Historian platform (OSIsoft PI, Honeywell PHD, GE Proficy, AVEVA Historian) installed and operational
  • Network segmentation with historian placed in Level 3 (Site Operations) per Purdue Model
  • Understanding of data flows: field devices -> PLCs -> OPC servers -> historian
  • Access to historian administration credentials
  • DMZ infrastructure for IT-facing data replication

Workflow

Step 1: Audit Current Historian Security Configuration

Evaluate the current security posture of the historian server including network exposure, authentication, and access controls.

#!/usr/bin/env python3
"""Historian Security Audit Tool.

Evaluates the security configuration of process historian servers
including network exposure, authentication, access controls,
and data integrity protections.
"""

import json
import socket
import ssl
import subprocess
import sys
from dataclasses import dataclass, field, asdict
from datetime import datetime


@dataclass
class AuditFinding:
    finding_id: str
    severity: str
    category: str
    title: str
    detail: str
    remediation: str


class HistorianSecurityAudit:
    """Security audit for OT historian servers."""

    def __init__(self, historian_ip, historian_type="PI"):
        self.ip = historian_ip
        self.type = historian_type
        self.findings = []
        self.counter = 1

    def check_network_exposure(self):
        """Check which network services are exposed by the historian."""
        print(f"[*] Checking network exposure: {self.ip}")

        # Common historian ports
        ports_to_check = {
            5450: ("PI Data Archive", "PI SDK/API connections"),
            5457: ("PI AF Server", "PI Asset Framework"),
            5459: ("PI Notifications", "PI Notification Service"),
            443: ("HTTPS", "PI Vision / Web API"),
            80: ("HTTP", "Unsecured web interface"),
            1433: ("MS SQL Server", "Direct database access"),
            5432: ("PostgreSQL", "Direct database access"),
            3389: ("RDP", "Remote Desktop"),
            135: ("RPC", "Windows RPC"),
            445: ("SMB", "Windows File Sharing"),
            8080: ("HTTP Alt", "Alternative web interface"),
        }

        exposed = []
        for port, (service, desc) in ports_to_check.items():
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(3)
                result = sock.connect_ex((self.ip, port))
                sock.close()
                if result == 0:
                    exposed.append({"port": port, "service": service, "description": desc})
            except Exception:
                pass

        # Flag unnecessary exposed services
        for svc in exposed:
            if svc["port"] in (80, 135, 445, 3389):
                self.findings.append(AuditFinding(
                    finding_id=f"HIST-{self.counter:03d}",
                    severity="high",
                    category="Network Exposure",
                    title=f"Unnecessary service exposed: {svc['service']} (port {svc['port']})",
                    detail=f"Port {svc['port']} ({svc['description']}) is accessible on historian",
                    remediation=f"Disable {svc['service']} or restrict via host firewall",
                ))
                self.counter += 1

        if any(s["port"] == 80 for s in exposed):
            self.findings.append(AuditFinding(
                finding_id=f"HIST-{self.counter:03d}",
                severity="high",
                category="Encryption",
                title="Historian web interface on unencrypted HTTP",

…
FAQ

What is an 'OT environment'?

OT stands for 'Operational Technology'. These are the systems that control industrial equipment and processes, such as factories and power plants.

What is the 'Purdue Model'?

It's a model that divides the industrial network into levels, from the factory floor up to the IT network, to organize and secure systems.

What is a 'DMZ'?

A DMZ (Demilitarized Zone) is an intermediate network area that protects the internal network (OT) from external access (IT), allowing controlled communication.

Details

Original description by the author

Audits and hardens process historian servers (OSIsoft PI, Honeywell PHD, GE Proficy, AVEVA Historian) in OT environments: Purdue-level network placement, interface access control, secure DMZ replication via data diodes or PI-to-PI connectors, SQL injection prevention, and process data integrity. Use when auditing or hardening a historian server, or designing secure OT-to-IT data replication throug

repo: mukul975/Anthropic-Cybersecurity-Skills

Popularity

GitHub stars
35k
Ranking position
#6209
License
Apache-2.0
Updated
8/31/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills