This guide provides comprehensive security best practices for using QuorumProof, including common attack vectors, mitigation strategies, and code examples.
Description: Attackers attempt to create fake credentials or modify existing ones.
Attack Scenarios:
- Issuing credentials without proper authorization
- Modifying credential metadata after issuance
- Creating credentials with false information
Mitigation Strategies:
- Verify issuer identity before accepting credentials
- Implement multi-signature requirements for critical operations
- Use cryptographic proofs to ensure credential integrity
- Maintain audit logs of all credential operations
Code Example:
// Verify credential issuer
pub fn verify_credential_issuer(
credential_id: u64,
expected_issuer: &Address,
) -> Result<bool, Error> {
let credential = get_credential(credential_id)?;
// Verify issuer matches expected value
if credential.issuer != *expected_issuer {
return Err(Error::IssuerMismatch);
}
// Verify credential signature
verify_credential_signature(&credential)?;
Ok(true)
}
// Implement multi-signature for credential issuance
pub fn issue_credential_multisig(
subject: &Address,
credential_type: u32,
metadata_hash: &BytesN<32>,
signers: &Vec<Address>,
threshold: u32,
) -> Result<u64, Error> {
// Verify minimum signers
if signers.len() < threshold as usize {
return Err(Error::InsufficientSignatures);
}
// Verify all signers are authorized
for signer in signers {
verify_signer_authorization(signer)?;
}
// Issue credential
let credential_id = issue_credential(subject, credential_type, metadata_hash)?;
// Log multi-signature operation
log_multisig_operation(&credential_id, signers, threshold);
Ok(credential_id)
}Description: Attackers attempt to manipulate quorum slices to bypass verification requirements.
Attack Scenarios:
- Adding malicious attestors to a quorum slice
- Reducing the threshold to require fewer attestations
- Removing legitimate attestors
- Creating fake quorum slices
Mitigation Strategies:
- Implement strict access controls on quorum slice modifications
- Require multi-party approval for slice changes
- Maintain immutable audit trails
- Validate attestor credentials before adding to slice
Code Example:
// Validate attestor before adding to slice
pub fn add_attestor_with_validation(
slice_id: u64,
attestor: &Address,
) -> Result<(), Error> {
// Verify caller has permission
verify_caller_authorization()?;
// Validate attestor credentials
validate_attestor_credentials(attestor)?;
// Check for duplicate attestors
if slice_contains_attestor(slice_id, attestor) {
return Err(Error::DuplicateAttestor);
}
// Add attestor with audit log
add_attestor(slice_id, attestor)?;
log_attestor_addition(slice_id, attestor);
Ok(())
}
// Implement approval workflow for slice modifications
pub fn modify_slice_with_approval(
slice_id: u64,
modification: SliceModification,
approvers: &Vec<Address>,
) -> Result<(), Error> {
// Create modification request
let request_id = create_modification_request(slice_id, modification.clone())?;
// Collect approvals
let mut approval_count = 0;
for approver in approvers {
if approve_modification(request_id, approver)? {
approval_count += 1;
}
}
// Check if threshold met
let slice = get_slice(slice_id)?;
if approval_count < slice.threshold as usize {
return Err(Error::InsufficientApprovals);
}
// Apply modification
apply_modification(request_id, modification)?;
log_modification_applied(slice_id, request_id);
Ok(())
}Description: Attackers attempt to attest credentials without proper authorization.
Attack Scenarios:
- Attesting credentials for unauthorized subjects
- Providing false attestations
- Attesting revoked credentials
- Attesting credentials outside of authority scope
Mitigation Strategies:
- Implement role-based access control (RBAC)
- Verify attestor authority for credential type
- Check credential status before accepting attestation
- Maintain attestor reputation scores
Code Example:
// Verify attestor authority
pub fn attest_with_authority_check(
credential_id: u64,
attestor: &Address,
) -> Result<(), Error> {
let credential = get_credential(credential_id)?;
// Verify credential is not revoked
if credential.is_revoked {
return Err(Error::CredentialRevoked);
}
// Verify attestor has authority for this credential type
verify_attestor_authority(attestor, credential.credential_type)?;
// Check attestor reputation
let reputation = get_attestor_reputation(attestor)?;
if reputation < MINIMUM_REPUTATION_THRESHOLD {
return Err(Error::InsufficientReputation);
}
// Record attestation
attest(credential_id, attestor)?;
log_attestation(credential_id, attestor);
Ok(())
}
// Implement role-based access control
pub fn verify_attestor_authority(
attestor: &Address,
credential_type: u32,
) -> Result<(), Error> {
let attestor_role = get_attestor_role(attestor)?;
let allowed_types = get_allowed_credential_types(&attestor_role)?;
if !allowed_types.contains(&credential_type) {
return Err(Error::UnauthorizedCredentialType);
}
Ok(())
}Description: Attackers replay valid transactions to perform unauthorized operations.
Attack Scenarios:
- Replaying attestation transactions
- Replaying credential issuance transactions
- Replaying slice modifications
Mitigation Strategies:
- Implement nonce-based transaction validation
- Use sequence numbers for operations
- Implement time-based expiration
- Validate transaction signatures
Code Example:
// Implement nonce-based validation
pub fn attest_with_nonce(
credential_id: u64,
attestor: &Address,
nonce: u64,
) -> Result<(), Error> {
// Verify nonce hasn't been used
if nonce_used(attestor, nonce) {
return Err(Error::NonceAlreadyUsed);
}
// Verify nonce is within valid range
let current_nonce = get_current_nonce(attestor)?;
if nonce <= current_nonce {
return Err(Error::InvalidNonce);
}
// Perform attestation
attest(credential_id, attestor)?;
// Mark nonce as used
mark_nonce_used(attestor, nonce)?;
Ok(())
}
// Implement sequence-based validation
pub fn issue_credential_with_sequence(
subject: &Address,
credential_type: u32,
metadata_hash: &BytesN<32>,
sequence: u64,
) -> Result<u64, Error> {
// Get expected sequence
let expected_sequence = get_next_sequence(subject)?;
// Verify sequence matches
if sequence != expected_sequence {
return Err(Error::InvalidSequence);
}
// Issue credential
let credential_id = issue_credential(subject, credential_type, metadata_hash)?;
// Increment sequence
increment_sequence(subject)?;
Ok(credential_id)
}Description: Attackers create multiple fake identities to gain disproportionate influence.
Attack Scenarios:
- Creating multiple attestor accounts
- Manipulating quorum slices with fake attestors
- Gaining majority control through fake identities
Mitigation Strategies:
- Implement identity verification requirements
- Use reputation systems
- Implement rate limiting
- Monitor for suspicious patterns
Code Example:
// Implement identity verification
pub fn register_attestor_with_verification(
attestor: &Address,
identity_proof: &BytesN<32>,
) -> Result<(), Error> {
// Verify identity proof
verify_identity_proof(attestor, identity_proof)?;
// Check for duplicate identities
if identity_already_registered(identity_proof) {
return Err(Error::DuplicateIdentity);
}
// Register attestor
register_attestor(attestor)?;
store_identity_proof(attestor, identity_proof)?;
Ok(())
}
// Implement reputation system
pub fn update_attestor_reputation(
attestor: &Address,
delta: i32,
) -> Result<(), Error> {
let current_reputation = get_attestor_reputation(attestor)?;
let new_reputation = (current_reputation as i32 + delta).max(0) as u32;
// Check for suspicious reputation changes
if delta < -100 {
log_suspicious_activity(attestor, "Large reputation decrease");
}
// Update reputation
set_attestor_reputation(attestor, new_reputation)?;
Ok(())
}
// Implement rate limiting
pub fn attest_with_rate_limit(
credential_id: u64,
attestor: &Address,
) -> Result<(), Error> {
// Check rate limit
let attestations_in_window = count_recent_attestations(attestor, RATE_LIMIT_WINDOW)?;
if attestations_in_window >= MAX_ATTESTATIONS_PER_WINDOW {
return Err(Error::RateLimitExceeded);
}
// Perform attestation
attest(credential_id, attestor)?;
Ok(())
}Description: Attackers gain access to private keys and can impersonate users.
Attack Scenarios:
- Stealing private keys from wallets
- Compromising key management systems
- Phishing attacks to obtain keys
- Malware stealing keys from devices
Mitigation Strategies:
- Use hardware wallets for key storage
- Implement multi-signature schemes
- Use key rotation policies
- Implement transaction signing verification
Code Example:
// Implement secure key storage
class SecureKeyManager {
private keyStore: Map<string, EncryptedKey> = new Map();
// Store key with encryption
storeKey(userId: string, privateKey: string): void {
const encrypted = this.encryptKey(privateKey);
this.keyStore.set(userId, encrypted);
}
// Retrieve and decrypt key
getKey(userId: string, password: string): string {
const encrypted = this.keyStore.get(userId);
if (!encrypted) {
throw new Error('Key not found');
}
return this.decryptKey(encrypted, password);
}
// Encrypt key with AES-256
private encryptKey(key: string): EncryptedKey {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', this.masterKey, iv);
const encrypted = Buffer.concat([
cipher.update(key, 'utf8'),
cipher.final()
]);
return { iv: iv.toString('hex'), data: encrypted.toString('hex') };
}
// Decrypt key
private decryptKey(encrypted: EncryptedKey, password: string): string {
const decipher = crypto.createDecipheriv(
'aes-256-cbc',
this.masterKey,
Buffer.from(encrypted.iv, 'hex')
);
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encrypted.data, 'hex')),
decipher.final()
]);
return decrypted.toString('utf8');
}
}
// Implement transaction signing verification
async function verifyTransactionSignature(
transaction: Transaction,
publicKey: string
): Promise<boolean> {
const messageHash = crypto
.createHash('sha256')
.update(JSON.stringify(transaction.data))
.digest();
const isValid = crypto.verify(
'sha256',
messageHash,
publicKey,
Buffer.from(transaction.signature, 'hex')
);
return isValid;
}
// Implement key rotation
async function rotateKeys(userId: string): Promise<void> {
// Generate new key pair
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// Store new key
const keyManager = new SecureKeyManager();
keyManager.storeKey(userId, privateKey.export({ format: 'pem', type: 'pkcs8' }));
// Update public key in system
await updatePublicKey(userId, publicKey.export({ format: 'pem', type: 'spki' }));
// Log key rotation
logKeyRotation(userId);
}- Use secure coding practices
- Implement input validation
- Implement output encoding
- Use parameterized queries
- Implement proper error handling
- Avoid hardcoding secrets
- Use security linters
- Use HTTPS/TLS for all communications
- Implement rate limiting
- Use Web Application Firewall (WAF)
- Implement DDoS protection
- Use security headers
- Implement logging and monitoring
- Regular security updates
- Implement access controls
- Use multi-factor authentication
- Implement audit logging
- Regular security audits
- Incident response plan
- Backup and disaster recovery
- Security training for staff
- Use strong encryption algorithms
- Use secure random number generation
- Implement proper key management
- Use digital signatures
- Implement certificate pinning
- Regular cryptographic audits
- Monitor for suspicious activities
- Implement alerting systems
- Regular security assessments
- Penetration testing
- Identify: Determine the scope and nature of the incident
- Contain: Isolate affected systems
- Eradicate: Remove the threat
- Recover: Restore systems to normal operation
- Learn: Conduct post-incident analysis
- Notify affected users
- Inform regulatory bodies if required
- Maintain transparency
- Provide remediation guidance