88 lines
2.9 KiB
Plaintext
88 lines
2.9 KiB
Plaintext
Using bidirectional (BIDI) characters can lead to incomprehensible code.
|
||
|
||
The Unicode encoding contains BIDI control characters that are used to display text right-to-left (RTL) instead of left-to-right (LTR). This is necessary for certain languages that use RTL text.
|
||
The BIDI characters can be used to create a difference in the code between what a human sees and what a compiler or interpreter sees.
|
||
An advisary might use this feature to hide a backdoor in the code that will not be spotted by a human reviewer as it is not visible.
|
||
|
||
This can lead to supply chain attacks since the backdoored code might persist over a long time without being detected and can even be included in other projects, for example in the case of libraries.
|
||
|
||
|
||
== Ask Yourself Whether
|
||
|
||
* This text requires a right-to-left writing system (to use Arabic or Hebrew words, for example).
|
||
* The author of this text is a legitimate user.
|
||
* This text contains a standard instruction, comment or sequence of characters.
|
||
|
||
There is a risk if you answered no to any of these questions.
|
||
|
||
|
||
== Recommended Secure Coding Practices
|
||
|
||
Open the file in an editor that reveals non-ASCII characters and remove all BIDI control characters that are not intended.
|
||
|
||
If hidden characters are illegitimate, this issue could indicate a potential ongoing attack on the code. Therefore, it would be best to warn your organization's security team about this issue.
|
||
|
||
Required opening BIDI characters should be explicitly closed with the PDI character.
|
||
|
||
|
||
== Sensitive Code Example
|
||
|
||
A hidden BIDI character is present in front of `return`:
|
||
|
||
----
|
||
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
|
||
|
||
No hidden BIDI characters are present:
|
||
|
||
[source,text]
|
||
----
|
||
def subtract_funds(account: str, amount: int):
|
||
''' Subtract funds from bank account then return; '''
|
||
bank[account] -= amount
|
||
return
|
||
----
|
||
|
||
== See
|
||
|
||
* https://unicode.org/reports/tr9/[Bidirectional Algorithm] - Unicode Standard
|
||
* https://en.wikipedia.org/wiki/Bidirectional_text[Wikipedia] - Bidirectional Text
|
||
* https://www.trojansource.codes/trojan-source.pdf[Trojan Source Report]
|
||
* https://www.trojansource.codes/trojan-source.pdf#page=15[Trojan Source Report] - IDEs revealing hidden characters
|
||
* CWE - https://cwe.mitre.org/data/definitions/94[CWE-94 - Improper Control of Generation of Code ('Code Injection')]
|
||
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
=== Message
|
||
|
||
This line contains a bidirectional character in column {x}. Make sure that using bidirectional characters is safe here.
|
||
|
||
|
||
=== Highlighting
|
||
|
||
The entire line should be highlighted.
|
||
|
||
|
||
'''
|
||
|
||
endif::env-github,rspecator-view[]
|