Skills Plugins MCP Prompt Model 博客 我的中心

perl-security

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

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-ja-jp-skills-perl-security-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name perl-security description テイントモード、入力バリデーション、安全なプロセス実行、DBIパラメータ化クエリ、Webセキュリティ(XSS/SQLi/CSRF)、perlcriticセキュリティポリシーを網羅する包括的なPerlセキュリティ。 origin ECC 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::Temp ( tempfile(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' ); }); 出力エンコード
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。