Executive summary
AWS published CVE-2026-8178 against the Amazon Redshift JDBC Driver. The description is one sentence and it is worth reading twice: “Under certain conditions, the driver could load and execute arbitrary classes when processing JDBC connection URL parameters.”
Affected: “Amazon Redshift JDBC Driver < 2.2.2”. Fixed in 2.2.2. The bulletin publishes no CVSS score and documents no workaround beyond upgrading — plus one instruction that is easy to skip: “any forked or derivative code” must be patched too.
Upgrade and the specific bug is gone. The more durable finding is what the driver's own documentation says a connection URL is allowed to do, because a class-loading bug in that code path is the sharp end of a surface that is documented, intended, and much larger than most people assume.
What changed
A Type 4 JDBC driver is pure Java running inside your process — a Glue job, a Spark executor, an EMR cluster, a BI server, a Lambda. Arbitrary class loading there is not a database problem. It is code execution with whatever identity that JVM holds, which on AWS is usually an instance or task role.
The upgrade path is straightforward: move every consumer to 2.2.2 or later. The part that takes longer is finding them, because a JDBC driver arrives bundled — inside a BI tool, a Glue connection, a container image, a fat JAR built months ago.
Two option names are worth noting while you are auditing versions.
EnableTableTypes and preferPQ are documented as
“available in driver versions 2.2.8 and later”, which is a useful marker: a
codebase setting either of those is already past the fix, and a codebase that cannot is telling you how
old its driver is.
Architecture
The driver documentation opens with the relevant sentence: “You can set configuration properties using the connection URL… Configuration options are not case sensitive.” Then it lists them. Six are worth pulling out.
Plugin_Name —
“The fully qualified class name to implement a specific credentials provider
plugin.” A connection URL parameter whose value is a class the driver loads. Ten providers
are supported by name, from OktaCredentialsProvider to
IdpTokenAuthPlugin — but the documented data type is a fully qualified
class name, not an enumeration.
socketFactory and
SSLFactory — “specifies a socket factory for
socket creation” and “The SSL factory to use when connecting to the server through
TLS/SSL without using a server certificate.” Two more class names, both on the connection
path.
IniFile and
IniSection —
“The full path of the .ini file, including file name” and
“The name of a section in the .ini file containing the configuration options.” The
URL can point the driver at a local file and have it take its configuration from there.
StsEndpointUrl — specifies an STS endpoint, and
“If you specify this option, the Region option is ignored.” Constrained to HTTPS,
which is the right constraint, and still a redirection of where credentials are requested from.
It is: can anything outside your code contribute a fragment of that URL? A BI tool where analysts configure their own data source. A multi-tenant product that accepts a customer's warehouse endpoint. A Glue job whose connection options come from a job parameter. Anything that string-concatenates a JDBC URL from a database row. In each of those, the documented option list — never mind the CVE — is the actual threat model.
Business value
There is no feature here, so the value is in what the audit turns up. Inventorying every Redshift JDBC driver in the estate is work that pays twice: once for this CVE, and again for the next one, because the hard part is the inventory rather than the upgrade.
The instruction about “forked or derivative code” is the one that finds the interesting cases. A vendored driver, a shaded JAR, a relocated package inside somebody's connector — those do not show up as the driver and do not get upgraded with it.
Security considerations
Treat connection strings as code. They belong under the same controls as code: built from a template with a fixed option set, not concatenated; validated against an allowlist of parameter names if any part is externally supplied; and reviewed when they change.
Two documented defaults deserve attention while you are in this page.
SSL_Insecure has a default value of true, meaning
“The driver doesn't check the authenticity of the IDP server certificate.” For
anyone authenticating through an identity provider, that is certificate verification off unless set.
And SSLMode defaults to “verify-ca”, which checks the CA
but not the hostname. “verify-full” checks that
“the host name in the certificate matches the host name specified in the connection
URL”, and AWS's own note is unambiguous: “We recommend using
verify-full for SSL connections whenever possible.” The recommended value is
not the default value.
Credentials in the URL are a related hazard. The documentation notes that
AccessKeyID, SecretAccessKey and the session
token “must be URL encoded” if passed in the JDBC URL — which tells you people
do. A connection string containing a secret key ends up in logs, stack traces and process listings.
And check AutoCreate. Set true,
“If the user specified by either DBUser or unique ID (UID) doesn't
exist, a new user with that name is created.” Combined with a URL an outsider can influence,
that is user provisioning driven by a connection parameter.
Cost considerations
None directly — a driver upgrade is free. The cost is engineering time, and it is proportional to how many places a JDBC driver is bundled rather than to how many clusters you run.
One indirect note: LogPath and LogLevel are
URL-settable, and the documentation warns that logging “decreases performance and can consume a
large quantity of disk space”, with LogLevel 6 logging
“all driver activity”. A connection string that quietly turns on TRACE logging is a
performance and storage event as well as a disclosure one.
Operational considerations
Find the driver, not the application. Search build manifests and container images for
the artifact, not just your own dependency files — redshift-jdbc42 and
its relocated variants inside other packages.
Option names are case-insensitive, so filters must be too.
“Configuration options are not case sensitive” — any allowlist or blocklist
that matches Plugin_Name exactly will miss
plugin_name and PLUGIN_NAME.
Check the whole bulletin list from this week, not just this one. The same day's feed
carried the Firecracker out-of-bounds write and a FreeRTOS-Plus-TCP issue; the week carried the
pgcollection RCE. This one is the most broadly deployed of them, which is why
it is here, and it is not the only one worth a ticket.
An upgrade is the fix, but the surface remains. 2.2.2 closes the specific class-loading
path. Plugin_Name, socketFactory,
SSLFactory and IniFile are features and are still
there, working as documented.
Tradeoffs
Pluggable auth against a larger parse surface. A class-name option is genuinely how you support ten identity providers plus customers' own. It is also, unavoidably, a string that names code to load.
Convenience defaults against secure defaults.
SSL_Insecure true and SSLMode verify-ca make
first connections work in more environments. Both are weaker than the documentation's own
recommendation.
Configuration in the URL against configuration in code. Putting everything in one string is portable across tools that only accept a URL. It also means configuration travels through logs and user input paths that a properties object would not.
Implementation guidance
Upgrade to 2.2.2 or later, everywhere, including vendored and shaded copies. That is the fix and the bulletin offers no alternative.
Build connection URLs from a template with a fixed parameter set. Externally supplied values belong in named slots, never appended as raw parameters.
Allowlist parameter names case-insensitively anywhere a URL is assembled from configuration you do not fully control.
Set SSLMode=verify-full and
SSL_Insecure=false explicitly. Neither is the default; both are what
the documentation recommends.
Keep credentials out of the URL. Use IAM authentication or a properties object, so the string that gets logged is not the string that holds a secret.
Best practices
Review connection strings in code review. A changed JDBC URL can alter which class loads, which file is read and which STS endpoint is called.
Pin driver versions and alert on drift. The inventory is the expensive part; keeping it current is cheap once built.
Assume the next one lands in the same place. URL-parameter parsing in database drivers has been a recurring class of bug across the industry, not a Redshift-specific event.
Who should act on this
Anyone running the Redshift JDBC driver below 2.2.2 — which, given how drivers arrive bundled, is worth checking even if you do not think you use it directly.
Prioritise it where the JVM holds a powerful role and where any part of the connection string originates outside your code: BI servers with user-defined data sources, multi-tenant products accepting customer endpoints, and Glue or EMR jobs taking connection options as parameters. Deprioritise it where the URL is a constant in an image you build and the role is tightly scoped — still upgrade, just not tonight.
Key takeaways
- CVE-2026-8178: the Redshift JDBC driver "could load and execute arbitrary classes when processing JDBC connection URL parameters."
- Affected below 2.2.2; fixed in 2.2.2. No CVSS published, no workaround but upgrading.
- Forked or derivative code must be patched separately — vendored and shaded copies will not upgrade with the dependency.
- A Type 4 driver is pure Java in your process, so class loading runs with the JVM's role.
Plugin_Nameis documented as "the fully qualified class name" — the URL names code to load, by design.socketFactoryandSSLFactoryare two more class-name options on the connection path.IniFile/IniSectionlet the URL take configuration from an arbitrary local file;LogPathchooses where it writes.StsEndpointUrlredirects credential requests and causesRegionto be ignored.SSL_Insecuredefaults totrue— the IdP certificate is not verified unless you set it.SSLModedefaults toverify-ca, while AWS recommendsverify-full.- Option names are not case sensitive, so any filtering must be case-insensitive too.
Comments