APIセキュリティ情報セキュリティベストプラクティス
APIセキュリティのベストプラクティス
2025年3月10日
API(Application Programming Interface)の利用が増加する中、セキュリティ対策の重要性がより高まっています。特に法人情報のような機密性の高いデータを扱う場合、適切なセキュリティ対策は必須です。
APIセキュリティの基本概念
主要なセキュリティリスク
API利用において注意すべきリスク:
- 認証・認可の不備
- データの盗聴・改ざん
- 不正アクセスによる情報漏洩
- サービス拒否攻撃(DoS)
- APIキーの漏洩・悪用
セキュリティの三原則
機密性(Confidentiality)
権限のない者による情報の閲覧を防ぐ
完全性(Integrity)
データの改ざんや破損を防ぐ
可用性(Availability)
正当な利用者が必要な時にサービスを利用できる状態を保つ
認証・認可のベストプラクティス
1. APIキー管理
安全なAPIキーの生成
// 推奨:十分な長さのランダムな文字列
const apiKey = generateSecureApiKey(32); // 32文字以上推奨
// 非推奨:予測可能なパターン
const weakApiKey = "company123_api_key"; // 危険
APIキーの保護方法
環境変数での管理
// .env ファイル
ICHISAN_API_KEY=your_secure_api_key_here
// アプリケーションコード
const apiKey = process.env.ICHISAN_API_KEY;
設定ファイルの暗号化
const encryptedConfig = encrypt(config, masterKey);
const decryptedApiKey = decrypt(encryptedConfig.apiKey, masterKey);
2. OAuth 2.0 の活用
トークンベース認証の実装
// アクセストークンの取得
const tokenResponse = await fetch('/oauth/token', {
method: 'POST',
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret
})
});
const { access_token } = await tokenResponse.json();
// APIリクエストでトークンを使用
const apiResponse = await fetch('/api/corporate-info', {
headers: {
'Authorization': `Bearer ${access_token}`
}
});
3. レート制限の実装
適切な制限値の設定
const rateLimiter = {
windowMs: 15 * 60 * 1000, // 15分
maxRequests: 100, // 最大100リクエスト
onLimitReached: (req, res) => {
res.status(429).json({
error: 'Rate limit exceeded',
retryAfter: 900 // 15分後に再試行
});
}
};
通信セキュリティ
1. HTTPS の必須化
TLS 1.2以上の使用
// Node.jsでの実装例
const https = require('https');
const options = {
secureProtocol: 'TLSv1_2_method',
ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
};
2. 証明書の検証
SSL証明書の適切な検証
const axios = require('axios');
const httpsAgent = new https.Agent({
rejectUnauthorized: true, // 証明書検証を有効化
checkServerIdentity: (host, cert) => {
// 追加の証明書検証ロジック
return undefined; // 検証成功
}
});
const response = await axios.get('/api/endpoint', { httpsAgent });
データ保護
1. 機密データの暗号化
保存時の暗号化
const crypto = require('crypto');
function encryptSensitiveData(data, key) {
const cipher = crypto.createCipher('aes-256-cbc', key);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// APIレスポンスの機密部分を暗号化
const encryptedResponse = {
corporateNumber: response.corporateNumber,
name: response.name,
sensitiveInfo: encryptSensitiveData(response.sensitiveInfo, encryptionKey)
};
2. データマスキング
機密情報の部分隠蔽
function maskSensitiveData(data) {
return {
...data,
phone: data.phone.replace(/(\d{3})-(\d{4})-(\d{4})/, '$1-****-$3'),
address: data.address.replace(/\d+番地.*/, '***番地'),
代表者名: data.代表者名.replace(/^(.).*(.{1})$/, '$1***$2')
};
}
アクセス制御
1. 最小権限の原則
必要最小限の権限付与
const permissions = {
基本情報取得: ['corporate_number', 'name', 'address'],
詳細情報取得: ['corporate_number', 'name', 'address', 'capital', 'employees'],
更新権限: ['update_basic_info']
};
function checkPermission(userRole, requestedData) {
const allowedFields = permissions[userRole] || [];
return requestedData.every(field => allowedFields.includes(field));
}
2. IPアドレス制限
許可されたIPからのアクセスのみ受付
const allowedIPs = ['192.168.1.0/24', '203.0.113.10'];
function isAllowedIP(clientIP) {
return allowedIPs.some(range => isIPInRange(clientIP, range));
}
app.use((req, res, next) => {
if (!isAllowedIP(req.ip)) {
return res.status(403).json({ error: 'Access denied' });
}
next();
});
ログ記録と監視
1. セキュリティログの記録
重要なイベントの記録
const securityLogger = {
logAuthAttempt: (success, userIP, timestamp) => {
console.log(JSON.stringify({
event: 'auth_attempt',
success,
userIP,
timestamp,
severity: success ? 'info' : 'warning'
}));
},
logAPIAccess: (endpoint, userID, timestamp, responseCode) => {
console.log(JSON.stringify({
event: 'api_access',
endpoint,
userID,
timestamp,
responseCode,
severity: responseCode >= 400 ? 'error' : 'info'
}));
}
};
2. 異常検知
不審なアクセスパターンの検出
class AnomalyDetector {
constructor() {
this.accessPatterns = new Map();
}
checkAnomaly(userID, endpoint, timestamp) {
const key = `${userID}:${endpoint}`;
const pattern = this.accessPatterns.get(key) || { count: 0, lastAccess: 0 };
const timeDiff = timestamp - pattern.lastAccess;
// 短時間に大量のリクエスト
if (timeDiff < 1000 && pattern.count > 10) {
this.alertSecurityTeam('Potential DoS attack', { userID, endpoint });
return true;
}
this.accessPatterns.set(key, {
count: pattern.count + 1,
lastAccess: timestamp
});
return false;
}
}
インシデント対応
1. セキュリティインシデントの対応手順
初期対応
- 検知: セキュリティアラートの確認
- 分析: インシデントの詳細調査
- 対応: 必要な措置の実施
- 復旧: サービスの正常化
- 改善: 再発防止策の実装
対応チームの連絡先
const incidentResponse = {
securityTeam: 'security@company.com',
escalationLevel1: 'manager@company.com',
escalationLevel2: 'ciso@company.com',
notifyIncident: function(severity, details) {
const contacts = this.getContactsBySeverity(severity);
contacts.forEach(contact => {
this.sendAlert(contact, details);
});
}
};
2. APIキー漏洩時の対処
緊急時の手順
async function handleApiKeyCompromise(compromisedKey) {
// 1. 該当キーの無効化
await revokeApiKey(compromisedKey);
// 2. 新しいキーの発行
const newApiKey = await generateNewApiKey();
// 3. 関係者への通知
await notifyKeyRotation(compromisedKey, newApiKey);
// 4. アクセスログの確認
const suspiciousAccess = await auditAccessLogs(compromisedKey);
return {
newApiKey,
suspiciousAccess
};
}
イチサンAPIのセキュリティ機能
標準装備のセキュリティ対策
- TLS 1.3 対応: 最新の暗号化プロトコル
- OAuth 2.0 認証: 業界標準の認証方式
- レート制限: DDoS攻撃の防止
- アクセスログ: 詳細な利用履歴の記録
- IP制限: 指定されたIPアドレスからのみアクセス許可
追加セキュリティオプション
- エンドツーエンド暗号化: データの完全保護
- デジタル署名: データの完全性保証
- 多要素認証: より強固な認証
- リアルタイム監視: 24時間体制の監視
まとめ
APIセキュリティは、技術的対策だけでなく、運用プロセスや組織体制の整備も重要です。定期的なセキュリティ監査と継続的な改善により、安全なAPI利用環境を維持できます。
イチサンでは、セキュリティを最優先に考えたAPIサービスを提供しています。セキュリティに関するご相談も承っておりますので、お問い合わせからお気軽にご連絡ください。