{"id":9075,"date":"2026-05-03T08:49:36","date_gmt":"2026-05-03T03:19:36","guid":{"rendered":"https:\/\/www.veeble.com\/kb\/?p=9075"},"modified":"2026-05-03T09:05:14","modified_gmt":"2026-05-03T03:35:14","slug":"cve-2026-41940-cve-2026-31431-two-critical-vulnerabilities-affecting-linux-servers-fix-now","status":"publish","type":"post","link":"https:\/\/www.veeble.com\/kb\/cve-2026-41940-cve-2026-31431-two-critical-vulnerabilities-affecting-linux-servers-fix-now\/","title":{"rendered":"CVE-2026-41940 &amp; CVE-2026-31431: Two Critical Vulnerabilities Affecting Linux Servers &#8211; Fix Now"},"content":{"rendered":"\n<p>Two critical security vulnerabilities were publicly disclosed in late April 2026 that affect a large portion of Linux-based servers, including cPanel\/WHM installations and any Linux server running a kernel version from 4.14 onward. Both require immediate action.<\/p>\n\n\n\n<p>This article covers what each vulnerability does, which systems are affected, and the exact steps to patch or mitigate each one.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h2 class=\"wp-block-heading\" id=\"cve202641940-cpanel-amp-whm-authentication-bypass\">CVE-2026-41940 \u2014 cPanel &amp; WHM Authentication Bypass<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"what-this-vulnerability-does\">What This Vulnerability Does<\/h3>\n\n\n<p>CVE-2026-41940 is an authentication bypass flaw in cPanel software, including DNSOnly. It affects all cPanel versions after 11.40. A remote attacker can exploit this to authenticate to cPanel, WHM, or Webmail interfaces without valid credentials, gaining full or partial access to hosted accounts and server administration panels.<\/p>\n\n\n\n<p>Patches have been released. If your server is running cPanel, treat this as a P1 incident and update immediately.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"affected-versions\">Affected Versions<\/h3>\n\n\n<p>All cPanel &amp; WHM versions from 11.40 onward are vulnerable. The following builds include the patch:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>cPanel Tier<\/th><th>Patched Version<\/th><\/tr><\/thead><tbody><tr><td>11.86<\/td><td>11.86.0.41<\/td><\/tr><tr><td>11.110<\/td><td>11.110.0.97<\/td><\/tr><tr><td>11.118<\/td><td>11.118.0.63<\/td><\/tr><tr><td>11.124<\/td><td>11.124.0.35<\/td><\/tr><tr><td>11.126<\/td><td>11.126.0.54<\/td><\/tr><tr><td>11.130<\/td><td>11.130.0.19<\/td><\/tr><tr><td>11.132<\/td><td>11.132.0.29<\/td><\/tr><tr><td>11.134<\/td><td>11.134.0.20<\/td><\/tr><tr><td>11.136<\/td><td>11.136.0.5<\/td><\/tr><tr><td>WP Squared<\/td><td>136.1.7<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If you are on <strong>CentOS 6 or CloudLinux 6 running v110.0.50<\/strong>, a direct upgrade path to v110.0.103 is available (see Step 1 below).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"how-to-patch-cve202641940\">How to Patch CVE-2026-41940<\/h3>\n\n\n<p><strong>Step 1 \u2014 (CentOS 6 \/ CloudLinux 6 on v110 only)<\/strong> Set the upgrade tier before running the update:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>whmapi1 set_tier tier=11.110.0.103<\/code><\/pre>\n\n\n\n<p>For CentOS 7 or CloudLinux 7 servers that need to pin to 11.110:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>whmapi1 set_tier tier=11.110<\/code><\/pre>\n\n\n\n<p><strong>Step 2 \u2014 Run the forced cPanel update:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/scripts\/upcp --force<\/code><\/pre>\n\n\n\n<p><strong>Step 3 \u2014 Confirm the build version after the update completes:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/usr\/local\/cpanel\/cpanel -V<\/code><\/pre>\n\n\n\n<p>Verify the output matches one of the patched versions listed in the table above.<\/p>\n\n\n\n<p><strong>Step 4 \u2014 Perform a hard restart of the cPanel service:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/scripts\/restartsrv_cpsrvd --hard<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong> If you have disabled automatic cPanel updates or pinned your server to a specific version, it will not have auto-updated. Identify and update these servers manually as a priority.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"if-you-cannot-update-immediately\">If You Cannot Update Immediately<\/h3>\n\n\n<p>Apply one of the following mitigations to reduce exposure while you prepare the update:<\/p>\n\n\n\n<p><strong>Option A \u2014 Block cPanel ports at the firewall:<\/strong><\/p>\n\n\n\n<p>Block inbound traffic on ports <code>2083<\/code>, <code>2087<\/code>, <code>2095<\/code>, and <code>2096<\/code>.<\/p>\n\n\n\n<p><strong>Option B \u2014 Stop the cPanel service entirely:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>whmapi1 configureservice service=cpsrvd enabled=0 monitored=0 &amp;&amp; \\\nwhmapi1 configureservice service=cpdavd enabled=0 monitored=0 &amp;&amp; \\\n\/scripts\/restartsrv_cpsrvd --stop &amp;&amp; \\\n\/scripts\/restartsrv_cpdavd --stop<\/code><\/pre>\n\n\n\n<p>This will take cPanel and Webmail offline. Only use this if you have an alternative way to manage the server (SSH\/WHM API) and downtime is acceptable.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"checking-for-indicators-of-compromise\">Checking for Indicators of Compromise<\/h3>\n\n\n<p>cPanel has released a detection script that scans session files for signs of exploitation. Save the script below as <code>ioc_checksessions_files.sh<\/code>, then run it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/bin\/bash .\/ioc_checksessions_files.sh<\/code><\/pre>\n\n\n\n<p>The script checks for six distinct exploitation patterns across session files in <code>\/var\/cpanel\/sessions\/raw\/<\/code> and produces a severity-graded summary:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>=================================================================\n                       SCAN SUMMARY\n=================================================================\n  CRITICAL findings: 1\n  WARNING  findings: 0\n  ATTEMPT  findings: 1\n  INFO     findings: 0\n  Total            : 2<\/code><\/pre>\n\n\n\n<p><strong>Severity levels:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Severity<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td>CRITICAL<\/td><td>Active exploitation confirmed. The injected session was used to authenticate successfully.<\/td><\/tr><tr><td>WARNING<\/td><td>Suspicious session structure that cannot occur in a legitimate flow.<\/td><\/tr><tr><td>ATTEMPT<\/td><td>A failed exploit attempt was detected \u2014 session was probed but authentication was not achieved.<\/td><\/tr><tr><td>INFO<\/td><td>Anomalous but inconclusive. Monitor and investigate.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The script also accepts the following optional flags:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Flag<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>--verbose<\/code><\/td><td>Dump full contents of flagged session files<\/td><\/tr><tr><td><code>--purge<\/code><\/td><td>Delete all flagged session files and their preauth markers<\/td><\/tr><tr><td><code>--yes<\/code><\/td><td>Skip interactive confirmation when used with <code>--purge<\/code> (required in cron\/non-TTY environments)<\/td><\/tr><tr><td><code>--sessions-dir DIR<\/code><\/td><td>Override the default <code>\/var\/cpanel\/sessions<\/code> path<\/td><\/tr><tr><td><code>--access-log FILE<\/code><\/td><td>Override the default access log path<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Exit codes<\/strong> (useful for monitoring integrations):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Code<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td><code>0<\/code><\/td><td>Clean \u2014 no indicators found<\/td><\/tr><tr><td><code>1<\/code><\/td><td>Probing activity detected (ATTEMPT or INFO only)<\/td><\/tr><tr><td><code>2<\/code><\/td><td>Compromise indicators detected (CRITICAL or WARNING present)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Detection Script:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# Scan for compromised cPanel\/WHM session files.\n\nSESSIONS_DIR=\"\/var\/cpanel\/sessions\"\nACCESS_LOG=\"\/usr\/local\/cpanel\/logs\/access_log\"\nVERBOSE=0\nPURGE=0\nASSUME_YES=0\n\nwhile &#091; $# -gt 0 ]; do\n    case \"$1\" in\n        --verbose) VERBOSE=1 ;;\n        --purge) PURGE=1 ;;\n        --yes|-y) ASSUME_YES=1 ;;\n        --sessions-dir) SESSIONS_DIR=\"$2\"; shift ;;\n        --access-log) ACCESS_LOG=\"$2\"; shift ;;\n        --help|-h)\n            echo \"Usage: $0 &#091;--verbose] &#091;--purge &#091;--yes]] &#091;--sessions-dir DIR] &#091;--access-log FILE]\"\n            exit 0 ;;\n        *) echo \"Unknown argument: $1\" &gt;&amp;2; exit 1 ;;\n    esac\n    shift\ndone\n\nFINDINGS=()\nFINDING_SESSIONS=()\nFINDING_TOKENS=()\nFINDING_SEVERITIES=()\nCOUNT_CRITICAL=0\nCOUNT_WARNING=0\nCOUNT_INFO=0\nCOUNT_ATTEMPT=0\n\nget_field() { grep \"^${2}=\" \"$1\" | head -1 | cut -d= -f2-; }\nhr() { echo \"    ----------------------------------------------------------------\"; }\n\ndump_session() {\n    local session_file=\"$1\" token_val=\"$2\" session_name preauth_file\n    session_name=$(basename \"$session_file\")\n    preauth_file=\"$SESSIONS_DIR\/preauth\/$session_name\"\n    hr\n    echo \"    SESSION DUMP: $session_file\"\n    hr\n    echo \"    File metadata:\"\n    ls -la \"$session_file\" 2&gt;\/dev\/null | sed 's\/^\/      \/'\n    echo\n    echo \"    Full session contents:\"\n    sed 's\/^\/      \/' \"$session_file\"\n    echo\n    if &#091; -f \"$preauth_file\" ]; then\n        echo \"    Matching pre-auth file: $preauth_file\"\n        ls -la \"$preauth_file\" 2&gt;\/dev\/null | sed 's\/^\/      \/'\n        echo \"    Pre-auth contents:\"\n        sed 's\/^\/      \/' \"$preauth_file\"\n        echo\n    fi\n    if &#091; -n \"$token_val\" ] &amp;&amp; &#091; -r \"$ACCESS_LOG\" ]; then\n        echo \"    Access log hits for token '$token_val':\"\n        grep -aF -- \"$token_val\" \"$ACCESS_LOG\" | sed 's\/^\/      \/' || echo \"      (none)\"\n        echo\n    fi\n    hr\n}\n\nreport_finding() {\n    local severity=\"$1\" session_file=\"$2\" token_val=\"$3\" message=\"$4\"\n    local sev_rank=0\n    case \"$severity\" in CRITICAL) sev_rank=3 ;; WARNING) sev_rank=2 ;; ATTEMPT) sev_rank=1 ;; INFO) sev_rank=0 ;; esac\n    local i found=0 prev_sev prev_rank\n    for i in \"${!FINDING_SESSIONS&#091;@]}\"; do\n        if &#091; \"${FINDING_SESSIONS&#091;$i]}\" = \"$session_file\" ]; then\n            found=1\n            prev_sev=\"${FINDING_SEVERITIES&#091;$i]}\"\n            case \"$prev_sev\" in CRITICAL) prev_rank=3 ;; WARNING) prev_rank=2 ;; ATTEMPT) prev_rank=1 ;; INFO) prev_rank=0 ;; esac\n            if &#091; \"$sev_rank\" -le \"$prev_rank\" ]; then return; fi\n            FINDING_SEVERITIES&#091;$i]=\"$severity\"\n            &#091; -n \"$token_val\" ] &amp;&amp; FINDING_TOKENS&#091;$i]=\"$token_val\"\n            local j\n            for j in \"${!FINDINGS&#091;@]}\"; do\n                local entry=\"${FINDINGS&#091;$j]}\" entry_sev entry_file\n                entry_sev=\"${entry%%|*}\"\n                entry_file=\"${entry#*|}\"; entry_file=\"${entry_file%%|*}\"\n                if &#091; \"$entry_file\" = \"$session_file\" ] &amp;&amp; &#091; \"$entry_sev\" = \"$prev_sev\" ]; then\n                    FINDINGS&#091;$j]=\"${severity}|${session_file}|${message}\"; break\n                fi\n            done\n            case \"$prev_sev\" in CRITICAL) COUNT_CRITICAL=$((COUNT_CRITICAL-1)) ;; WARNING) COUNT_WARNING=$((COUNT_WARNING-1)) ;; ATTEMPT) COUNT_ATTEMPT=$((COUNT_ATTEMPT-1)) ;; INFO) COUNT_INFO=$((COUNT_INFO-1)) ;; esac\n            break\n        fi\n    done\n    if &#091; \"$found\" -eq 0 ]; then\n        FINDING_SESSIONS+=(\"$session_file\")\n        FINDING_TOKENS+=(\"$token_val\")\n        FINDING_SEVERITIES+=(\"$severity\")\n        FINDINGS+=(\"${severity}|${session_file}|${message}\")\n    fi\n    case \"$severity\" in CRITICAL) COUNT_CRITICAL=$((COUNT_CRITICAL+1)) ;; WARNING) COUNT_WARNING=$((COUNT_WARNING+1)) ;; ATTEMPT) COUNT_ATTEMPT=$((COUNT_ATTEMPT+1)) ;; INFO) COUNT_INFO=$((COUNT_INFO+1)) ;; esac\n    echo \"&#091;${severity}] ${message}: ${session_file}\"\n}\n\ncheck_token_denied_with_injected_token() {\n    local session_file=\"$1\"\n    grep -q '^token_denied=' \"$session_file\" || return\n    grep -q '^cp_security_token=' \"$session_file\" || return\n    local token_val external_auth internal_auth hasroot tfa used\n    token_val=$(get_field \"$session_file\" cp_security_token)\n    external_auth=$(get_field \"$session_file\" successful_external_auth_with_timestamp)\n    internal_auth=$(get_field \"$session_file\" successful_internal_auth_with_timestamp)\n    hasroot=$(get_field \"$session_file\" hasroot)\n    tfa=$(get_field \"$session_file\" tfa_verified)\n    used=\"\"\n    if &#091; -r \"$ACCESS_LOG\" ]; then\n        used=$(grep -aF -- \"$token_val\" \"$ACCESS_LOG\" | grep -m1 \" 200 \")\n    fi\n    local has_auth_markers=0\n    if &#091; -n \"$external_auth\" ] || &#091; -n \"$internal_auth\" ] || &#091; \"$hasroot\" = \"1\" ] || &#091; \"$tfa\" = \"1\" ] || &#091; -n \"$used\" ]; then\n        has_auth_markers=1\n    fi\n    if grep -q '^origin_as_string=.*method=badpass' \"$session_file\"; then\n        if &#091; \"$has_auth_markers\" -eq 1 ]; then\n            report_finding CRITICAL \"$session_file\" \"$token_val\" \"Exploitation artifact - token_denied with injected cp_security_token (badpass origin, token used)\"\n        else\n            if grep -q '^pass=' \"$session_file\"; then return; fi\n            report_finding INFO \"$session_file\" \"$token_val\" \"Possible injected session (badpass origin, no usage observed)\"\n        fi\n    elif grep -q '^origin_as_string=.*method=handle_form_login' \"$session_file\" || \\\n         grep -q '^origin_as_string=.*method=create_user_session' \"$session_file\" || \\\n         grep -q '^origin_as_string=.*method=handle_auth_transfer' \"$session_file\"; then\n        return\n    else\n        report_finding WARNING \"$session_file\" \"$token_val\" \"Suspicious session with token_denied + cp_security_token (non-badpass origin)\"\n    fi\n}\n\ncheck_preauth_with_auth_attrs() {\n    local session_file=\"$1\" session_name preauth_file\n    session_name=$(basename \"$session_file\")\n    preauth_file=\"$SESSIONS_DIR\/preauth\/$session_name\"\n    &#091; -f \"$preauth_file\" ] || return\n    local marker\n    if grep -qE '^successful_external_auth_with_timestamp=' \"$session_file\"; then\n        marker=\"successful_external_auth_with_timestamp\"\n    elif grep -qE '^successful_internal_auth_with_timestamp=' \"$session_file\"; then\n        marker=\"successful_internal_auth_with_timestamp\"\n    else\n        return\n    fi\n    report_finding CRITICAL \"$session_file\" \"$(get_field \"$session_file\" cp_security_token)\" \"Injected session - ${marker} present in pre-auth session\"\n}\n\ncheck_tfa_with_bad_origin() {\n    local session_file=\"$1\"\n    grep -qE '^tfa_verified=1$' \"$session_file\" || return\n    grep -q '^origin_as_string=.*method=handle_form_login' \"$session_file\" &amp;&amp; return\n    grep -q '^origin_as_string=.*method=create_user_session' \"$session_file\" &amp;&amp; return\n    grep -q '^origin_as_string=.*method=handle_auth_transfer' \"$session_file\" &amp;&amp; return\n    report_finding WARNING \"$session_file\" \"$(get_field \"$session_file\" cp_security_token)\" \"Session with tfa_verified=1 but suspicious origin\"\n}\n\ncheck_malformed_session_line() {\n    local session_file=\"$1\"\n    grep -nE -v '^&#091;A-Za-z_]&#091;A-Za-z0-9_]*=|^&#091;&#091;:space:]]*$' \"$session_file\" &gt;\/dev\/null 2&gt;&amp;1 || return\n    report_finding CRITICAL \"$session_file\" \"$(get_field \"$session_file\" cp_security_token)\" \"Malformed session line(s) detected (not key=value - newline injection footprint)\"\n}\n\ncheck_badpass_with_auth_markers() {\n    local session_file=\"$1\"\n    grep -q '^origin_as_string=.*method=badpass' \"$session_file\" || return\n    local markers=()\n    grep -q '^successful_external_auth_with_timestamp=' \"$session_file\" &amp;&amp; markers+=(\"successful_external_auth_with_timestamp\")\n    grep -q '^successful_internal_auth_with_timestamp=' \"$session_file\" &amp;&amp; markers+=(\"successful_internal_auth_with_timestamp\")\n    grep -qE '^hasroot=1$' \"$session_file\" &amp;&amp; markers+=(\"hasroot=1\")\n    grep -qE '^tfa_verified=1$' \"$session_file\" &amp;&amp; markers+=(\"tfa_verified=1\")\n    &#091; \"${#markers&#091;@]}\" -gt 0 ] || return\n    local joined; joined=$(IFS=,; echo \"${markers&#091;*]}\")\n    report_finding CRITICAL \"$session_file\" \"$(get_field \"$session_file\" cp_security_token)\" \"badpass origin combined with authenticated markers ($joined) - impossible in benign flow\"\n}\n\ncheck_failed_exploit_attempt() {\n    local session_file=\"$1\"\n    grep -q '^origin_as_string=.*method=badpass' \"$session_file\" || return\n    grep -q '^token_denied=' \"$session_file\" || return\n    grep -q '^successful_internal_auth_with_timestamp=' \"$session_file\" &amp;&amp; return\n    grep -q '^successful_external_auth_with_timestamp=' \"$session_file\" &amp;&amp; return\n    grep -q '^pass=' \"$session_file\" || return\n    report_finding ATTEMPT \"$session_file\" \"$(get_field \"$session_file\" cp_security_token)\" \"Failed exploit attempt (badpass origin, token_denied, no auth markers, anomalous pass= line)\"\n}\n\nscan_sessions() {\n    local session_file\n    while IFS= read -r -d '' session_file; do\n        check_token_denied_with_injected_token \"$session_file\"\n        check_preauth_with_auth_attrs \"$session_file\"\n        check_tfa_with_bad_origin \"$session_file\"\n        check_malformed_session_line \"$session_file\"\n        check_badpass_with_auth_markers \"$session_file\"\n        check_failed_exploit_attempt \"$session_file\"\n    done &lt; &lt;(find \"$SESSIONS_DIR\/raw\" -type f -print0 2&gt;\/dev\/null)\n}\n\nprint_summary() {\n    local total=$((COUNT_CRITICAL+COUNT_WARNING+COUNT_INFO+COUNT_ATTEMPT))\n    echo\n    echo \"=================================================================\"\n    echo \"                       SCAN SUMMARY\"\n    echo \"=================================================================\"\n    echo \"  CRITICAL findings: $COUNT_CRITICAL\"\n    echo \"  WARNING  findings: $COUNT_WARNING\"\n    echo \"  ATTEMPT  findings: $COUNT_ATTEMPT\"\n    echo \"  INFO     findings: $COUNT_INFO\"\n    echo \"  Total            : $total\"\n    echo \"-----------------------------------------------------------------\"\n    if &#091; \"$total\" -eq 0 ]; then echo \"&#091;+] No indicators of compromise found.\"; return; fi\n    if &#091; \"$PURGE\" -eq 1 ] &amp;&amp; &#091; \"$ASSUME_YES\" -ne 1 ]; then\n        if &#091; ! -t 0 ]; then\n            echo \"&#091;ERROR] --purge requires --yes when stdin is not a TTY\" &gt;&amp;2; exit 64\n        fi\n        echo\n        echo \"About to delete ${#FINDING_SESSIONS&#091;@]} session file(s) plus matching preauth markers.\"\n        local confirm=\"\"\n        read -r -p \"Type 'yes' to confirm: \" confirm\n        if &#091; \"$confirm\" != \"yes\" ]; then echo \"&#091;+] Aborted; no files deleted.\"; PURGE=0; fi\n    fi\n    local i session token severity message found=0\n    for i in \"${!FINDING_SESSIONS&#091;@]}\"; do\n        session=\"${FINDING_SESSIONS&#091;$i]}\"\n        token=\"${FINDING_TOKENS&#091;$i]}\"\n        severity=\"${FINDING_SEVERITIES&#091;$i]}\"\n        found=0\n        for entry in \"${FINDINGS&#091;@]}\"; do\n            local entry_sev entry_file entry_msg\n            IFS='|' read -r entry_sev entry_file entry_msg &lt;&lt;&lt; \"$entry\"\n            if &#091; \"$entry_file\" = \"$session\" ] &amp;&amp; &#091; \"$entry_sev\" = \"$severity\" ]; then\n                message=\"$entry_msg\"; found=1; break\n            fi\n        done\n        echo\n        echo \"=================================================================\"\n        echo \"  SESSION: $session\"\n        echo \"=================================================================\"\n        echo \"  Findings:\"\n        if &#091; \"$found\" -eq 1 ]; then printf \"    &#091;%-8s] %s\\n\" \"$severity\" \"$message\"\n        else printf \"    &#091;%-8s] %s\\n\" \"$severity\" \"(no message found)\"; fi\n        echo\n        if &#091; \"$VERBOSE\" -eq 1 ]; then dump_session \"$session\" \"$token\"; fi\n        if &#091; \"$PURGE\" -eq 1 ]; then\n            echo \"    &#091;ACTION] Deleting session file: $session\"\n            rm -f -- \"$session\"\n            local preauth_marker=\"$SESSIONS_DIR\/preauth\/$(basename \"$session\")\"\n            if &#091; -e \"$preauth_marker\" ]; then\n                echo \"    &#091;ACTION] Deleting preauth marker: $preauth_marker\"\n                rm -f -- \"$preauth_marker\"\n            fi\n        fi\n    done\n    if &#091; \"$COUNT_CRITICAL\" -gt 0 ] || &#091; \"$COUNT_WARNING\" -gt 0 ]; then\n        echo\n        echo \"&#091;!] INDICATORS OF COMPROMISE DETECTED - IMMEDIATE ACTION REQUIRED\"\n        echo \"    1. Purge all affected sessions\"\n        echo \"    2. Force password reset for root and all WHM users\"\n        echo \"    3. Audit \/var\/log\/wtmp and WHM access logs for unauthorized access\"\n        echo \"    4. Check for persistence mechanisms (cron, SSH keys, backdoors)\"\n    fi\n}\n\nif &#091; ! -d \"$SESSIONS_DIR\/raw\" ]; then\n    echo \"&#091;ERROR] Sessions directory not found: $SESSIONS_DIR\/raw\" &gt;&amp;2\n    echo \"        Pass --sessions-dir DIR to point at a different location\" &gt;&amp;2\n    exit 64\nfi\n\necho \"&#091;*] Scanning session files for injection indicators...\"\nscan_sessions\nprint_summary\n\nif &#091; \"$COUNT_CRITICAL\" -gt 0 ] || &#091; \"$COUNT_WARNING\" -gt 0 ]; then exit 2\nelif &#091; \"$COUNT_ATTEMPT\" -gt 0 ] || &#091; \"$COUNT_INFO\" -gt 0 ]; then exit 1\nfi\nexit 0<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"if-the-server-is-confirmed-compromised\">If the Server Is Confirmed Compromised<\/h3>\n\n\n<p>If the detection script returns CRITICAL or WARNING findings, the server should be treated as root-compromised until proven otherwise.<\/p>\n\n\n\n<p><strong>Immediate actions:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Purge all flagged session files (use <code>--purge --yes<\/code> with the detection script).<\/li>\n\n\n\n<li>Force a password reset for <code>root<\/code> and all WHM-level users.<\/li>\n\n\n\n<li>Audit <code>\/var\/log\/wtmp<\/code> and WHM access logs for unauthorized logins.<\/li>\n\n\n\n<li>Check for persistence mechanisms: cron jobs, added SSH authorized keys, webshells, and any new system users.<\/li>\n\n\n\n<li>If you cannot confirm the scope of the compromise, migrate all cPanel accounts to a clean server or reinstall the OS and restore from a known-good backup.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h2 class=\"wp-block-heading\" id=\"cve202631431-linux-kernel-copy-fail-local-privilege-escalation\">CVE-2026-31431 \u2014 Linux Kernel &#8220;Copy Fail&#8221; Local Privilege Escalation<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"what-this-vulnerability-does\">What This Vulnerability Does<\/h3>\n\n\n<p>CVE-2026-31431, nicknamed &#8220;Copy Fail,&#8221; is a local privilege escalation vulnerability in the Linux kernel. Any unprivileged local user \u2014 including users inside containers \u2014 can use it to obtain a root shell. It was introduced with kernel 4.14 and affects all major Linux distributions that have shipped a kernel in that range since 2017, including Ubuntu, Amazon Linux, RHEL, and SUSE.<\/p>\n\n\n\n<p>The flaw is in the <code>authencesn<\/code> cryptographic module (<code>algif_aead.c<\/code>), reachable via the <code>AF_ALG<\/code> socket interface combined with the <code>splice()<\/code> system call. Unlike earlier kernel privilege escalation exploits, it requires no race condition, no kernel offsets, no recompilation, and no compiled payload. A 732-byte Python script using only standard library modules achieves reliable root on affected systems.<\/p>\n\n\n\n<p>The mechanism: by splicing a file into a pipe and feeding it into an <code>AF_ALG<\/code> socket, the kernel&#8217;s page cache pages are placed into a writable destination scatterlist. The <code>authencesn<\/code> algorithm then writes 4 bytes past the declared output boundary directly into chained page cache pages. Because the kernel never marks those corrupted pages dirty for writeback, the on-disk file is untouched \u2014 standard file integrity tools that check on-disk checksums will not detect the modification. The attacker then executes the corrupted in-memory version of a setuid binary (such as <code>\/usr\/bin\/su<\/code>) to obtain a root shell.<\/p>\n\n\n\n<p>This vulnerability also functions as a Kubernetes container escape primitive, since the page cache is shared across all processes on a host, including across container boundaries.<\/p>\n\n\n\n<p><strong>Confirmed affected distributions:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Distribution<\/th><th>Kernel Version Tested<\/th><\/tr><\/thead><tbody><tr><td>Ubuntu 24.04 LTS<\/td><td>6.17.0-1007-aws<\/td><\/tr><tr><td>Amazon Linux 2023<\/td><td>6.18.8-9.213.amzn2023<\/td><\/tr><tr><td>RHEL 14.3<\/td><td>6.12.0-124.45.1.el10_1<\/td><\/tr><tr><td>SUSE 16<\/td><td>6.12.0-160000.9-default<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"how-to-patch-cve202631431\">How to Patch CVE-2026-31431<\/h3>\n\n\n<p><strong>Step 1 \u2014 Apply the kernel update through your distribution&#8217;s package manager.<\/strong><\/p>\n\n\n\n<p>On Debian\/Ubuntu:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt update &amp;&amp; apt upgrade -y linux-image-$(uname -r)\nreboot<\/code><\/pre>\n\n\n\n<p>On RHEL\/AlmaLinux\/Rocky Linux:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf update kernel -y\nreboot<\/code><\/pre>\n\n\n\n<p>On Amazon Linux 2023:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf update kernel -y\nreboot<\/code><\/pre>\n\n\n\n<p>On SUSE:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zypper update -y kernel-default\nreboot<\/code><\/pre>\n\n\n\n<p><strong>Step 2 \u2014 Verify the kernel version after reboot:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uname -r<\/code><\/pre>\n\n\n\n<p>Cross-reference the output against your distribution&#8217;s security advisory to confirm the patched build is running.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h3 class=\"wp-block-heading\" id=\"immediate-mitigation-if-you-cannot-reboot-now\">Immediate Mitigation (If You Cannot Reboot Now)<\/h3>\n\n\n<p>Disable the <code>algif_aead<\/code> kernel module to remove the attack surface without rebooting:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo \"install algif_aead \/bin\/false\" &gt; \/etc\/modprobe.d\/disable-algif-aead.conf\nrmmod algif_aead 2&gt;\/dev\/null<\/code><\/pre>\n\n\n\n<p>This prevents the module from loading or being loaded on demand. The second command unloads it if it is currently loaded. The change persists across reboots via the <code>modprobe.d<\/code> configuration.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong> This mitigation blocks the exploit path but does not fix the underlying kernel vulnerability. Apply the kernel update and reboot as soon as your maintenance window allows.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h2 class=\"wp-block-heading\" id=\"prevention\">Prevention<\/h2>\n\n\n<p>These two vulnerabilities highlight two recurring issues worth addressing systematically.<\/p>\n\n\n\n<p><strong>For cPanel servers:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep automatic cPanel updates enabled. If you have pinned a specific version or disabled updates, document why and put a recurring review date on it. Pinned versions will not receive security patches automatically.<\/li>\n\n\n\n<li>Restrict access to cPanel ports (2083, 2087, 2095, 2096) at the firewall to known IP ranges where operationally possible.<\/li>\n\n\n\n<li>Set up WHM&#8217;s Two-Factor Authentication for all reseller and root-level accounts.<\/li>\n<\/ul>\n\n\n\n<p><strong>For Linux servers:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Apply kernel updates within your defined patch SLA. For critical kernel CVEs, that window should be 24\u201372 hours with a mitigation applied immediately.<\/li>\n\n\n\n<li>Use a file integrity monitoring tool (AIDE, Wazuh, or similar) configured to check in-memory state, not just on-disk checksums, where supported.<\/li>\n\n\n\n<li>Limit local user accounts on shared systems. CVE-2026-31431 requires unprivileged local access \u2014 the fewer local users, the smaller the attack surface.<\/li>\n\n\n\n<li>On container platforms, ensure kernel updates are applied to the host node, not just inside containers.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n<p>CVE-2026-41940 is a remotely exploitable authentication bypass in cPanel affecting all versions since 11.40 \u2014 update via <code>\/scripts\/upcp --force<\/code> and run the detection script to confirm no exploitation has occurred. CVE-2026-31431 is a locally exploitable kernel privilege escalation affecting virtually every Linux system since 2017 \u2014 update the kernel and disable <code>algif_aead<\/code> as an immediate stopgap.<\/p>\n\n\n\n<p>If you are running a Veeble <a href=\"https:\/\/veeble.com\/cpanel-hosting\/\" target=\"_blank\" rel=\"noreferrer noopener\">cPanel Hosting<\/a> or <a href=\"https:\/\/veeble.com\/vps-hosting\/\" target=\"_blank\" rel=\"noreferrer noopener\">VPS<\/a> plan and need assistance applying these patches, open a support ticket from your Veeble Client Zone and our team will help you through the update process.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"references\">References<\/h2>\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/support.cpanel.net\/hc\/en-us\/articles\/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026\" target=\"_blank\" rel=\"noreferrer noopener\">Security: CVE-2026-41940 &#8211; cPanel &amp; WHM \/ WP2 Security Update 04\/28\/2026<\/a> \u2014 Official cPanel advisory with patched versions, detection script, and mitigation steps.<\/li>\n\n\n\n<li><a href=\"https:\/\/cybersecuritynews.com\/linux-kernel-0-day-copy-fail\/\" target=\"_blank\" rel=\"noreferrer noopener\">Linux Kernel 0-Day &#8220;Copy Fail&#8221; Roots Every Major Distribution Since 2017<\/a> \u2014 Full technical disclosure of CVE-2026-31431, including exploit mechanism and affected distributions.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Two critical security vulnerabilities were publicly disclosed in late April 2026 that affect a large portion of Linux-based servers, including cPanel\/WHM installations and any [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":9076,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1,4,9,5],"tags":[34,73,67,71,68,72,35],"class_list":["post-9075","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","category-cpanel","category-firewallsecurity","category-linux","tag-cpanel","tag-kernel","tag-linux","tag-security","tag-vps","tag-vulnerability","tag-whm"],"uagb_featured_image_src":{"full":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image.png",1210,640,false],"thumbnail":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image-150x150.png",150,150,true],"medium":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image-300x159.png",300,159,true],"medium_large":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image-768x406.png",768,406,true],"large":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image-1024x542.png",1024,542,true],"1536x1536":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image.png",1210,640,false],"2048x2048":["https:\/\/www.veeble.com\/kb\/wp-content\/uploads\/2026\/05\/security_advisory_featured_image.png",1210,640,false]},"uagb_author_info":{"display_name":"Nasarul Naseer","author_link":"https:\/\/www.veeble.com\/kb\/author\/nasarulnaseer\/"},"uagb_comment_info":0,"uagb_excerpt":"Two critical security vulnerabilities were publicly disclosed in late April 2026 that affect a large portion of Linux-based servers, including cPanel\/WHM installations and any [&hellip;]","_links":{"self":[{"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/posts\/9075","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/comments?post=9075"}],"version-history":[{"count":5,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/posts\/9075\/revisions"}],"predecessor-version":[{"id":9082,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/posts\/9075\/revisions\/9082"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/media\/9076"}],"wp:attachment":[{"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/media?parent=9075"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/categories?post=9075"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.veeble.com\/kb\/wp-json\/wp\/v2\/tags?post=9075"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}