面试题答案
一键面试防止密码明文显示在终端上
在Rust中,可以使用std::io::Write
和std::io::Read
特性结合termios
库(在Unix系统上)或者windows
库(在Windows系统上)来实现隐藏用户输入。对于跨平台方案,可以使用console
库。
- 使用
console
库:- 首先在
Cargo.toml
中添加依赖:
console = "0.15"
- 然后在代码中使用:
use console::Term; fn main() { let term = Term::stdout(); term.write_str("Enter password: ").unwrap(); let password = term.read_password().unwrap(); println!("\nPassword entered: {}", password); }
- 首先在
安全验证防止注入攻击
-
输入验证思路:
- 对于密码等敏感信息,验证长度是否合理。例如,密码长度可以设置一个合理的范围,比如8到128字符之间。
- 检查输入中是否包含恶意字符。对于密码,可以只允许字母、数字和一些特定的安全符号(如
_
,-
等)。 - 对于可能用于SQL查询等场景的输入,要使用参数化查询而不是字符串拼接,以防止SQL注入。
-
关键代码示例(密码验证):
use std::str::Chars; fn validate_password(password: &str) -> bool { // 验证长度 if password.len() < 8 || password.len() > 128 { return false; } let valid_chars: Vec<char> = ('a'..='z').chain(('A'..='Z')).chain(('0'..='9')).chain(['_', '-']).collect(); let chars: Chars<'_> = password.chars(); for c in chars { if!valid_chars.contains(&c) { return false; } } true }
可以在获取到密码后调用这个函数进行验证:
fn main() { let term = Term::stdout(); term.write_str("Enter password: ").unwrap(); let password = term.read_password().unwrap(); if validate_password(&password) { println!("Password is valid."); } else { println!("Password is invalid."); } }
-
防止SQL注入示例(假设使用
rusqlite
库):- 首先在
Cargo.toml
中添加依赖:
rusqlite = "0.28"
- 然后在代码中使用参数化查询:
use rusqlite::{Connection, params}; fn main() { let conn = Connection::open("test.db").expect("Failed to open database"); let username = "test_user"; let password = "test_password"; let mut stmt = conn.prepare("SELECT * FROM users WHERE username =? AND password =?").expect("Failed to prepare statement"); let rows = stmt.query(params![username, password]).expect("Failed to query database"); for row in rows { println!("User found: {:?}", row); } }
- 首先在
通过以上方法,可以有效地防止密码明文显示和一些常见的安全威胁。