---
description: SFCC security best practices and validation patterns
alwaysApply: true
---
# SFCC Security Best Practices
Use this rule when implementing security-sensitive features or validating user input.
## Mandatory MCP Tools Sequence
**BEFORE implementing ANY security-sensitive code:**
1. `mcp_sfcc-dev_search_best_practices` with query: "security"
2. `mcp_sfcc-dev_get_best_practice_guide` with guideName: "security"
3. `mcp_sfcc-dev_search_best_practices` with query: "validation"
4. `mcp_sfcc-dev_search_sfcc_classes` with query: relevant security domains
## MCP-Guided Security Development Process
### Step 1: Get Security Best Practices
```
Use: mcp_sfcc-dev_search_best_practices with query: "security"
Use: mcp_sfcc-dev_get_best_practice_guide with guideName: "security"
Purpose: Get comprehensive security guidelines, validation patterns, and threat mitigation strategies
```
### Step 2: Input Validation Patterns
```
Use: mcp_sfcc-dev_search_best_practices with query: "validation"
Purpose: Get input validation, sanitization, and XSS prevention patterns
```
### Step 3: SFCC Security API Research
```
Use: mcp_sfcc-dev_search_sfcc_classes with query: [security domain]
Use: mcp_sfcc-dev_get_sfcc_class_info with className: [security-related classes]
Purpose: Understand available SFCC security APIs and encryption methods
```
## MCP-Enhanced Input Validation Template
```javascript
'use strict';
/**
* Input Validation Utilities
* Implementation based on:
* - mcp_sfcc-dev_search_best_practices with query: "security"
* - mcp_sfcc-dev_get_best_practice_guide with guideName: "security"
*/
var StringUtils = require('dw/util/StringUtils');
var Logger = require('dw/system/Logger').getLogger('security', 'InputValidation');
/**
* Validate and sanitize user input
* Security patterns from MCP security best practices
* @param {string} input - User provided input
* @param {string} type - Expected input type (email, phone, text, etc.)
* @param {Object} options - Validation options
* @returns {Object} Validation result
*/
function validateInput(input, type, options) {
options = options || {};
try {
// Basic type validation (from MCP security guide)
if (!input || typeof input !== 'string') {
return { valid: false, error: 'Invalid input type', code: 'INVALID_TYPE' };
}
// Length validation (security pattern from MCP)
var maxLength = options.maxLength || 1000;
if (input.length > maxLength) {
Logger.warn('Input length exceeded limit: {0} > {1}', input.length, maxLength);
return { valid: false, error: 'Input too long', code: 'LENGTH_EXCEEDED' };
}
// Empty input handling (from MCP validation patterns)
if (input.trim().length === 0) {
return { valid: false, error: 'Input cannot be empty', code: 'EMPTY_INPUT' };
}
// Sanitize for XSS (critical security pattern from MCP)
var sanitized = StringUtils.stringToHtml(input);
// Type-specific validation (patterns from MCP security guide)
switch (type) {
case 'email':
var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(input)) {
return { valid: false, error: 'Invalid email format', code: 'INVALID_EMAIL' };
}
break;
case 'phone':
var phoneRegex = /^\+?[\d\s\-\(\)]+$/;
if (!phoneRegex.test(input)) {
return { valid: false, error: 'Invalid phone format', code: 'INVALID_PHONE' };
}
break;
case 'alphanumeric':
var alphaNumRegex = /^[a-zA-Z0-9]+$/;
if (!alphaNumRegex.test(input)) {
return { valid: false, error: 'Only alphanumeric characters allowed', code: 'INVALID_ALPHANUMERIC' };
}
break;
case 'customerNo':
// Customer number validation (SFCC-specific pattern from MCP)
var customerNoRegex = /^[a-zA-Z0-9\-_]+$/;
if (!customerNoRegex.test(input) || input.length > 50) {
return { valid: false, error: 'Invalid customer number format', code: 'INVALID_CUSTOMER_NO' };
}
break;
case 'productId':
// Product ID validation (SFCC-specific pattern from MCP)
var productIdRegex = /^[a-zA-Z0-9\-_\.]+$/;
if (!productIdRegex.test(input) || input.length > 100) {
return { valid: false, error: 'Invalid product ID format', code: 'INVALID_PRODUCT_ID' };
}
break;
}
// Additional security checks (from MCP security patterns)
if (containsSuspiciousPatterns(input)) {
Logger.warn('Suspicious input pattern detected: {0}', input.substring(0, 50) + '...');
return { valid: false, error: 'Input contains invalid patterns', code: 'SUSPICIOUS_INPUT' };
}
return { valid: true, sanitized: sanitized, original: input };
} catch (e) {
Logger.error('Error during input validation: {0}', e.message);
return { valid: false, error: 'Validation error', code: 'VALIDATION_ERROR' };
}
}
/**
* Check for suspicious patterns that could indicate attacks
* Security patterns from MCP security guide
*/
function containsSuspiciousPatterns(input) {
var suspiciousPatterns = [
/<script/i, // XSS attempt
/javascript:/i, // JavaScript protocol
/on\w+\s*=/i, // Event handlers
/eval\s*\(/i, // Code execution
/expression\s*\(/i, // CSS expression
/'.*OR.*'/i, // SQL injection
/UNION.*SELECT/i, // SQL injection
/DROP.*TABLE/i, // SQL injection
/--/, // SQL comment
/\/\*/, // Multi-line comment
/\.\.\//, // Path traversal
/%2e%2e%2f/i, // Encoded path traversal
/\x00/, // Null byte
];
return suspiciousPatterns.some(function(pattern) {
return pattern.test(input);
});
}
module.exports.validateInput = validateInput;
module.exports.containsSuspiciousPatterns = containsSuspiciousPatterns;
```
## MCP-Enhanced Authentication Patterns
```javascript
'use strict';
/**
* Authentication and Authorization Utilities
* Implementation based on MCP security best practices
*/
var Logger = require('dw/system/Logger').getLogger('security', 'Authentication');
/**
* Check customer authentication with comprehensive logging
* Security pattern from MCP security guide
*/
function validateCustomerAuthentication(req, res, options) {
options = options || {};
try {
var customer = req.currentCustomer;
// Basic authentication check (from MCP security patterns)
if (!customer || !customer.authenticated) {
Logger.warn('Unauthenticated access attempt to protected resource: {0}', req.httpURL);
if (options.returnJson) {
res.setStatusCode(401);
res.json({
error: 'AUTHENTICATION_REQUIRED',
message: 'Authentication required'
});
} else {
res.setStatusCode(401);
res.render('error/unauthorized');
}
return false;
}
// Additional security checks (from MCP security guide)
if (options.requireActiveCustomer && !customer.profile) {
Logger.warn('Customer authenticated but no profile found: {0}', customer.ID);
if (options.returnJson) {
res.setStatusCode(403);
res.json({
error: 'INVALID_CUSTOMER_STATE',
message: 'Customer profile required'
});
} else {
res.setStatusCode(403);
res.render('error/forbidden');
}
return false;
}
// Log successful authentication (for security auditing)
Logger.debug('Customer authentication validated: {0}', customer.profile ? customer.profile.customerNo : customer.ID);
return true;
} catch (e) {
Logger.error('Error during authentication validation: {0}', e.message);
if (options.returnJson) {
res.setStatusCode(500);
res.json({
error: 'AUTHENTICATION_ERROR',
message: 'Authentication validation failed'
});
} else {
res.setStatusCode(500);
res.render('error/servererror');
}
return false;
}
}
/**
* Check specific permissions for authenticated customers
* Authorization pattern from MCP security guide
*/
function checkCustomerPermissions(customer, requiredPermissions) {
if (!customer || !customer.authenticated || !customer.profile) {
return { authorized: false, error: 'Customer not authenticated' };
}
// Implement permission checking logic based on your business requirements
// This is a template - customize based on your permission system
if (requiredPermissions && requiredPermissions.length > 0) {
// Check customer groups, custom attributes, or other permission mechanisms
var hasPermissions = requiredPermissions.every(function(permission) {
return checkSinglePermission(customer, permission);
});
if (!hasPermissions) {
Logger.warn('Customer {0} lacks required permissions: {1}',
customer.profile.customerNo, requiredPermissions.join(', '));
return { authorized: false, error: 'Insufficient permissions' };
}
}
return { authorized: true };
}
function checkSinglePermission(customer, permission) {
// Implement your specific permission logic here
// Examples: customer groups, custom attributes, etc.
return true; // Placeholder implementation
}
module.exports.validateCustomerAuthentication = validateCustomerAuthentication;
module.exports.checkCustomerPermissions = checkCustomerPermissions;
```
## Security Checklist (MCP-Verified)
Before implementing security features, verify with MCP:
- [ ] `mcp_sfcc-dev_search_best_practices` with query: "security" - Get security patterns
- [ ] `mcp_sfcc-dev_get_best_practice_guide` with guideName: "security" - Comprehensive guide
- [ ] `mcp_sfcc-dev_search_best_practices` with query: "validation" - Input validation patterns
Implementation verification:
- [ ] Validate all user inputs with type-specific validation
- [ ] Sanitize data before rendering in templates
- [ ] Use CSRF protection for forms
- [ ] Implement proper authentication checks
- [ ] Avoid exposing sensitive data in errors
- [ ] Use HTTPS for all sensitive operations
- [ ] Validate file uploads and restrict types
- [ ] Implement rate limiting for APIs
- [ ] Use secure session management
- [ ] Log security events appropriately
## Common Security Anti-Patterns (from MCP Security Guide)
```javascript
// DON'T: Direct parameter access without validation (security vulnerability)
var userInput = request.httpParameterMap.parameter.value;
response.getWriter().print(userInput); // XSS vulnerability
// DO: Validate and sanitize (pattern from MCP security guide)
var userInput = request.httpParameterMap.parameter.value;
var validation = validateInput(userInput, 'text');
if (validation.valid) {
response.getWriter().print(validation.sanitized);
} else {
Logger.warn('Invalid input rejected: {0}', validation.error);
response.getWriter().print('Invalid input provided');
}
// DON'T: Expose system errors to users (information disclosure)
try {
// Operation
} catch (e) {
response.getWriter().print('Database error: ' + e.message); // Exposes system info
}
// DO: Log errors securely and return generic messages (MCP security pattern)
try {
// Operation
} catch (e) {
Logger.error('Database operation failed: {0}', e.message);
response.getWriter().print('An error occurred. Please try again later.');
}
```
## CSRF Protection Pattern (from MCP Security Guide)
```javascript
// Controller implementation with CSRF protection
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
// Route to display the form with CSRF token
server.get('ShowForm', csrfProtection.generateToken, function (req, res, next) {
res.render('myFormTemplate', {
csrf: res.getViewData().csrf // Pass token to template
});
next();
});
// Route to handle the submission with CSRF validation
server.post('SubmitForm', csrfProtection.validateRequest, function (req, res, next) {
// If execution reaches here, the token was valid
var formData = req.form;
var validation = validateInput(formData.userInput, 'text');
if (!validation.valid) {
res.json({
success: false,
error: validation.error
});
return next();
}
// Process validated data
res.json({ success: true });
next();
});
```
## NEVER Implement Security Without MCP
- ❌ Don't implement validation without patterns - use `mcp_sfcc-dev_search_best_practices`
- ❌ Don't skip input sanitization - use MCP XSS prevention patterns
- ❌ Don't expose system errors - follow MCP error handling guide
- ❌ Don't implement authentication without consulting MCP security guide
- ❌ Don't assume security APIs - use `mcp_sfcc-dev_search_sfcc_classes`