Implementing robust security measures is crucial for protecting user data, preventing unauthorized access, and maintaining system integrity. This guide covers comprehensive security practices for ShahiAssist.
Input Validation and Sanitization
Data Sanitization
`php
// Sanitize all user inputs
function sanitizeticketdata($data) {
return [
‘title’ => sanitizetextfield($data[‘title’] ?? ”),
‘description’ => wpksespost($data[‘description’] ?? ”),
‘priority’ => in_array($data[‘priority’] ?? ”, [‘low’, ‘medium’, ‘high’, ‘urgent’]) ? $data[‘priority’] : ‘medium’,
‘category’ => absint($data[‘category’] ?? 0),
‘tags’ => arraymap(‘sanitizetext_field’, $data[‘tags’] ?? []),
];
}
// Use before saving
$sanitizeddata = sanitizeticketdata($POST);
updatepostmeta($postid, ‘ticketdata’, $sanitizeddata);
`
Nonce Verification
`php
// Add nonces to all forms
function addsecuritynonce() {
wpnoncefield(‘shahiassistaction’, ‘shahiassistnonce’);
}
// Verify nonces on form submission
function verifysecuritynonce() {
if (!wpverifynonce($POST[‘shahiassistnonce’] ?? ”, ‘shahiassist_action’)) {
wp_die(‘Security check failed’, ‘Security Error’, [‘response’ => 403]);
}
}
`
SQL Injection Prevention
`php
// Always use prepared statements
global $wpdb;
$tickets = $wpdb->get_results($wpdb->prepare(“
SELECT * FROM {$wpdb->posts}
WHERE post_type = %s
AND post_author = %d
AND post_status = %s
LIMIT %d
“, ‘ticket’, $user_id, ‘publish’, 10));
// Use wpdb->prepare for all dynamic queries
$metavalue = $wpdb->getvar($wpdb->prepare(“
SELECT meta_value FROM {$wpdb->postmeta}
WHERE postid = %d AND metakey = %s
“, $postid, ‘ticket_status’));
`
Authentication and Authorization
Role-Based Access Control
`php
// Define custom capabilities
function addshahiassist_capabilities() {
$roles = [‘administrator’, ‘editor’, ‘author’, ‘contributor’];
foreach ($roles as $role_name) {
$role = getrole($rolename);
if ($role) {
$role->addcap(‘manageshahiassisttickets’);
$role->addcap(‘viewshahiassistreports’);
}
}
// Add agent role
addrole(‘shahiagent’, ‘Support Agent’, [
‘read’ => true,
‘manageshahiassist_tickets’ => true,
‘editshahiassist_tickets’ => true,
‘deleteshahiassist_tickets’ => false,
]);
}
// Check permissions before actions
function checkticketaccess($ticket_id, $action = ‘view’) {
$ticket = getpost($ticketid);
if (!$ticket || $ticket->post_type !== ‘ticket’) {
return false;
}
$userid = getcurrentuserid();
// Check if user owns the ticket or has agent role
if ($ticket->postauthor == $userid || currentusercan(‘manageshahiassist_tickets’)) {
return true;
}
return false;
}
`
Session Management
`php
// Secure session configuration
add_action(‘init’, function() {
// Force secure cookies in production
if (is_ssl()) {
iniset(‘session.cookiesecure’, 1);
iniset(‘session.cookiehttponly’, 1);
iniset(‘session.cookiesamesite’, ‘Strict’);
}
// Regenerate session ID periodically
if (!isset($SESSION[‘lastregeneration’])) {
$SESSION[‘lastregeneration’] = time();
} elseif (time() – $SESSION[‘lastregeneration’] > 300) { // 5 minutes
sessionregenerateid(true);
$SESSION[‘lastregeneration’] = time();
}
});
`
Two-Factor Authentication
`php
// Integrate with WordPress 2FA
addfilter(‘wplogin’, function($user_login, $user) {
if (getusermeta($user->ID, ‘shahiassist2fa_enabled’, true)) {
// Redirect to 2FA verification
wpredirect(addquery_arg([
‘action’ => ‘verify_2fa’,
‘user_id’ => $user->ID
], wploginurl()));
exit;
}
}, 10, 2);
// Verify 2FA code
function verify2facode($user_id, $code) {
$secret = getusermeta($userid, ‘shahiassist2fasecret’, true);
// Use a 2FA library like Google Authenticator
require_once ‘vendor/sonata-project/google-authenticator/src/FixedBitNotation.php’;
require_once ‘vendor/sonata-project/google-authenticator/src/GoogleAuthenticator.php’;
$g = new \Sonata\GoogleAuthenticator\GoogleAuthenticator();
return $g->checkCode($secret, $code);
}
`
File Upload Security
Secure File Uploads
`php
function securefileupload($file) {
// Check file type
$allowed_types = [‘image/jpeg’, ‘image/png’, ‘application/pdf’];
if (!inarray($file[‘type’], $allowedtypes)) {
return new WPError(‘invalidfile_type’, ‘File type not allowed’);
}
// Check file size (5MB limit)
$max_size = 5 1024 1024;
if ($file[‘size’] > $max_size) {
return new WPError(‘filetoo_large’, ‘File size exceeds limit’);
}
// Generate secure filename
$filename = sanitizefilename($file[‘name’]);
$filename = wpuniquefilename(wpuploaddir()[‘path’], $filename);
// Move file to secure location
$uploaddir = wpupload_dir();
$targetpath = $uploaddir[‘path’] . ‘/’ . $filename;
if (!moveuploadedfile($file[‘tmpname’], $targetpath)) {
return new WPError(‘uploadfailed’, ‘File upload failed’);
}
return [
‘file’ => $filename,
‘url’ => $upload_dir[‘url’] . ‘/’ . $filename,
‘path’ => $target_path
];
}
`
Image Processing Security
`php
// Strip EXIF data for privacy
addfilter(‘wphandle_upload’, function($upload) {
if (strpos($upload[‘type’], ‘image/’) === 0) {
$image_path = $upload[‘file’];
// Remove EXIF data
if (functionexists(‘exifread_data’)) {
$exif = @exifreaddata($image_path);
if ($exif) {
// Create new image without EXIF
$image = wpgetimageeditor($imagepath);
if (!iswperror($image)) {
$image->save($image_path);
}
}
}
}
return $upload;
});
`
API Security
REST API Authentication
`php
// Custom authentication for REST API
addfilter(‘restauthentication_errors’, function($result) {
if (!empty($result)) {
return $result;
}
if (!isuserlogged_in()) {
return new WPError(‘restnotloggedin’, ‘You are not logged in.’, [‘status’ => 401]);
}
return $result;
});
// API key authentication for external access
function authenticateapikey() {
$apikey = $SERVER[‘HTTPXAPI_KEY’] ?? ”;
if (empty($api_key)) {
return false;
}
$validkeys = getoption(‘shahiassistapi_keys’, []);
return inarray($apikey, $valid_keys);
}
// Rate limiting
class ShahiAssist_RateLimiter {
private $max_requests = 100;
private $time_window = 3600; // 1 hour
public function check_limit($identifier) {
$key = ‘shahiassistrate_’ . md5($identifier);
$requests = get_transient($key) ?: [];
// Remove old requests
$requests = array_filter($requests, function($time) {
return $time > (time() – $this->time_window);
});
if (count($requests) >= $this->max_requests) {
return false;
}
$requests[] = time();
settransient($key, $requests, $this->timewindow);
return true;
}
}
`
Webhook Security
`php
// Verify webhook signatures
function verifywebhooksignature($payload, $signature, $secret) {
$expectedsignature = hashhmac(‘sha256’, $payload, $secret);
return hashequals($expectedsignature, $signature);
}
// Process secure webhooks
addaction(‘restapi_init’, function() {
registerrestroute(‘shahi-assist/v1’, ‘/webhook/(?P
‘methods’ => ‘POST’,
‘callback’ => ‘handlesecurewebhook’,
‘permissioncallback’ => ‘returntrue’,
]);
});
function handlesecurewebhook($request) {
$provider = $request->get_param(‘provider’);
$secret = getoption(“shahiassistwebhooksecret_{$provider}”);
if (!$secret) {
return new WPError(‘invalidprovider’, ‘Unknown webhook provider’, [‘status’ => 400]);
}
$signature = $request->get_header(‘X-Signature’);
$payload = $request->get_body();
if (!verifywebhooksignature($payload, $signature, $secret)) {
return new WPError(‘invalidsignature’, ‘Invalid webhook signature’, [‘status’ => 401]);
}
// Process webhook payload
$data = json_decode($payload, true);
processwebhookdata($provider, $data);
return [‘status’ => ‘success’];
}
`
Data Protection
Data Encryption
`php
// Encrypt sensitive data
function encrypt_data($data, $key = null) {
if (!$key) {
$key = getoption(‘shahiassistencryptionkey’);
}
$cipher = “aes-256-gcm”;
$iv = random_bytes(16);
$tag = ”;
$encrypted = opensslencrypt($data, $cipher, $key, OPENSSLRAW_DATA, $iv, $tag);
return base64_encode($iv . $tag . $encrypted);
}
function decryptdata($encrypteddata, $key = null) {
if (!$key) {
$key = getoption(‘shahiassistencryptionkey’);
}
$data = base64decode($encrypteddata);
$iv = substr($data, 0, 16);
$tag = substr($data, 16, 16);
$encrypted = substr($data, 32);
return openssldecrypt($encrypted, “aes-256-gcm”, $key, OPENSSLRAW_DATA, $iv, $tag);
}
// Store encrypted sensitive data
updatepostmeta($ticketid, ‘encryptedcustomerdata’, encryptdata($customerdata));
`
GDPR Compliance
`php
// Data export functionality
addaction(‘wpajaxexportuser_data’, function() {
$userid = getcurrentuserid();
if (!$user_id) {
wp_die(‘Unauthorized’);
}
$data = [
‘tickets’ => getusertickets($user_id),
‘profile’ => getusermeta($user_id),
‘activity’ => getuseractivitylog($userid),
];
header(‘Content-Type: application/json’);
header(‘Content-Disposition: attachment; filename=”user-data-export.json”‘);
echo json_encode($data);
exit;
});
// Data deletion
function deleteuserdata($user_id) {
// Anonymize tickets
$tickets = get_posts([
‘post_type’ => ‘ticket’,
‘author’ => $user_id,
‘postsperpage’ => -1,
‘fields’ => ‘ids’
]);
foreach ($tickets as $ticket_id) {
wpupdatepost([
‘ID’ => $ticket_id,
‘post_author’ => 0, // Anonymous
‘post_title’ => ‘Anonymous Ticket’,
‘post_content’ => ‘Content removed for privacy’
]);
// Remove personal meta
deletepostmeta($ticketid, ‘customer_email’);
deletepostmeta($ticketid, ‘customer_phone’);
}
// Remove user activity logs
global $wpdb;
$wpdb->delete($wpdb->prefix . ‘shahiassistactivitylog’, [‘userid’ => $user_id]);
}
`
XSS Prevention
Output Escaping
`php
// Always escape output
function displayticketinfo($ticket) {
?>
html($ticket->posttitle); ?>
Status: html(getpostmeta($ticket->ID, ‘ticket_status’, true)); ?>
Created: html(getthe_date(”, $ticket)); ?>
title” value=”‘ . escattr($title) . ‘” />’;
// Escape URLs
echo ‘WordPress Security Best Practices
Share this article
Still need help?
Our support team is ready to assist you with personalized guidance for your workspace.