警告
本文最后更新于 2021-12-06 ,文中内容可能已过时。
Unicode的视觉欺骗
新闻来源:特洛伊之源| 在 Rust 代码中隐藏无形的漏洞 作者: 张汉东
https://trojansource.codes/ 给出了更详细的解释。比如这段代码
1
2
3
4
5
6
7
8
// 该文件包含双向Unicode文本,其解释或编译方式可能与下面的内容不同。要审查,请在一个能显示隐藏的Unicode字符的编辑器中打开该文件。
// 执行输出
fn main() {
let is_admin = false;
/* } if is_admin begin admins only */
println!("You are an admin.");
/* end admins only { */
}
上面这段代码在最新的 VSCode 会有非常明显的隐藏字符提示。
明显的隐藏字符提示" 有时,Unicode 会视觉欺骗,不会有明显提示。比如say_hello和say_һello,看上去没有区别,实际并不相同。你可以通过浏览器带的搜索,看到这两个不能同时被搜索。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main () {
fn say_hello () {
println! ( "Hello, World! \n " );
}
fn say_ һ ello () {
println! ( "Goodbye, World! \n " );
}
say_hello ();
say_ һ ello ();
let str1 = String ::from ( "say_hello" );
let str2 = String ::from ( "say_һello" );
for i in str1 . as_bytes () { print! ( " {} " , i ); }
println! ( "" );
for i in str2 . as_bytes () { print! ( " {} " , i ); }
}
执行结果
1
2
3
4
5
6
Hello , World !
Goodbye , World !
115 97 121 95 104 101 108 108 111
115 97 121 95 210 187 101 108 108 111
完整结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
> Executing task : ~/ .cargo / bin / cargo run <
Compiling mo v0.1.0 ( D : \rustcode\mo )
warning : identifier pair considered confusable between `say_hello` and `say_һello`
--> src\main.rs : 5 : 8
|
2 | fn say_hello () {
| --------- this is where the previous identifier occurred
...
5 | fn say_ һello () {
| ^^^^^^^^^
|
= note : `#[warn(confusable_idents)]` on by default
warning : The usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables
--> src\main.rs : 5 : 8
|
5 | fn say_ һello () {
| ^^^^^^^^^
|
= note : `#[warn(mixed_script_confusables)]` on by default
= note : The usage includes 'һ' ( U +04 BB ) .
= note : Please recheck to make sure their usages are indeed what you want.
warning : `mo` ( bin "mo" ) generated 2 warnings
Finished dev [unoptimized + debuginfo] target ( s ) in 1.38 s
Running `target\debug\mo.exe`
Hello , World !
Goodbye , World !
115 97 121 95 104 101 108 108 111
115 97 121 95 210 187 101 108 108 111
终端将被任务重用,按任意键关闭。