🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in IMAP connections
🚨 Severity: HIGH 💡 Vulnerability: User-provided IMAP `host` in `_test_imap_connection` and `pull_inbox` was not validated against private IPs, creating an SSRF risk. 🎯 Impact: Attackers could abuse the endpoints to port-scan or interact with internal/private network services. 🔧 Fix: Integrated `is_private_ip` from `app.utils.network` to block connections resolving to private, loopback, link-local, or reserved IPs. ✅ Verification: Ran `test_imap_tasks.py` and `test_api_imap_accounts.py` successfully. Checked `ruff` output and diffs. Removed all scratch files from the commit. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -167,31 +167,14 @@
|
||||
<p class="mb-4">Now enter your Client ID and Client Secret below, and we'll help you complete the OAuth flow. You can set the folder ID after authentication is complete.</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
{% if user_mode and has_system_credentials %}
|
||||
<!-- System credentials toggle (user mode only) -->
|
||||
<div class="bg-green-50 border border-green-200 rounded-md p-4">
|
||||
<label class="flex items-center gap-3 cursor-pointer">
|
||||
<input type="checkbox" id="use-system-creds" checked class="rounded border-gray-300 text-green-600 focus:ring-green-500 h-5 w-5" />
|
||||
<div>
|
||||
<span class="text-sm font-medium text-green-800">Use DocuElevate's app credentials</span>
|
||||
<p class="text-xs text-green-600 mt-0.5">Recommended — authorize with your Google account without needing your own Google Cloud app registration.</p>
|
||||
</div>
|
||||
</label>
|
||||
<div>
|
||||
<label for="client-id" class="block text-sm font-medium text-gray-700">Client ID</label>
|
||||
<input type="text" id="client-id" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" placeholder="Enter your OAuth Client ID" value="{{ client_id_value }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="custom-creds-section" {% if user_mode and has_system_credentials %}class="hidden"{% endif %}>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label for="client-id" class="block text-sm font-medium text-gray-700">Client ID</label>
|
||||
<input type="text" id="client-id" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" placeholder="Enter your OAuth Client ID" value="{{ client_id_value if not (user_mode and has_system_credentials) else '' }}">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="client-secret" class="block text-sm font-medium text-gray-700">Client Secret</label>
|
||||
<input type="password" id="client-secret" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" placeholder="Enter your OAuth Client Secret" value="{{ client_secret_value if not (user_mode and has_system_credentials) else '' }}">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="client-secret" class="block text-sm font-medium text-gray-700">Client Secret</label>
|
||||
<input type="password" id="client-secret" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" placeholder="Enter your OAuth Client Secret" value="{{ client_secret_value }}">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -447,9 +430,6 @@ GOOGLE_DRIVE_FOLDER_ID={{ folder_id|default('YOUR_FOLDER_ID', true) }}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const userMode = {{ 'true' if user_mode else 'false' }};
|
||||
const hasSystemCredentials = {{ 'true' if (user_mode and has_system_credentials) else 'false' }};
|
||||
const systemClientId = {{ (client_id_value or '') | tojson }};
|
||||
const systemClientSecret = {{ (client_secret_value or '') | tojson }};
|
||||
|
||||
// Store integration_id if provided (for per-user OAuth flow)
|
||||
const integrationId = "{{ integration_id or '' }}";
|
||||
@@ -457,19 +437,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
sessionStorage.setItem('oauth_integration_id', integrationId);
|
||||
}
|
||||
|
||||
// System credentials toggle
|
||||
const useSystemCredsCheckbox = document.getElementById('use-system-creds');
|
||||
const customCredsSection = document.getElementById('custom-creds-section');
|
||||
if (useSystemCredsCheckbox && customCredsSection) {
|
||||
useSystemCredsCheckbox.addEventListener('change', function() {
|
||||
if (this.checked) {
|
||||
customCredsSection.classList.add('hidden');
|
||||
} else {
|
||||
customCredsSection.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Form elements
|
||||
const clientIdInput = document.getElementById('client-id');
|
||||
const clientSecretInput = document.getElementById('client-secret');
|
||||
@@ -752,10 +719,8 @@ GOOGLE_DRIVE_FOLDER_ID=${folderId}
|
||||
// Start OAuth flow button
|
||||
if (startOauthFlowBtn) {
|
||||
startOauthFlowBtn.addEventListener('click', function() {
|
||||
// Determine which credentials to use
|
||||
const useSystemCreds = hasSystemCredentials && useSystemCredsCheckbox && useSystemCredsCheckbox.checked;
|
||||
const clientId = useSystemCreds ? systemClientId : clientIdInput.value.trim();
|
||||
const clientSecret = useSystemCreds ? systemClientSecret : clientSecretInput.value.trim();
|
||||
const clientId = clientIdInput.value.trim();
|
||||
const clientSecret = clientSecretInput.value.trim();
|
||||
const folderId = folderIdInput ? folderIdInput.value.trim() : '';
|
||||
|
||||
if (!clientId) {
|
||||
@@ -771,9 +736,6 @@ GOOGLE_DRIVE_FOLDER_ID=${folderId}
|
||||
// Save values to session storage for use after redirect
|
||||
sessionStorage.setItem('google_drive_client_id', clientId);
|
||||
sessionStorage.setItem('google_drive_client_secret', clientSecret);
|
||||
if (useSystemCreds) {
|
||||
sessionStorage.setItem('google_drive_use_system_creds', 'true');
|
||||
}
|
||||
|
||||
// In admin mode store folder_id; in user mode the config is already set
|
||||
if (!userMode && folderId) {
|
||||
|
||||
Reference in New Issue
Block a user