diff --git a/SOURCES/squid-4.11-CVE-2020-15810.patch b/SOURCES/squid-4.11-CVE-2020-15810.patch
new file mode 100644
index 0000000..252ffad
--- /dev/null
+++ b/SOURCES/squid-4.11-CVE-2020-15810.patch
@@ -0,0 +1,44 @@
+diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
+index 67543a4..19efc6d 100644
+--- a/src/HttpHeader.cc
++++ b/src/HttpHeader.cc
+@@ -445,18 +445,6 @@ HttpHeader::parse(const char *header_start, size_t hdrLen)
+             return 0;
+         }
+ 
+-        if (e->id == Http::HdrType::OTHER && stringHasWhitespace(e->name.termedBuf())) {
+-            debugs(55, warnOnError, "WARNING: found whitespace in HTTP header name {" <<
+-                   getStringPrefix(field_start, field_end-field_start) << "}");
+-
+-            if (!Config.onoff.relaxed_header_parser) {
+-                delete e;
+-                PROF_stop(HttpHeaderParse);
+-                clean();
+-                return 0;
+-            }
+-        }
+-
+         addEntry(e);
+     }
+ 
+@@ -1451,6 +1439,20 @@ HttpHeaderEntry::parse(const char *field_start, const char *field_end, const htt
+         }
+     }
+ 
++    /* RFC 7230 section 3.2:
++     *
++     *  header-field   = field-name ":" OWS field-value OWS
++     *  field-name     = token
++     *  token          = 1*TCHAR
++     */
++    for (const char *pos = field_start; pos < (field_start+name_len); ++pos) {
++        if (!CharacterSet::TCHAR[*pos]) {
++            debugs(55, 2, "found header with invalid characters in " <<
++                   Raw("field-name", field_start, min(name_len,100)) << "...");
++            return nullptr;
++        }
++    }
++
+     /* now we know we can parse it */
+ 
+     debugs(55, 9, "parsing HttpHeaderEntry: near '" <<  getStringPrefix(field_start, field_end-field_start) << "'");
diff --git a/SOURCES/squid-4.11-CVE-2020-15811.patch b/SOURCES/squid-4.11-CVE-2020-15811.patch
new file mode 100644
index 0000000..080124f
--- /dev/null
+++ b/SOURCES/squid-4.11-CVE-2020-15811.patch
@@ -0,0 +1,139 @@
+diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
+index dc6e0ff..67543a4 100644
+--- a/src/HttpHeader.cc
++++ b/src/HttpHeader.cc
+@@ -174,6 +174,7 @@ HttpHeader::operator =(const HttpHeader &other)
+         update(&other); // will update the mask as well
+         len = other.len;
+         conflictingContentLength_ = other.conflictingContentLength_;
++        teUnsupported_ = other.teUnsupported_;
+     }
+     return *this;
+ }
+@@ -222,6 +223,7 @@ HttpHeader::clean()
+     httpHeaderMaskInit(&mask, 0);
+     len = 0;
+     conflictingContentLength_ = false;
++    teUnsupported_ = false;
+     PROF_stop(HttpHeaderClean);
+ }
+ 
+@@ -464,11 +466,23 @@ HttpHeader::parse(const char *header_start, size_t hdrLen)
+                Raw("header", header_start, hdrLen));
+     }
+ 
+-    if (chunked()) {
++    String rawTe;
++    if (getByIdIfPresent(Http::HdrType::TRANSFER_ENCODING, &rawTe)) {
+         // RFC 2616 section 4.4: ignore Content-Length with Transfer-Encoding
+         // RFC 7230 section 3.3.3 #3: Transfer-Encoding overwrites Content-Length
+         delById(Http::HdrType::CONTENT_LENGTH);
+         // and clen state becomes irrelevant
++
++        if (rawTe == "chunked") {
++            ; // leave header present for chunked() method
++        } else if (rawTe == "identity") { // deprecated. no coding
++            delById(Http::HdrType::TRANSFER_ENCODING);
++        } else {
++            // This also rejects multiple encodings until we support them properly.
++            debugs(55, warnOnError, "WARNING: unsupported Transfer-Encoding used by client: " << rawTe);
++            teUnsupported_ = true;
++        }
++
+     } else if (clen.sawBad) {
+         // ensure our callers do not accidentally see bad Content-Length values
+         delById(Http::HdrType::CONTENT_LENGTH);
+diff --git a/src/HttpHeader.h b/src/HttpHeader.h
+index e3553a4..64f294a 100644
+--- a/src/HttpHeader.h
++++ b/src/HttpHeader.h
+@@ -140,7 +140,13 @@ public:
+     int hasListMember(Http::HdrType id, const char *member, const char separator) const;
+     int hasByNameListMember(const char *name, const char *member, const char separator) const;
+     void removeHopByHopEntries();
+-    inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
++
++    /// whether the message uses chunked Transfer-Encoding
++    /// optimized implementation relies on us rejecting/removing other codings
++    bool chunked() const { return has(Http::HdrType::TRANSFER_ENCODING); }
++
++    /// whether message used an unsupported and/or invalid Transfer-Encoding
++    bool unsupportedTe() const { return teUnsupported_; }
+ 
+     /* protected, do not use these, use interface functions instead */
+     std::vector<HttpHeaderEntry *> entries;     /**< parsed fields in raw format */
+@@ -158,6 +164,9 @@ protected:
+ private:
+     HttpHeaderEntry *findLastEntry(Http::HdrType id) const;
+     bool conflictingContentLength_; ///< found different Content-Length fields
++    /// unsupported encoding, unnecessary syntax characters, and/or
++    /// invalid field-value found in Transfer-Encoding header
++    bool teUnsupported_ = false;
+ };
+ 
+ int httpHeaderParseQuotedString(const char *start, const int len, String *val);
+@@ -167,13 +176,6 @@ SBuf httpHeaderQuoteString(const char *raw);
+ 
+ void httpHeaderCalcMask(HttpHeaderMask * mask, Http::HdrType http_hdr_type_enums[], size_t count);
+ 
+-inline bool
+-HttpHeader::chunked() const
+-{
+-    return has(Http::HdrType::TRANSFER_ENCODING) &&
+-           hasListMember(Http::HdrType::TRANSFER_ENCODING, "chunked", ',');
+-}
+-
+ void httpHeaderInitModule(void);
+ 
+ #endif /* SQUID_HTTPHEADER_H */
+diff --git a/src/client_side.cc b/src/client_side.cc
+index 5f5a79e..000a00b 100644
+--- a/src/client_side.cc
++++ b/src/client_side.cc
+@@ -1600,9 +1600,7 @@ void
+ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp, Http::Stream *context)
+ {
+     ClientHttpRequest *http = context->http;
+-    bool chunked = false;
+     bool mustReplyToOptions = false;
+-    bool unsupportedTe = false;
+     bool expectBody = false;
+ 
+     // We already have the request parsed and checked, so we
+@@ -1659,13 +1657,7 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
+         request->http_ver.minor = http_ver.minor;
+     }
+ 
+-    if (request->header.chunked()) {
+-        chunked = true;
+-    } else if (request->header.has(Http::HdrType::TRANSFER_ENCODING)) {
+-        const String te = request->header.getList(Http::HdrType::TRANSFER_ENCODING);
+-        // HTTP/1.1 requires chunking to be the last encoding if there is one
+-        unsupportedTe = te.size() && te != "identity";
+-    } // else implied identity coding
++    const auto unsupportedTe = request->header.unsupportedTe();
+ 
+     mustReplyToOptions = (request->method == Http::METHOD_OPTIONS) &&
+                          (request->header.getInt64(Http::HdrType::MAX_FORWARDS) == 0);
+@@ -1682,6 +1674,7 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
+         return;
+     }
+ 
++    const auto chunked = request->header.chunked();
+     if (!chunked && !clientIsContentLengthValid(request.getRaw())) {
+         clientStreamNode *node = context->getClientReplyContext();
+         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
+diff --git a/src/http.cc b/src/http.cc
+index 9654c4a..6f4d3b2 100644
+--- a/src/http.cc
++++ b/src/http.cc
+@@ -1292,6 +1292,9 @@ HttpStateData::continueAfterParsingHeader()
+             } else if (vrep->header.conflictingContentLength()) {
+                 fwd->dontRetry(true);
+                 error = ERR_INVALID_RESP;
++            } else if (vrep->header.unsupportedTe()) {
++                fwd->dontRetry(true);
++                error = ERR_INVALID_RESP;
+             } else {
+                 return true; // done parsing, got reply, and no error
+             }
diff --git a/SOURCES/squid-4.11-CVE-2020-24606.patch b/SOURCES/squid-4.11-CVE-2020-24606.patch
new file mode 100644
index 0000000..d277507
--- /dev/null
+++ b/SOURCES/squid-4.11-CVE-2020-24606.patch
@@ -0,0 +1,34 @@
+commit b789e719affbb0a6ff9c22095f6ca8db6a5f4926
+Author: Eduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
+Date:   2020-07-27 15:28:31 +0000
+
+    Fix livelocking in peerDigestHandleReply (#698)
+    
+    peerDigestHandleReply() was missing a premature EOF check. The existing
+    peerDigestFetchedEnough() cannot detect EOF because it does not have
+    access to receivedData.length used to indicate the EOF condition. We did
+    not adjust peerDigestFetchedEnough() because it is abused to check both
+    post-I/O state and the state after each digest processing step. The
+    latter invocations lack access to receivedData.length and should not
+    really bother with EOF anyway.
+
+diff --git a/src/peer_digest.cc b/src/peer_digest.cc
+index d48340f97..265f16183 100644
+--- a/src/peer_digest.cc
++++ b/src/peer_digest.cc
+@@ -483,6 +483,15 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData)
+ 
+     } while (cbdataReferenceValid(fetch) && prevstate != fetch->state && fetch->bufofs > 0);
+ 
++    // Check for EOF here, thus giving the parser one extra run. We could avoid this overhead by
++    // checking at the beginning of this function. However, in this case, we would have to require
++    // that the parser does not regard EOF as a special condition (it is true now but may change
++    // in the future).
++    if (!receivedData.length) { // EOF
++        peerDigestFetchAbort(fetch, fetch->buf, "premature end of digest reply");
++        return;
++    }
++
+     /* Update the copy offset */
+     fetch->offset += receivedData.length;
+ 
diff --git a/SPECS/squid.spec b/SPECS/squid.spec
index c0fc773..597f1a1 100644
--- a/SPECS/squid.spec
+++ b/SPECS/squid.spec
@@ -2,7 +2,7 @@
 
 Name:     squid
 Version:  4.11
-Release:  2%{?dist}
+Release:  3%{?dist}
 Summary:  The Squid proxy caching server
 Epoch:    7
 # See CREDITS for breakdown of non GPLv2+ code
@@ -42,6 +42,13 @@ Patch208: squid-4.11-convert-ipv4.patch
 Patch500: squid-4.11-CVE-2020-14058.patch
 # https://bugzilla.redhat.com/show_bug.cgi?id=1852550
 Patch501: squid-4.11-CVE-2020-15049.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1871705
+Patch502: squid-4.11-CVE-2020-24606.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1871702
+Patch503: squid-4.11-CVE-2020-15811.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1871700
+Patch504: squid-4.11-CVE-2020-15810.patch
+
 
 Requires: bash >= 2.0
 Requires(pre): shadow-utils
@@ -106,6 +113,9 @@ lookup program (dnsserver), a program for retrieving FTP data
 # Security patches
 %patch500 -p1 -b .cve-2020-14058
 %patch501 -p1 -b .cve-2020-15049
+%patch502 -p1 -b .cve-2020-24606
+%patch503 -p1 -b .CVE-2020-15811
+%patch504 -p1 -b .CVE-2020-15810
 
 # https://bugzilla.redhat.com/show_bug.cgi?id=1679526
 # Patch in the vendor documentation and used different location for documentation
@@ -322,6 +332,14 @@ fi
 
 
 %changelog
+* Wed Aug 26 2020 Lubos Uhliarik <luhliari@redhat.com> - 7:4.11-3
+- Resolves: #1871705 - CVE-2020-24606 squid: Improper Input Validation could
+  result in a DoS
+- Resolves: #1871702 - CVE-2020-15811 squid: HTTP Request Splitting could result
+  in cache poisoning
+- Resolves: #1871700 - CVE-2020-15810 squid: HTTP Request Smuggling could result
+  in cache poisoning
+
 * Thu Jul 02 2020 Lubos Uhliarik <luhliari@redhat.com> - 7:4.11-2
 - Resolves: #1853130 - CVE-2020-15049 squid:4/squid: request smuggling and
   poisoning attack against the HTTP cache