mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-07-14 20:05:02 +03:00
Compare commits
1 Commits
id-whiteli
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdb38c4730 |
@@ -2623,6 +2623,20 @@ pub fn is_direct_ip_access(peer: &str) -> bool {
|
|||||||
hbb_common::is_ip_str(peer) || hbb_common::is_domain_port_str(peer)
|
hbb_common::is_ip_str(peer) || hbb_common::is_domain_port_str(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Align the maximum length of the peer id to the maximum length of the peer id in the server.
|
||||||
|
const MAX_UNTRUSTED_PEER_ID_LEN: usize = 253;
|
||||||
|
const UNTRUSTED_PEER_ID_FORBIDDEN_CHARS: &[char] = &['"', '<', '>', '/', '\\', '|', '?', '*'];
|
||||||
|
|
||||||
|
// Shared validation for peer/connect ids that cross untrusted boundaries before
|
||||||
|
// they are stored or written into command/script contexts.
|
||||||
|
pub fn is_valid_untrusted_peer_id(id: &str) -> bool {
|
||||||
|
!id.is_empty()
|
||||||
|
&& id.len() <= MAX_UNTRUSTED_PEER_ID_LEN
|
||||||
|
&& !id.chars().any(|ch| {
|
||||||
|
ch.is_control() || ch.is_whitespace() || UNTRUSTED_PEER_ID_FORBIDDEN_CHARS.contains(&ch)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -2653,6 +2667,29 @@ mod tests {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn untrusted_peer_id_validation() {
|
||||||
|
let cases = [
|
||||||
|
("123456789", true),
|
||||||
|
("m\u{00FC}nchen-pc", true),
|
||||||
|
("192.168.1.10:21118", true),
|
||||||
|
("9123456234@public", true),
|
||||||
|
(
|
||||||
|
r#"1" & oWS.Run("cmd.exe /k whoami /priv",1,False) & ""#,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
("", false),
|
||||||
|
("peer id", false),
|
||||||
|
("peer\nid", false),
|
||||||
|
("peer/id", false),
|
||||||
|
("peer?id", false),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (id, expected) in cases {
|
||||||
|
assert_eq!(is_valid_untrusted_peer_id(id), expected, "{id:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ThrottledInterval tick at the same time as tokio interval, if no sleeps
|
// ThrottledInterval tick at the same time as tokio interval, if no sleeps
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -241,6 +241,14 @@ fn wait_response(
|
|||||||
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
||||||
last_recv_time = Instant::now();
|
last_recv_time = Instant::now();
|
||||||
if p.cmd == "pong" {
|
if p.cmd == "pong" {
|
||||||
|
if !crate::common::is_valid_untrusted_peer_id(&p.id) {
|
||||||
|
log::warn!(
|
||||||
|
"Ignoring LAN discovery response from {} with invalid peer id",
|
||||||
|
addr
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let local_mac = if try_get_ip_by_peer {
|
let local_mac = if try_get_ip_by_peer {
|
||||||
if let Some(self_addr) = get_ipaddr_by_peer(&addr) {
|
if let Some(self_addr) = get_ipaddr_by_peer(&addr) {
|
||||||
get_mac(&self_addr)
|
get_mac(&self_addr)
|
||||||
|
|||||||
@@ -2278,6 +2278,10 @@ fn get_shortcut_icon_location(install_dir: &str, exe: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_shortcut(id: &str) -> ResultType<()> {
|
pub fn create_shortcut(id: &str) -> ResultType<()> {
|
||||||
|
if !crate::common::is_valid_untrusted_peer_id(id) {
|
||||||
|
bail!("Invalid peer id for shortcut");
|
||||||
|
}
|
||||||
|
|
||||||
let exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned();
|
let exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned();
|
||||||
// https://github.com/rustdesk/rustdesk/issues/13735
|
// https://github.com/rustdesk/rustdesk/issues/13735
|
||||||
// Replace ':' with '_' for filename since ':' is not allowed in Windows filenames
|
// Replace ':' with '_' for filename since ':' is not allowed in Windows filenames
|
||||||
|
|||||||
Reference in New Issue
Block a user