affaan-m/ECC

perl-security

テイントモード、入力バリデーション、安全なプロセス実行、DBIパラメータ化クエリ、Webセキュリティ(XSS/SQLi/CSRF)、perlcriticセキュリティポリシーを網羅する包括的なPerlセキュリティ。

82Collecting
See how to use itView GitHub source
npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-security"
Automated source guide

Source checked Jul 28, 2026·Refresh due Oct 26, 2026

Reorganized from the pinned upstream SKILL.md

Turn perl-security's source instructions into a guide you can follow

According to the pinned SKILL.md from affaan-m/ECC: 入力バリデーション、インジェクション防止、セキュアコーディングプラクティスを網羅するPerlアプリケーションの包括的なセキュリティガイドライン。

npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-security"
Check the pinned source

Best fit

  • テイントモード、入力バリデーション、安全なプロセス実行、DBIパラメータ化クエリ、Webセキュリティ(XSS/SQLi/CSRF)、perlcriticセキュリティポリシーを網羅する包括的なPerlセキュリティ。

Bring this context

  • A concrete task that matches the documented purpose of perl-security.
  • The files, examples, or context the task depends on.
  • Your constraints, target environment, and definition of done.

Expected outputs

  • A result that follows the pinned perl-security instructions.
  • A concise record of assumptions, inputs used, and unresolved questions.
  • A final check against the source workflow and relevant permission signals.

Key source sections

Read perl-security through these 5 source sections

Sections are extracted automatically from the pinned SKILL.md and link back to the source.

01

アクティベートするタイミング

Perlアプリケーションでユーザー入力を処理するとき

SKILL.md · アクティベートするタイミング
Perlアプリケーションでユーザー入力を処理するときPerlのWebアプリケーション(CGI、Mojolicious、Dancer2、Catalyst)を構築するときセキュリティ脆弱性についてPerlコードをレビューするとき
02

仕組み

テイント対応の入力境界から始め、次に外側に移動する: 入力をバリデートしてアンテイントし、ファイルシステムとプロセス実行を制約内に保ち、どこでもパラメータ化されたDBIクエリを使用する。以下の例は、ユーザー入力、シェル、またはネットワークに触れるPerlコードをリリースする前に適用することが期待されるデフォルトを示す。

SKILL.md · 仕組み
テイント対応の入力境界から始め、次に外側に移動する: 入力をバリデートしてアンテイントし、ファイルシステムとプロセス実行を制約内に保ち、どこでもパラメータ化されたDBIクエリを使用する。以下の例は、ユーザー入力、シェル、またはネットワークに触れるPerlコードをリリースする前に適用することが期待されるデフォルトを示す。
03

テイントモード

Perlのテイントモード(-T)は外部ソースからのデータを追跡し、明示的なバリデーションなしに安全でない操作で使用されることを防ぐ。

SKILL.md · テイントモード
Perlのテイントモード(-T)は外部ソースからのデータを追跡し、明示的なバリデーションなしに安全でない操作で使用されることを防ぐ。perl !/usr/bin/perl -T use v5.36;
05

テイントされた: プログラム外からのもの

my $input = $ARGV[0]; テイントされた my $envpath = $ENV{PATH}; テイントされた my $form = ; テイントされた my $query = $ENV{QUERYSTRING}; テイントされた

SKILL.md · テイントされた: プログラム外からのもの
my $input = $ARGV[0]; テイントされた my $envpath = $ENV{PATH}; テイントされた my $form = ; テイントされた my $query = $ENV{QUERYSTRING}; テイントされた

SkillSignal prompt templates

Provide the task, context, and acceptance criteria

These prompts were written by SkillSignal from the source structure; they are not upstream text.

Task-start prompt

Confirm source fit, inputs, and outputs before acting.

Use perl-security to help me with: [specific task]. Context: [files, data, or background]. Constraints: [environment, scope, and prohibited actions]. Before acting, check the pinned SKILL.md and explain which sections apply, what inputs are still missing, and what you will deliver.

Source-guided execution

Make the Agent explicitly follow the key extracted sections.

Apply the pinned perl-security source to [task]. Pay particular attention to these source sections: “アクティベートするタイミング”, “仕組み”, “テイントモード”, “テイントモードの有効化”, “テイントされた: プログラム外からのもの”. Preserve the important decision at each step. Mark facts not covered by the source as “needs confirmation” instead of inventing them. Then verify the result against my acceptance criteria: [criteria].

Result-review prompt

Check omissions, permissions, and source drift before delivery.

Review the current perl-security result: (1) does it satisfy the original task; (2) were any applicable steps or limits in the pinned SKILL.md missed; (3) did it perform any unauthorized file, command, network, or data action; and (4) which conclusions remain unverified? List issues first, then fix only what the source or user authorization supports.

Output checklist

Verify each item before delivery

The task matches the purpose documented in the SKILL.md.

The source section “アクティベートするタイミング” has been checked.

The source section “仕組み” has been checked.

The source section “テイントモード” has been checked.

The source section “テイントモードの有効化” has been checked.

Inputs, constraints, and acceptance criteria are explicit.

Unverified facts, compatibility, and outcome claims are clearly marked.

Any file, command, network, or data action has been reviewed.

Choose a different workflow

When another Skill is the better fit

FAQ

What does perl-security do?

入力バリデーション、インジェクション防止、セキュアコーディングプラクティスを網羅するPerlアプリケーションの包括的なセキュリティガイドライン。

How do I start using perl-security?

The catalog detected this source-specific install command: npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-security". Inspect the command and pinned source before running it.

Which Agent platforms does it declare?

No dedicated Agent platform is declared in the pinned source record.

Repository stars
234,327
Repository forks
35,711
Quality
82/100
Source repository last pushed

Quality breakdown

Based on traceable docs and repository signals; stars are not treated as quality.

82/100
Documentation29/30
Specificity11/25
Maintenance20/20
Trust signals22/25

Compare before choosing

Related Agent Skills and source variants

These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.

perl-security by affaan-m

Comprehensive Perl security covering taint mode, input validation, safe process execution, DBI parameterized queries, web security (XSS/SQLi/CSRF), and perlcritic security policies.

perl-security by affaan-m

全面的Perl安全指南,涵盖污染模式、输入验证、安全进程执行、DBI参数化查询、Web安全(XSS/SQLi/CSRF)以及perlcritic安全策略。

dask by k-dense-ai

Distributed computing for larger-than-RAM pandas/NumPy workflows. Use when you need to scale existing pandas/NumPy code beyond memory or across clusters. Best for parallel file processing, distributed ML, integration with existing pandas code. For out-of-core analytics on single machine use vaex; for in-memory speed use polars.

imaging-data-commons by k-dense-ai

Query and download public cancer imaging data from NCI Imaging Data Commons using idc-index. Use for accessing large-scale radiology (CT, MR, PET) and pathology datasets for AI training or research. No authentication required. Query by metadata, visualize in browser, check licenses.

geofeed-tuner by github

Use this skill whenever the user mentions IP geolocation feeds, RFC 8805, geofeeds, or wants help creating, tuning, validating, or publishing a self-published IP geolocation feed in CSV format. Intended user audience is a network operator, ISP, mobile carrier, cloud provider, hosting company, IXP, or satellite provider asking about IP geolocation accuracy, or geofeed authoring best practices. Helps create, refine, and improve CSV-format IP geolocation feeds with opinionated recommendations beyon

View original Skill.mdThis page is parsed directly from the repository SKILL.md without editorial rewriting. Collected: Jul 28, 2026 · about 1 min

Perlセキュリティパターン

入力バリデーション、インジェクション防止、セキュアコーディングプラクティスを網羅するPerlアプリケーションの包括的なセキュリティガイドライン。

アクティベートするタイミング

  • Perlアプリケーションでユーザー入力を処理するとき
  • PerlのWebアプリケーション(CGI、Mojolicious、Dancer2、Catalyst)を構築するとき
  • セキュリティ脆弱性についてPerlコードをレビューするとき
  • ユーザー指定パスでファイル操作を実行するとき
  • PerlからシステムコマンドをExecuteするとき
  • DBIデータベースクエリを書くとき

仕組み

テイント対応の入力境界から始め、次に外側に移動する: 入力をバリデートしてアンテイントし、ファイルシステムとプロセス実行を制約内に保ち、どこでもパラメータ化されたDBIクエリを使用する。以下の例は、ユーザー入力、シェル、またはネットワークに触れるPerlコードをリリースする前に適用することが期待されるデフォルトを示す。

テイントモード

Perlのテイントモード(-T)は外部ソースからのデータを追跡し、明示的なバリデーションなしに安全でない操作で使用されることを防ぐ。

テイントモードの有効化

#!/usr/bin/perl -T
use v5.36;

# テイントされた: プログラム外からのもの
my $input    = $ARGV[0];        # テイントされた
my $env_path = $ENV{PATH};      # テイントされた
my $form     = <STDIN>;         # テイントされた
my $query    = $ENV{QUERY_STRING}; # テイントされた

# PATHを早期にサニタイズ(テイントモードで必要)
$ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

アンテイントパターン

use v5.36;

# Good: 特定の正規表現でバリデートしてアンテイント
sub untaint_username($input) {
    if ($input =~ /^([a-zA-Z0-9_]{3,30})$/) {
        return $1;  # $1はアンテイントされている
    }
    die "Invalid username: must be 3-30 alphanumeric characters\n";
}

# Good: ファイルパスをバリデートしてアンテイント
sub untaint_filename($input) {
    if ($input =~ m{^([a-zA-Z0-9._-]+)$}) {
        return $1;
    }
    die "Invalid filename: contains unsafe characters\n";
}

# Bad: 過度に許可的なアンテイント(目的を無効化する)
sub bad_untaint($input) {
    $input =~ /^(.*)$/s;
    return $1;  # 何でも受け入れる — 無意味
}

入力バリデーション

ブロックリストよりアローリスト

use v5.36;

# Good: アローリスト — 許可されるものを正確に定義
sub validate_sort_field($field) {
    my %allowed = map { $_ => 1 } qw(name email created_at updated_at);
    die "Invalid sort field: $field\n" unless $allowed{$field};
    return $field;
}

# Good: 特定のパターンでバリデート
sub validate_email($email) {
    if ($email =~ /^([a-zA-Z0-9._%+-]+\@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/) {
        return $1;
    }
    die "Invalid email address\n";
}

sub validate_integer($input) {
    if ($input =~ /^(-?\d{1,10})$/) {
        return $1 + 0;  # 数値に強制変換
    }
    die "Invalid integer\n";
}

# Bad: ブロックリスト — 常に不完全
sub bad_validate($input) {
    die "Invalid" if $input =~ /[<>"';&|]/;  # エンコードされた攻撃を見逃す
    return $input;
}

長さ制約

use v5.36;

sub validate_comment($text) {
    die "Comment is required\n"        unless length($text) > 0;
    die "Comment exceeds 10000 chars\n" if length($text) > 10_000;
    return $text;
}

安全な正規表現

ReDoS防止

壊滅的なバックトラッキングは重複するパターンにネストされた量詞が使用されるときに発生する。

use v5.36;

# Bad: ReDoSに脆弱(指数的バックトラッキング)
my $bad_re = qr/^(a+)+$/;           # ネストされた量詞
my $bad_re2 = qr/^([a-zA-Z]+)*$/;   # クラスにネストされた量詞
my $bad_re3 = qr/^(.*?,){10,}$/;    # 繰り返される貪欲/怠惰な組み合わせ

# Good: ネストなしで書き直す
my $good_re = qr/^a+$/;             # 単一の量詞
my $good_re2 = qr/^[a-zA-Z]+$/;     # クラスに単一の量詞

# Good: バックトラッキングを防ぐためにpossessive量詞またはアトミックグループを使用
my $safe_re = qr/^[a-zA-Z]++$/;             # Possessive (5.10+)
my $safe_re2 = qr/^(?>a+)$/;                # アトミックグループ

# Good: 信頼されていないパターンにタイムアウトを適用
use POSIX qw(alarm);
sub safe_match($string, $pattern, $timeout = 2) {
    my $matched;
    eval {
        local $SIG{ALRM} = sub { die "Regex timeout\n" };
        alarm($timeout);
        $matched = $string =~ $pattern;
        alarm(0);
    };
    alarm(0);
    die $@ if $@;
    return $matched;
}

安全なファイル操作

3引数open

use v5.36;

# Good: 3引数open、レキシカルファイルハンドル、戻り値チェック
sub read_file($path) {
    open my $fh, '<:encoding(UTF-8)', $path
        or die "Cannot open '$path': $!\n";
    local $/;
    my $content = <$fh>;
    close $fh;
    return $content;
}

# Bad: ユーザーデータを使った2引数open(コマンドインジェクション)
sub bad_read($path) {
    open my $fh, $path;        # $pathが"|rm -rf /"なら、コマンドを実行!
    open my $fh, "< $path";   # シェルメタキャラクターインジェクション
}

TOCTOU防止とパストラバーサル

use v5.36;
use Fcntl qw(:DEFAULT :flock);
use File::Spec;
use Cwd qw(realpath);

# アトミックファイル作成
sub create_file_safe($path) {
    sysopen(my $fh, $path, O_WRONLY | O_CREAT | O_EXCL, 0600)
        or die "Cannot create '$path': $!\n";
    return $fh;
}

# パスが許可されたディレクトリ内に留まることをバリデート
sub safe_path($base_dir, $user_path) {
    my $real = realpath(File::Spec->catfile($base_dir, $user_path))
        // die "Path does not exist\n";
    my $base_real = realpath($base_dir)
        // die "Base dir does not exist\n";
    die "Path traversal blocked\n" unless $real =~ /^\Q$base_real\E(?:\/|\z)/;
    return $real;
}

一時ファイルにはFile::Temptempfile(UNLINK => 1))を使用し、レースコンディションを防ぐためにflock(LOCK_EX)を使用する。

安全なプロセス実行

リスト形式のsystemとexec

use v5.36;

# Good: リスト形式 — シェル補間なし
sub run_command(@cmd) {
    system(@cmd) == 0
        or die "Command failed: @cmd\n";
}

run_command('grep', '-r', $user_pattern, '/var/log/app/');

# Good: IPC::Run3で安全に出力をキャプチャ
use IPC::Run3;
sub capture_output(@cmd) {
    my ($stdout, $stderr);
    run3(\@cmd, \undef, \$stdout, \$stderr);
    if ($?) {
        die "Command failed (exit $?): $stderr\n";
    }
    return $stdout;
}

# Bad: 文字列形式 — シェルインジェクション!
sub bad_search($pattern) {
    system("grep -r '$pattern' /var/log/app/");  # $patternが"'; rm -rf / #"なら
}

# Bad: 補間のあるバッククォート
my $output = `ls $user_dir`;   # シェルインジェクションリスク

外部コマンドからstdout/stderrを安全にキャプチャするためにはCapture::Tinyも使用する。

SQLインジェクション防止

DBIプレースホルダー

use v5.36;
use DBI;

my $dbh = DBI->connect($dsn, $user, $pass, {
    RaiseError => 1,
    PrintError => 0,
    AutoCommit => 1,
});

# Good: パラメータ化クエリ — 常にプレースホルダーを使用
sub find_user($dbh, $email) {
    my $sth = $dbh->prepare('SELECT * FROM users WHERE email = ?');
    $sth->execute($email);
    return $sth->fetchrow_hashref;
}

sub search_users($dbh, $name, $status) {
    my $sth = $dbh->prepare(
        'SELECT * FROM users WHERE name LIKE ? AND status = ? ORDER BY name'
    );
    $sth->execute("%$name%", $status);
    return $sth->fetchall_arrayref({});
}

# Bad: SQLでの文字列補間(SQLi脆弱性!)
sub bad_find($dbh, $email) {
    my $sth = $dbh->prepare("SELECT * FROM users WHERE email = '$email'");
    # $emailが"' OR 1=1 --"なら、すべてのユーザーが返される
    $sth->execute;
    return $sth->fetchrow_hashref;
}

動的カラムアローリスト

use v5.36;

# Good: アローリストに対してカラム名をバリデート
sub order_by($dbh, $column, $direction) {
    my %allowed_cols = map { $_ => 1 } qw(name email created_at);
    my %allowed_dirs = map { $_ => 1 } qw(ASC DESC);

    die "Invalid column: $column\n"    unless $allowed_cols{$column};
    die "Invalid direction: $direction\n" unless $allowed_dirs{uc $direction};

    my $sth = $dbh->prepare("SELECT * FROM users ORDER BY $column $direction");
    $sth->execute;
    return $sth->fetchall_arrayref({});
}

# Bad: ユーザー選択カラムを直接補間
sub bad_order($dbh, $column) {
    $dbh->prepare("SELECT * FROM users ORDER BY $column");  # SQLi!
}

DBIx::Class(ORM安全性)

use v5.36;

# DBIx::Classは安全なパラメータ化クエリを生成する
my @users = $schema->resultset('User')->search({
    status => 'active',
    email  => { -like => '%@example.com' },
}, {
    order_by => { -asc => 'name' },
    rows     => 50,
});

Webセキュリティ

XSS防止

use v5.36;
use HTML::Entities qw(encode_entities);
use URI::Escape qw(uri_escape_utf8);

# Good: HTMLコンテキスト用に出力をエンコード
sub safe_html($user_input) {
    return encode_entities($user_input);
}

# Good: URLコンテキスト用にエンコード
sub safe_url_param($value) {
    return uri_escape_utf8($value);
}

# Good: JSONコンテキスト用にエンコード
use JSON::MaybeXS qw(encode_json);
sub safe_json($data) {
    return encode_json($data);  # エスケープを処理
}

# テンプレートの自動エスケープ(Mojolicious)
# <%= $user_input %>   — 自動エスケープ(安全)
# <%== $raw_html %>    — 生の出力(危険、信頼されたコンテンツのみ)

# テンプレートの自動エスケープ(Template Toolkit)
# [% user_input | html %]  — 明示的なHTMLエンコード

# Bad: HTMLの生の出力
sub bad_html($input) {
    print "<div>$input</div>";  # $inputが<script>を含む場合XSS
}

CSRF保護

use v5.36;
use Crypt::URandom qw(urandom);
use MIME::Base64 qw(encode_base64url);

sub generate_csrf_token() {
    return encode_base64url(urandom(32));
}

トークンを検証するときは定数時間比較を使用する。ほとんどのWebフレームワーク(Mojolicious、Dancer2、Catalyst)には組み込みのCSRF保護がある — 手作りのソリューションよりそれらを優先する。

セッションとヘッダーセキュリティ

use v5.36;

# Mojolicousセッション + ヘッダー
$app->secrets(['long-random-secret-rotated-regularly']);
$app->sessions->secure(1);          # HTTPSのみ
$app->sessions->samesite('Lax');

$app->hook(after_dispatch => sub ($c) {
    $c->res->headers->header('X-Content-Type-Options' => 'nosniff');
    $c->res->headers->header('X-Frame-Options'        => 'DENY');
    $c->res->headers->header('Content-Security-Policy' => "default-src 'self'");
    $c->res->headers->header('Strict-Transport-Security' => 'max-age=31536000; includeSubDomains');
});

出力エンコード

常に出力をそのコンテキスト用にエンコードする: HTML用にはHTML::Entities::encode_entities()、URL用にはURI::Escape::uri_escape_utf8()、JSON用にはJSON::MaybeXS::encode_json()

CPANモジュールセキュリティ

  • cpanfileでバージョンをピン留め: requires 'DBI', '== 1.643';
  • メンテナンスされたモジュールを優先: MetaCPANで最近のリリースを確認
  • 依存関係を最小化: 各依存関係は攻撃面積

セキュリティツーリング

perlcriticセキュリティポリシー

# .perlcriticrc — セキュリティ重視の設定
severity = 3
theme = security + core

# 3引数openを要求
[InputOutput::RequireThreeArgOpen]
severity = 5

# チェックされたシステムコールを要求
[InputOutput::RequireCheckedSyscalls]
functions = :builtins
severity = 4

# 文字列evalを禁止
[BuiltinFunctions::ProhibitStringyEval]
severity = 5

# バッククォート演算子を禁止
[InputOutput::ProhibitBacktickOperators]
severity = 4

# CGIでテイントチェックを要求
[Modules::RequireTaintChecking]
severity = 5

# 2引数openを禁止
[InputOutput::ProhibitTwoArgOpen]
severity = 5

# 裸のファイルハンドルを禁止
[InputOutput::ProhibitBarewordFileHandles]
severity = 5

perlcriticの実行

# ファイルをチェック
perlcritic --severity 3 --theme security lib/MyApp/Handler.pm

# プロジェクト全体をチェック
perlcritic --severity 3 --theme security lib/

# CI統合
perlcritic --severity 4 --theme security --quiet lib/ || exit 1

クイックセキュリティチェックリスト

チェック確認事項
テイントモードCGI/Webスクリプトの-Tフラグ
入力バリデーションアローリストパターン、長さ制限
ファイル操作3引数open、パストラバーサルチェック
プロセス実行リスト形式のsystem、シェル補間なし
SQLクエリDBIプレースホルダー、補間しない
HTML出力encode_entities()、テンプレート自動エスケープ
CSRFトークン生成され、状態変更リクエストで検証される
セッション設定Secure、HttpOnly、SameSiteクッキー
HTTPヘッダーCSP、X-Frame-Options、HSTS
依存関係ピン留めされたバージョン、監査されたモジュール
正規表現の安全性ネストされた量詞なし、アンカーされたパターン
エラーメッセージスタックトレースやパスがユーザーに漏れない

アンチパターン

# 1. ユーザーデータを使った2引数open(コマンドインジェクション)
open my $fh, $user_input;               # CRITICAL脆弱性

# 2. 文字列形式のsystem(シェルインジェクション)
system("convert $user_file output.png"); # CRITICAL脆弱性

# 3. SQL文字列補間
$dbh->do("DELETE FROM users WHERE id = $id");  # SQLi

# 4. ユーザー入力でのeval(コードインジェクション)
eval $user_code;                         # リモートコード実行

# 5. サニタイズせずに$ENVを信頼する
my $path = $ENV{UPLOAD_DIR};             # 操作される可能性がある
system("ls $path");                      # 二重脆弱性

# 6. バリデーションなしにテイントを無効化
($input) = $input =~ /(.*)/s;           # 怠惰なアンテイント — 目的を無効化

# 7. HTMLでの生のユーザーデータ
print "<div>Welcome, $username!</div>";  # XSS

# 8. 未バリデートのリダイレクト
print $cgi->redirect($user_url);         # オープンリダイレクト

忘れないこと: Perlの柔軟性は強力だが規律が必要。Webに面したコードにはテイントモードを使用し、アローリストですべての入力をバリデートし、すべてのクエリにDBIプレースホルダーを使用し、すべての出力をそのコンテキスト用にエンコードする。多層防御 — 単一の層に依存しない。

Source repo
affaan-m/ECC
Skill path
docs/ja-JP/skills/perl-security/SKILL.md
Commit SHA
4e973d3eaf92
Repository license
MIT
Data collected