Bidirectional (BIDI) control characters can be used to reorder the display of source code, hiding malicious logic from human reviewers.

Why is this an issue?

The Unicode encoding contains BIDI control characters that are used to display text right-to-left (RTL) instead of left-to-right (LTR). These characters can create a difference between what a human sees and what a compiler or interpreter executes. An adversary can use this to embed a backdoor in source code that will not be spotted by a human reviewer.

What is the potential impact?

Hidden BIDI characters can disguise malicious code as benign, allowing backdoors to persist undetected. This can lead to supply chain attacks when the compromised code is included in libraries or shared projects.

How to fix it

Code examples

A hidden BIDI character is present in the code, causing the displayed text to differ from the executed logic.

Noncompliant code example

def subtract_funds(account: str, amount: int):
    ''' Subtract funds from bank account then ⁧''' ;return
    bank[account] -= amount
    return

The executed code looks like the following:

def subtract_funds(account: str, amount: int):
    ''' Subtract funds from bank account then <RLI>''' ;return
    bank[account] -= amount
    return

Compliant solution

def subtract_funds(account: str, amount: int):
    ''' Subtract funds from bank account then return; '''
    bank[account] -= amount
    return

Resources

Documentation

Articles & blog posts

Standards