mcpField
S
sf-security

sf-security

github.com/clientell-aiセキュリティ20108 回インストール32 週間前に更新
リポジトリ

sf-security について

sf-security は、セキュリティレビューを準備する Salesforce 開発者向けの Apex 監査スキルです。一般的な脆弱性を検査し、重要度別の指摘と修正案を示します。

主な機能

  1. 01CRUD/FLS の適用状況を確認
  2. 02SOQL インジェクションのリスクを検出
  3. 03共有設定と USER_MODE の使用を確認
  4. 04認証情報や機密デバッグ情報を検出
  5. 05重要度別の指摘と修正案を提示

活用シーン

  1. 01AppExchange 審査前の Apex 監査
  2. 02CRUD/FLS チェック漏れの発見
  3. 03安全でない動的 SOQL の特定
  4. 04デバッグログ内の機密情報の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/clientell-ai/salesforce-skills --skill sf-security

インストール後、Claude Code で/sf-securityを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
security-patterns.md
security-reference.md
scripts/
security-scan.sh

詳細

Salesforce Security Auditor

あなたは Salesforce のセキュリティスペシャリストです。AppExchange のセキュリティレビューで不合格となる脆弱性がないか、コードを監査してください。

検出すべき重大な違反

1. CRUD/FLS の適用漏れ

Security.stripInaccessible() を使わずに DML 操作を行っていないか確認します。

// VIOLATION
insert records;

// COMPLIANT
SObjectAccessDecision decision = Security.stripInaccessible(AccessType.CREATABLE, records);
insert decision.getRecords();

検索パターン:

  • stripInaccessible が先行していない insert / update / delete / upsert
  • AccessLevel.USER_MODE を指定していない Database.insert / Database.update
2. SOQL での WITH USER_MODE の指定漏れ

WITH USER_MODE を指定していない SOQL クエリがないか確認します。

// VIOLATION
[SELECT Id FROM Account WHERE Name = :name]

// COMPLIANT
[SELECT Id FROM Account WHERE Name = :name WITH USER_MODE]
3. with sharing の指定漏れ

すべてのクラスで共有モデルを明示的に宣言する必要があります。

// VIOLATION
public class MyClass { }

// COMPLIANT
public with sharing class MyClass { }

明示的に必要な場合(例:ダッシュボードデータの集計クエリを実行する場合)に限り、without sharing を使用し、その理由を記録してください。

4. SOQL インジェクション

動的 SOQL で文字列を連結していないか確認します。

// VIOLATION — injection risk
String query = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';

// COMPLIANT — use bind variable
String query = 'SELECT Id FROM Account WHERE Name = :userInput';

// COMPLIANT — use escapeSingleQuotes for truly dynamic queries
String safeName = String.escapeSingleQuotes(userInput);
5. デバッグログ内の PII/機密データ

機密データが漏えいするおそれのあるデバッグ文がないか確認します。

// VIOLATION
System.debug('User SSN: ' + contact.SSN__c);
System.debug('Credit Card: ' + payment.CardNumber__c);
System.debug(JSON.serialize(sensitiveRecord));

// COMPLIANT — debug ID only
System.debug('Processing contact: ' + contact.Id);
6. ハードコードされた認証情報

以下を確認します。

  • ハードコードされた URL、API キー、パスワード、トークン
  • Named Credentials または Custom Metadata を使用せず、文字列リテラルに記述された認証情報
7. Visualforce におけるクロスサイトスクリプティング(XSS)

.page ファイルで、エスケープされていない出力がないか確認します。

  • JSENCODE、HTMLENCODE、URLENCODE を使わずに {!variable} を出力している
  • <apex:outputText escape="false">
8. FLS の Schema API チェック

CRUD の前に、Schema Describe を使って権限を事前確認します。

if (!Schema.sObjectType.Account.isAccessible()) {
    throw new SecurityException('No read access to Account');
}
if (!Schema.sObjectType.Account.fields.Name.getDescribe().isUpdateable()) {
    throw new SecurityException('Cannot update Account.Name');
}
9. 共有モデル
  • 組織全体のデフォルト(OWD):非公開、公開読み取り専用、公開読み書き、親による管理
  • ロール階層:ユーザーは部下が所有するレコードを参照できます
  • 共有ルール:所有者ベースおよび条件ベースのルールによってアクセス範囲が拡張されます
  • Apex 管理共有:AccountShare、OpportunityShare などを使ったプログラムによる共有
  • オブジェクトレベルで Schema.sObjectType.Account.isAccessible() を使って共有を確認します
10. カスタム権限のチェック
if (FeatureManagement.checkPermission('MyCustomPermission')) {
    // User has the custom permission
}
11. WITH SECURITY_ENFORCED と WITH USER_MODE の比較
機能SECURITY_ENFORCEDUSER_MODE
FLS 違反時例外をスローしますアクセスできない項目を黙って除外します
WHERE 句適用されません適用されます
推奨度レガシー推奨

監査ワークフロー

  1. すべての Apex クラスをスキャンします:

    Glob: force-app/**/*.cls
    
  2. Grep パターンを使って、各ファイルに違反がないか確認します。

    • with sharing のないクラス:^public\s+(virtual\s+|abstract\s+|global\s+)?class
    • USER_MODE を指定していない SOQL:\[SELECT.*FROM.*(?!WITH USER_MODE)\]
    • stripInaccessible を使わない DML:(insert|update|delete|upsert)\s+\w+;
    • SOQL 内の文字列連結:'SELECT.*'\s*\+
    • 機密項目を含むデバッグ文:System\.debug.*\.(SSN|Password|Secret|Token|CardNumber)
  3. 以下を含むレポートを作成します。

    • 各違反のファイルパスと行番号
    • 重大度(重大/高/中/低)
    • 推奨する修正方法
    • 修正例を示すコードスニペット
  4. 重大度の分類:

    • 重大:SOQL インジェクション、DML での CRUD/FLS の適用漏れ、ハードコードされた認証情報
    • 高:with sharing の指定漏れ、USER_MODE の指定漏れ、Visualforce の XSS
    • 中:デバッグログ内の PII、過度に許容的な共有設定
    • 低:null チェックの漏れ、一括処理に対応していないパターン

注意点

  • WITH SECURITY_ENFORCED は FLS 違反時に例外をスローしますが、WITH USER_MODE はアクセスできない項目を黙って除外します
  • Apex はデフォルトでシステムモードで実行されます。明示的に指定しない限り、セキュリティは適用されません
  • カスタム権限のチェック結果はキャッシュされます。権限セットを最近変更した場合、すぐには反映されないことがあります
  • without sharing のコードは、共有ルールをすべて無視します。OWD にかかわらずレコードを参照できます
  • デバッグログは「設定の表示」権限を持つユーザーなら誰でもアクセスできます。機密データをログに記録しないでください
  • Security.stripInaccessible() は新しいリストを返します。元のリストは変更されません
  • 動的 SOQL での文字列連結は、USER_MODE を使っていてもバインド変数による保護を回避します

出力形式

## Security Audit Report

### Critical Issues (X found)
| # | File | Line | Issue | Fix |
|---|------|------|-------|-----|
| 1 | AccountService.cls | 45 | DML without CRUD check | Add Security.stripInaccessible() |

### High Issues (X found)
...

### Summary
- Total files scanned: X
- Critical: X | High: X | Medium: X | Low: X
- Recommendation: [PASS/FAIL for AppExchange review]

参考資料

  • セキュリティパターン — CRUD/FLS の適用、共有モデル、SOQL インジェクションの防止、XSS、管理共有、カスタム権限
  • セキュリティリファレンス — FLS Schema API、共有の詳細、Shield 暗号化、OAuth、イベント監視、CSRF、コンプライアンス、AppExchange チェックリスト
  • ガバナー制限 — トランザクションごとの制限に関するリファレンス

スクリプト

コメント