#StackBounty: #javascript #security #promise #cors #indexeddb Nested cross-origin iframes for secure user-configurable javascript tools

Bounty: 50

Context

I’m trying to build a system in which a tool (the Client) will generate a header to be used as part of an HTTP request from the user’s browser.

  • The user should be able to choose their own implementation of the Client.
  • The user should not have to install a plugin or extension to their browser.

Summary

A 3rd party will serve a small wrapper (the Shim) which will keep track of where to load the Client from. It will store this in the browser’s IndexedDB under its own origin.

The Shim and the Client will be loaded in iframes of their own origin, so that they (and the Host website) can only access each-other’s functionality through the defined methods (based on MessageChannels and postMessage() calls).

Parties, Prerogatives, and Restrictions

  • The Host website is at www.host.com.
    • They shouldn’t be able to know what implementation of the Client is in use,
    • nor should they be able to affect the Client in any way except by requesting header values.
    • (As it stands the Host is able to suggest a default Client; when I actually build the set-Client-address tool for the Shim, I’ll get rid of this.)
  • The Shim is served from www.shim.com.
    • They’re assumed to be trustworthy in the sense that people know what code they’re serving. (Even this isn’t ideal; subresource integrity checks would be great if they worked on iframes.)
    • Their code obviously knows who the Client is, and can see the requests and responses as they’re passed back and forth, but all of this stays on the user’s machine as far as the Shim is concerned.
    • They can only affect the client by requesting the header values.
  • The Client is served from www.client.com.
    • At present this is being passed in as a default, but in practice it should have been saved into the IndexedDB on the user’s machine belonging to the www.shim.com origin. (It will get put there by some other tool I haven’t written yet.)
    • It’s fine for the client to know who the Host is; I may even add that as an explicit property of each request.
  • There’s an image or some other resource that the Host wants to load on their page, but requesting that image requires a custom Receitps-Receipt HTTPS header, the value for which needs to come from the Client. Let’s suppose this image is at https://www.target.com/target.png, but it could just as easily be in the same origin as the Host website itself.

Code

www.host.com/host.html

<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <title>Host</title>
    https://www.shim.com/shim.js
    
        _page_loaded = ()=>{
            window.FOTR.fetch(
                new Request('https://www.target.com/target.png')
                ).then((response)=>{
                    return response.blob();
                }).then((b)=>{
                    const i = window.document.createElement('img');
                    i.src = URL.createObjectURL(b);
                    document.getElementById("testTarget").appendChild(i);
                });
        };
    
  </head>
  <body onload="_page_loaded()">
    <h1>Host</h1>
    <p>Lorem ipsum dolor sit amet.</p>
    <p id="testTarget"></p>
    <p>Text continues.</p>
  </body>
</html>

www.shim.com/shim.js

((toolName)=>{
    if(typeof window[toolName] === 'undefined'){

        const loaderUtilities = { //This is exactly the same between shim.html and shim.js.

            domReady: new Promise((resolve, reject)=>{
                if(document.readyState === "loading"){
                    document.addEventListener('DOMContentLoaded', resolve);
                }
                else{
                    resolve();
                }   // add error handler?
            }),

            origin: (uri)=>{
                const parser = window.document.createElement('a');
                parser.href = uri;
                return `${parser.protocol}//${parser.host}`;
            },

            loadTool: (uri)=>{
                return new Promise((resolve, reject)=>{
                    const tag = window.document.createElement('iframe');
                    tag.src = uri;
                    tag.width = 0;
                    tag.height = 0;
                    tag.style = "visibility: hidden";
                    window.addEventListener("message",
                        (e)=>{
                            if(e.origin == loaderUtilities.origin(uri)){ //is it possible to refine the origin check?
                                resolve(e.data);
                            }
                        }, 
                        false);
                    loaderUtilities.domReady.then(()=>{
                        document.body.appendChild(tag);
                    });
                });   // add error handler?
            },

            requestOverPort: (port, resource)=>{
                return new Promise((resolve, reject)=>{
                    const disposableChannel = new MessageChannel();
                    disposableChannel.port1.onmessage = (e)=>{
                        resolve(e.data);
                        disposableChannel.port1.close();
                    };
                    port.postMessage(
                        {
                            resource: resource,
                            port: disposableChannel.port2
                        },
                        [disposableChannel.port2]);
                });
            },
        };

        const defaultClient = document.currentScript.getAttribute("data-default") || '';
        const gotClientPort = loaderUtilities.loadTool(`https://www.shim.com/shim.html#${defaultClient}`);

        window[toolName] = {
            fetch: (request)=>{
                return gotClientPort
                    .then((clientPort)=>{
                        return loaderUtilities.requestOverPort(
                            clientPort,
                            {
                                url: request.url,
                                method: request.method
                            });
                    })
                    .then((receipt)=>{
                        return window.fetch(
                            request,
                            {
                                headers: new Headers({ 'Receipts-Receipt': receipt }),
                            });
                    });
            }
        }

    }
})(document.currentScript.getAttribute("data-name") || "FOTR")

www.shim.com/shim.html

<!DOCTYPE html>
<html>
  <head>
    <title>The FOTR Shim</title>
    <meta charset="UTF-8">
    

        const loaderUtilities = { //This is exactly the same between shim.html and shim.js.

            domReady: new Promise((resolve, reject)=>{
                if(document.readyState === "loading"){
                    document.addEventListener('DOMContentLoaded', resolve);
                }
                else{
                    resolve();
                }   // add error handler?
            }),

            origin: (uri)=>{
                const parser = window.document.createElement('a');
                parser.href = uri;
                return `${parser.protocol}//${parser.host}`;
            },

            loadTool: (uri)=>{
                return new Promise((resolve, reject)=>{
                    const tag = window.document.createElement('iframe');
                    tag.src = uri;
                    tag.width = 0;
                    tag.height = 0;
                    tag.style = "visibility: hidden";
                    window.addEventListener("message",
                        (e)=>{
                            if(e.origin == loaderUtilities.origin(uri)){ //is it possible to refine the origin check?
                                resolve(e.data);
                            }
                        }, 
                        false);
                    loaderUtilities.domReady.then(()=>{
                        document.body.appendChild(tag);
                    });
                });   // add error handler?
            },

            requestOverPort: (port, resource)=>{
                return new Promise((resolve, reject)=>{
                    const disposableChannel = new MessageChannel();
                    disposableChannel.port1.onmessage = (e)=>{
                        resolve(e.data);
                        disposableChannel.port1.close();
                    };
                    port.postMessage(
                        {
                            resource: resource,
                            port: disposableChannel.port2
                        },
                        [disposableChannel.port2]);
                });
            },
        };

        const indexedDBPromise = (request)=>{
            return new Promise(
                (resolve, reject)=>{
                    request.onsuccess = (e)=>{
                        resolve(e.target.result);
                    };
                    request.onerror = (e)=>{
                        reject(e.target.error);
                    };
                });
        };

        const defaultClient = window.location.href.split('#')[1] || '';
        const objectStoreName = "chosen_clients";

        const openDB = window.indexedDB.open("FOTR", 1);
        openDB.onupgradeneeded = (e)=>{
            e.target.result.createObjectStore(objectStoreName);
        };

        indexedDBPromise(openDB)
            .then(
                (db)=>{
                    const tx = db.transaction(objectStoreName, "readonly");
                    tx.oncomplete = ()=>{
                        db.close();
                    };
                    return indexedDBPromise(tx.objectStore(objectStoreName).getAll());
                })//handle open-db error?
            .then(
                (db_result)=>{
                    const clientURI = db_result.uri || defaultClient;
                    return loaderUtilities.loadTool(clientURI);
                })//handle db-read error?
            .then(
                (innerPort)=>{
                    const outerChannel = new MessageChannel();
                    outerChannel.port1.onmessage = (e)=>{
                        const newPort = e.data.port;
                        const request = e.data.resource;
                        console.log(`Forwarding request for [${request.method}]${request.url}.`);
                        loaderUtilities.requestOverPort(innerPort, request)
                            .then((response)=>{
                                console.log(`Forwarding requested value "${response}" for [${request.method}]${request.url}`);
                                newPort.postMessage(response);
                                newPort.close();
                            });
                    };
                    window.parent.postMessage(outerChannel.port2, '*', [outerChannel.port2]);
                });//handle tool-load error?

    
  </head>
  <body></body>
</html>

www.client.com/client.html

<!DOCTYPE html>
<html>
  <head>
    <title>The stupidest client.</title>
    <meta charset="UTF-8">
    
      const pipe = new MessageChannel();
      const work = (request)=>{
          return "555";
      };
      pipe.port1.onmessage = (e)=>{
          const newPort = e.data.port;
          const request = e.data.resource;
          const response = work(request);
          console.log(`Receipt requested for [${request.method}]${request.url}; returning "${response}"`);
          newPort.postMessage(response);
          newPort.close();
      };
      window.parent.postMessage(pipe.port2, '*', [pipe.port2]); //should I be more restrictive of the recipient?
    
  </head>
  <body</body>
</html>

Comments

  • The above works, in the sense that the image loads and the request for that image has the correct custom header.
  • The Client presented is just a test rig that always returns ‘555’.

Question

Mostly I’m concerned with the security and usability of the Shim.

  • Is the usage of iframes, Promises, indexedDB, and inter-frame messaging trustworthy? Am I doing them correctly?
  • Does this Shim system provide the protections described in “Parties, Prerogatives, and Restrictions”, insofar as any modern web-browser is secure?
  • How should I approach error-handling?
  • What else should I do to test this system?


Get this bounty!!!

#StackBounty: #beginner #php #security #authentication #codeigniter Codeigniter 3 Registration and Login System

Bounty: 50

I am working on a basic blog application in Codeigniter 3.1.8 and Bootstrap 4.

The application allows Registration and Login. I have concerns about the security level of the Registration system I have put together.

The Register controller:

class Register extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
    }

    public function index() {
        $data = $this->Static_model->get_static_data();
        $data['pages'] = $this->Pages_model->get_pages();
        $data['tagline'] = 'Want to write for ' . $data['site_title'] . '? Create an account.';
        $data['categories'] = $this->Categories_model->get_categories();

        $this->form_validation->set_rules('first_name', 'First name', 'required');
        $this->form_validation->set_rules('last_name', 'Last name', 'required');
        $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
        $this->form_validation->set_rules('password', 'Password', 'required|min_length[6]');
        $this->form_validation->set_rules('cpassword', 'Confirm password', 'required|matches[password]');
        $this->form_validation->set_rules('terms', 'Terms and Conditions', 'required', array('required' => 'You have to accept the Terms and Conditions'));
        $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

        // If validation fails
        if ($this->form_validation->run() === FALSE) {
            $this->load->view('partials/header', $data);
            $this->load->view('auth/register');
            $this->load->view('partials/footer');
        } else {
            // If the provided email does not already
            // exist in the authors table, register user
            if (!$this->Usermodel->email_exists()) {
                // Encrypt the password
                $enc_password = md5($this->input->post('password'));

                // Give the first author admin privileges
                if ($this->Usermodel->get_num_rows() < 1) {
                    $active = 1;
                    $is_admin = 1;
                } else {
                    $active = 0;
                    $is_admin = 0;
                }

                // Register user
                $this->Usermodel->register_user($enc_password, $active, $is_admin);

                if ($this->Usermodel->get_num_rows() == 1) {
                    $this->session->set_flashdata('user_registered', "You are now registered as an admin. You can sign in");
                } else {
                    $this->session->set_flashdata('user_registered', "You are now registered. Your account needs the admin's aproval before you can sign in.");
                }
                redirect('login');
            } else {
                // The user is already registered
                $this->session->set_flashdata('already_registered', "The email you provided already exists in our database. Please login.");
                redirect('login');
            }
        }
    }
}

The Usermodel model:

class Usermodel extends CI_Model {

    public function email_exists() {    
        $query = $this->db->get_where('authors', ['email' => $this->input->post('email')]);
        return $query->num_rows() > 0;
    }

    public function get_num_rows() {
        $query = $this->db->get('authors');
        return $query->num_rows(); 
    }

    public function getAuthors(){
        $query = $this->db->get('authors');
        return $query->result();
    }

    public function deleteAuthor($id) {
        return $this->db->delete('authors', array('id' => $id));
    }

    public function activateAuthor($id) {
        $author = null;
        $updateQuery = $this->db->where(['id' => $id, 'is_admin' => 0])->update('authors', array('active' => 1));
        if ($updateQuery !== false) {
        $authorQuery = $this->db->get_where('authors', array('id' => $id));
        $author = $authorQuery->row();
        }
        return $author;
    }

    public function deactivateAuthor($id) {
        $author = null;
        $updateQuery = $this->db->where(['id' => $id, 'is_admin' => 0])->update('authors', array('active' => 0));
        if ($updateQuery !== false) {
            $authorQuery = $this->db->get_where('authors', array('id' => $id));
            $author = $authorQuery->row();
        }
        return $author;
    }

    public function register_user($enc_password, $active, $is_admin) {
        // User data
        $data = [
            'first_name' => $this->input->post('first_name'),
            'last_name' => $this->input->post('last_name'),
            'email' => $this->input->post('email'),
            'password' => $enc_password,
            'register_date' => date('Y-m-d H:i:s'),
            'active' => $active,
            'is_admin' => $is_admin
        ];
        return $this->db->insert('authors', $data);
    }

    public function user_login($email, $password)
    {
        $query = $this->db->get_where('authors', ['email' => $email, 'password' => md5($password)]);
        return $query->row();
    }
}

UPDATE:

I have decided to post the login() method, from the Login controller, as changing the Register class would require changing the login accordingly:

public function login() {  
    $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
    $this->form_validation->set_rules('password', 'Password', 'required|trim');
    $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
    if ($this->form_validation->run()) {
      $email = $this->input->post('email');
      $password = $this->input->post('password');
      $this->load->model('Usermodel');
      $current_user = $this->Usermodel->user_login($email, $password);
        // If we find a user
      if ($current_user) {
        // If the user found is active
        if ($current_user->active == 1) {
          $this->session->set_userdata(
           array(
            'user_id' => $current_user->id,
            'user_email' => $current_user->email,
            'user_first_name' => $current_user->first_name,
            'user_is_admin' => $current_user->is_admin,
            'user_active' => $current_user->active,
            'is_logged_in' => TRUE
            )
           );
          // After login, display flash message
          $this->session->set_flashdata('user_signin', 'You have signed in');
          //and redirect to the posts page
          redirect('/dashboard');  
        } else {
          // If the user found is NOT active
          $this->session->set_flashdata("login_failure_activation", "Your account has not been activated yet.");
          redirect('login'); 
        }
      } else {
        // If we do NOT find a user
        $this->session->set_flashdata("login_failure_incorrect", "Incorrect email or password.");
        redirect('login'); 
      }
    }
    else {
      $this->index();
    }
  }

Looking for feedback and improvement ideas.


Get this bounty!!!

#StackBounty: #windows #security #service #server-message-block #hardening Windows service hardening: write restricted service that acc…

Bounty: 100

I have a service that runs as “NT AUTHORITYNetworkService” that periodically reads a file from a smb share. This works just fine in unrestricted mode.

Now I would like to make my service write restricted in order to further limit potential security repercussions. If I understand service hardening correctly I can do so by executing sc.exe sidtype MyService restricted and then my service should continue to be able to read anything it was capable of reading when running in unrestricted mode, but writing should be limited to ACLs granting explicit permissions to NT SERVICEMyService. However after doing so, the service can no longer read from the remote share. How do I fix that?

I’m having truble understanding windows service hardening. I come from the UNIX world and I really can’t find any good detailed documents explaining service priviliges etc. So if you can recommand a book or a site in the comments I would appreciate that. So far the best summary I was able to find is this blog article: https://www.itprotoday.com/security/understanding-windows-service-hardening.

Also to be honest I sort of mistrust the security of smb. Tough I don’t have any practical experience supporting this. In my case I don’t care about eavesdropping as the content of the files is not secret, but I’m worried about man in the middle attacks that tamper with the contents of my files. How realistic is that thread? For now I have taken the extra security measurement of signing my files with a RSA key and checking that signature in my service.


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!

#StackBounty: #ubuntu #security #tcp Windows .NET application can't connect after Ubuntu 16.04 upgrade of linux-image to 4.4.0-151

Bounty: 200

After upgrading Ubuntu 16.04 kernel to linux-image-4.4.0-151-generic some of our clients stopped being able to connect with TCP. Specifically using SSH.NET library from Windows servers with SFTP service provided by CrushFTP.

We had to rollback the upgrade, but the issues fixed in this kernel version look very serious (CVE-2019-11477, CVE-2019-11478 {SACK Panic}, CVE-2019-11479):

Version: 4.4.0-151.178  2019-06-19 13:11:04 UTC

  linux (4.4.0-151.178) xenial; urgency=medium

  * Remote denial of service (system crash) caused by integer overflow in TCP
    SACK handling (LP: #1831637)
    - SAUCE: tcp: limit payload size of sacked skbs
    - SAUCE: tcp: fix fack_count accounting on tcp_shift_skb_data()

  * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard
    manipulation (LP: #1831638)
    - SAUCE: tcp: tcp_fragment() should apply sane memory limits

 -- Stefan Bader <email address hidden> Tue, 11 Jun 2019 09:36:19 +0200

Do you know and can share any links for more information about similar problems experienced after upgrade to this specific Ubuntu kernel?


Get this bounty!!!