> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Semper vigilans: how Platform.sh stays ahead of emerging cybersecurity threats (so you don’t have to)

> Always vigilant is more than a motto. Find out how the Platform.sh Security team monitors vulnerabilities 24x7 to protect customers from cybersecurity threats.

export const PostMeta = ({data = {}}) => {
  const {author, date} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud",
      "linkedin": "https://www.linkedin.com/in/laurent-arnoud-861b44121/"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "maz-mohammadi": {
      "name": "Maz Mohammadi"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
    </div>;
};

<PostMeta data={{ author: ["diogo-sousa"], date: "2023-10-13T10:00:00+00:00", image: "/images/posts/how-it-works/how-platformsh-stays-ahead-of-emerging-cybersecurity-threats/terrible_trio_blog.webp" }} />

October is Cybersecurity Awareness month. So, we’ve asked Diogo Sousa, Platform.sh Security team manager to share how
his team contributes to helping customers protect their websites and applications from external threats, 24x7.

***

Part of the Platform.sh Security team’s day-to-day work is to monitor for any vulnerabilities that might impact our
customers. We do this by combining information from various sources—including CVE feeds, blogs, social media
accounts—then evaluate if any of these vulnerabilities are capable of affecting our infrastructure and the services we
provide. Because Platform.sh offers a depth and breadth of [languages and frameworks](https://platform.sh/marketplace/),
we might be analyzing advisories for Golang in the morning, Drupal in the afternoon, and Linux kernel bugs in the
evening. In 2022 alone, the Security team reviewed and advised on more than 300 CVEs across a dozen technologies.

These past weeks of autumn have brought a bountiful crop of high-profile vulnerabilities in popular libraries and tools:
libwebp (CVE-2023-4863), libvpx (CVE-2023-5217), glibc (CVE-2023-4911), HTTP/2 (CVE-2023-44487) and, culminating with a
big one, libcurl (CVE-2023-38545).

**To avoid burying the lede, here’s our current situation:**

We’ve made updated versions of all the library CVEs noted above, accessible to Platform.sh customers via a
[redeploy](https://docs.platform.sh/development/troubleshoot.html#force-a-redeploy). The HTTP/2 issue has been mitigated
at our edge layer.

Our service continues to operate securely.

### **So, what exactly are these vulnerabilities?**

#### **libwebp**

Let’s start with libwebp. As the name suggests, it’s a library used to process images in the WebP format,
[developed by Google for a faster web experience](https://developers.google.com/speed/webp). Faster load times, no loss
of quality, smaller file sizes through better compression—all benefits realized by using the webp format. However, I’m
certainly not alone in saying that it’s a slight annoyance when right-clicking an image to expect a transparent PNG, but
getting a .webp file back.

WebP can compress files without any loss of quality, and it’s in that compression that this vulnerability was discovered.

To achieve the compression, WebP uses a method called [Huffman coding](https://en.wikipedia.org/wiki/Huffman_coding). A
Huffman code is generated from the image and used to efficiently store information on a special table data structure,
producing a smaller file with no loss of quality, something very important for images on the web. We’ve all seen a JPEG
full of compression artifacts, and it isn’t pretty.

It was found that by using a specially crafted image file, you could bypass a size check and trigger a heap overflow
that you could, then, chain into other attacks. This payload, a singular image, made for an interesting delivery
mechanism: if your web application didn’t accept and process webp files, delivering a malicious payload was pretty much
blocked. *But* if your application merely displayed the webp image, like a browser or a messaging app, then visiting a
website or receiving a file would be enough to trigger it.

Fortunately, creating those files required a high degree of sophistication. They had to represent a valid encoding, with
enough additional data hidden to deliver a payload. And that limited the exploitation until patches were made available.
Vendors like Apple and Google promptly made the patches available to users once the issue became known. (Hope everyone
has the good habit of always keeping your OS and browser up to date.)

#### **HTTP/2: Rapid Reset**

The HTTP/2 vulnerability, named Rapid Reset, is interesting as it’s a part of the HTTP/2 protocol itself. In essence,
it wasn’t added to the code via a faulty commit; it’s baked in.

HTTP/2 allows for multiple data streams when accessing data, increasing the capability of the connection by prioritizing
what gets retrieved. One of those optimizations is the ability for the client to cancel an ongoing stream, similar to
saying to the server that it doesn’t need to send over every image on the page because they’re now outside the viewport.
This is an inexpensive process for the client, which can move on to other requests; it’s up to the server to honor that
cancellation and keep an accurate tally of requests to process, and that’s where the issue lies.

Keeping accurate counts of what requests are in what state and are still needed to be processed is important to avoid
getting overwhelmed by requests. The protocol sets a number for the maximum number of concurrent streams, but only
streams in certain stages of their lifecycle count against this number. The Rapid Reset attack takes advantage of this
by creating a backlog of reset streams that need to be cleaned up by the server. And since they’re not in one of the
lifecycle states that counts against the limit, this backlog can grow very quickly, leading to a DoS. With HTTP/2 being
common fare—and the attack having a very low complexity—it makes for an ample choice of targets and has already broken
some [infamous records](https://blog.cloudflare.com/zero-day-rapid-reset-http2-record-breaking-ddos-attack/).

Now, to our main course, libcurl.

#### **libcurl**

The issue in libcurl should be familiar to anyone who’s written C code. When connecting to a SOCKS5 proxy, it was
possible that the buffer allocated for the hostname was too small and, under specific circumstances, it could be
overwritten into a heap overflow.

Noticing a pattern here? As with libwebp, this vulnerability’s impact is limited by its requirements: if using version
8.x, the user needs to purposely override the default configuration (which is safe) to use a lower value for the limit
rate. By itself, this vulnerability causes a crash. To leverage it for further compromise, the user must use unsafe
options, like forcing cURL to follow redirects (-L), so a payload can be delivered
([example](https://blog.aquasec.com/new-vulnerability-in-curl-and-libcurl-could-lead-to-heap-buffer-overflow)). If
you’re not in the habit of connecting to unknown (potentially malicious) servers, this should have little to no impact
on your usage.

The biggest vulnerability issue here? libcurl is used
[by a vast number of companies](https://curl.se/docs/companies.html); it’s not an easy task (particularly if you’re
doing it on your own) to ensure that all these products, which you may be using directly or indirectly, are using safe
configurations.

### **Next steps: what you can do**

If you’re a Platform.sh customer, our teams have already overseen the patching and rollout of the updated versions I’ve
just discussed. After evaluating the vulnerabilities’ impact and manner of operation, we decided against forcing a
redeployment, leaving it for each customer to schedule and minimize the disruption to their workflows. When clear
indicators of active exploitation happen, our customers can rest assured we’ll force an update to keep their projects
safe.

To ensure your project remains protected, all you need to do is redeploy. That will trigger an automated check for any
changes, and your project will update itself to the latest version with all the necessary patches. We know it’s Friday,
but you don’t need to worry: Deploy Friday is our mantra for a reason.

If you’re not currently a Platform.sh customer, vendors have made patches available, together with some recommendations
about how to mitigate the impact of these vulnerabilities.

**libwebp**\
[https://blog.isosceles.com/the-webp-0day/](https://blog.isosceles.com/the-webp-0day/)\
[https://github.com/advisories/GHSA-j7hp-h8jx-5ppr](https://github.com/advisories/GHSA-j7hp-h8jx-5ppr)

**HTTP/2**\
[https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/](https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/)\
[https://www.nginx.com/blog/http-2-rapid-reset-attack-impacting-f5-nginx-products/](https://www.nginx.com/blog/http-2-rapid-reset-attack-impacting-f5-nginx-products/)

**libcurl**\
[https://curl.se/docs/CVE-2023-38545.html](https://curl.se/docs/CVE-2023-38545.html)

Finally, if you’re looking for a fully managed PaaS, including security and compliance, we hope you’ll
[give Platform.sh a try](https://auth.api.platform.sh/register?trial_type=general&_utm_medium=Email&_utm_campaign=2022-09-newsletter&_utm_source=devrelcareers).
