CyberPanel Remote Backup Transfer Bug Fix
Problem Description
When attempting to transfer websites between two fresh CyberPanel servers using the Remote Backups feature (:8090/backup/remoteBackups), users encounter the following error:
Can not initiate remote transfer. Error message: 'transferStatus'
Or alternatively:
Can not initiate remote transfer. Error message: API request contains potentially dangerous characters: `;`, `&&`, `||`, `|`, `` ` ``, `$`, `../` are not allowed.
Root Causes
Bug #1: KeyError - ‘transferStatus’
Location: backup/backupManager.py line 1253
Issue: The code attempts to access data['transferStatus'] without first checking if the key exists in the response. When the remote API returns an error response without this key, Python raises a KeyError which gets caught and displayed as 'transferStatus'.
Code Before Fix:
data = json.loads(r.text)
if data['transferStatus'] == 1: # KeyError if 'transferStatus' doesn't exist
Bug #2: Newline Character in IP Address
Location: backup/backupManager.py line 1238
Issue: The machine IP address is read from /etc/cyberpanel/machineIP without stripping the trailing newline character (\n). When this IP (containing \n) is sent to the remote server’s API endpoint, the security middleware (CyberCP/secMiddleware.py line 196) rejects it because newline characters are blocked to prevent command injection attacks.
Code Before Fix:
ipFile = os.path.join("/etc", "cyberpanel", "machineIP")
f = open(ipFile)
ownIP = f.read() # Contains '\n' at the end
Security Validation in secMiddleware.py:
if isinstance(value, (str, bytes)) and (value.find('\n') > -1 or value.find(';') > -1 or ...):
return HttpResponse(json.dumps({
'error_message': "API request contains potentially dangerous characters..."
}))
Solution
Fix #1: Add Proper Error Handling
Add validation to check if transferStatus key exists before accessing it:
data = json.loads(r.text)
# Check if transferStatus key exists in response
if 'transferStatus' not in data:
error_msg = data.get('error_message', 'Invalid response from remote server: ' + str(data))
final_json = json.dumps({'remoteTransferStatus': 0,
'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
return HttpResponse(final_json)
if data['transferStatus'] == 1:
# ... rest of the code
Also update the else block to safely get error_message:
else:
error_msg = data.get('error_message', 'Unknown error from remote server')
final_json = json.dumps({'remoteTransferStatus': 0,
'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
return HttpResponse(final_json)
Fix #2: Strip Newline from IP Address
Change line 1238 to strip whitespace characters:
ipFile = os.path.join("/etc", "cyberpanel", "machineIP")
f = open(ipFile)
ownIP = f.read().strip() # Remove trailing newline and whitespace
Implementation Steps
Option 1: Manual Patch (Recommended)
-
Backup the original file:
sudo cp /usr/local/CyberCP/public/backup/backupManager.py /usr/local/CyberCP/public/backup/backupManager.py.backup -
Edit the file:
sudo nano /usr/local/CyberCP/public/backup/backupManager.py -
Apply Fix #2 (around line 1238):
Find:
ownIP = f.read()Replace with:
ownIP = f.read().strip() -
Apply Fix #1 (around line 1251-1253):
Find:
data = json.loads(r.text) if data['transferStatus'] == 1:Replace with:
data = json.loads(r.text) # Check if transferStatus key exists in response if 'transferStatus' not in data: error_msg = data.get('error_message', 'Invalid response from remote server: ' + str(data)) final_json = json.dumps({'remoteTransferStatus': 0, 'error_message': "Can not initiate remote transfer. Error message: " + error_msg}) return HttpResponse(final_json) if data['transferStatus'] == 1: -
Update the else block (around line 1278-1282):
Find:
else: final_json = json.dumps({'remoteTransferStatus': 0, 'error_message': "Can not initiate remote transfer. Error message: " + data['error_message']}) return HttpResponse(final_json)Replace with:
else: error_msg = data.get('error_message', 'Unknown error from remote server') final_json = json.dumps({'remoteTransferStatus': 0, 'error_message': "Can not initiate remote transfer. Error message: " + error_msg}) return HttpResponse(final_json) -
Restart CyberPanel services:
sudo systemctl restart lscpd
Option 2: Replace the Modified File
- Download the fixed file to your server
- Replace the original:
sudo cp backupManager.py /usr/local/CyberCP/public/backup/backupManager.py sudo systemctl restart lscpd
Verification
After applying the fix:
-
Test the remote backup transfer:
- Go to
https://your-server-ip:8090/backup/remoteBackups - Enter remote server IP, admin password
- Select a website
- Click “Start Transfer”
- Go to
-
Check for proper error messages:
- If there are connection issues, you should now see meaningful error messages instead of
'transferStatus' - The security validation error should no longer appear
- If there are connection issues, you should now see meaningful error messages instead of
-
Enable debug mode (optional):
sudo touch /usr/local/CyberCP/debugThen check logs at
/usr/local/CyberCP/logs/for detailed transfer status
Technical Details
Why This Bug Existed
-
Inconsistent Code Pattern: Throughout the CyberPanel codebase, when reading from
/etc/cyberpanel/machineIP, the standard pattern is:ipData = f.read() ipAddress = ipData.split('\n', 1)[0]The bug in
backupManager.pywas an inconsistency where this pattern wasn’t followed. -
Missing Validation: The code assumed the API would always return a valid response with
transferStatuskey, but didn’t handle cases where the API might return an error response with a different structure.
Files Modified
- File:
/usr/local/CyberCP/public/backup/backupManager.py - Function:
BackupManager.starRemoteTransfer()(note: typo in original function name) - Lines Changed: 1238, 1253-1258, 1286-1289
Related Files (No Changes Needed)
CyberCP/secMiddleware.py- Security validation middlewareplogical/remoteBackup.py- Remote backup utilitiesapi/views.py- API endpoint forremoteTransfer
Additional Notes
Prerequisites for Remote Backup
Ensure both servers have:
Ports 8090 (CyberPanel) and SSH port (default 22) open
Admin user has API access enabled
SSH root login enabled (the code automatically enables this)
Valid SSL certificates for CyberPanel
Common Issues After Fix
If you still face issues after applying the fix:
-
Check firewall rules:
sudo firewall-cmd --list-all -
Verify API access:
- Go to Users → List Users
- Edit admin user
- Ensure “API Access” is enabled
-
Check SSH connectivity:
ssh root@remote-server-ip -
Review logs:
tail -f /usr/local/CyberCP/logs/access.log tail -f /usr/local/CyberCP/logs/error.log
Contributing
If you encounter any issues with this fix or have improvements, please report them to the CyberPanel GitHub repository:
Version Information
- CyberPanel Version: Stable branch (as of 2025-10-22)
- Affected Versions: All versions with remote backup feature
- Fix Status: Pending official merge into stable branch
License
This fix follows the same license as CyberPanel (GPL-3.0)