Skip to content

Commit

Permalink
desktop: Support for spoofing eval("window.location.href") with Exter…
Browse files Browse the repository at this point in the history
…nalInterface
  • Loading branch information
evilpie committed Jun 3, 2024
1 parent 35ec0b9 commit 6af5a9f
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions desktop/src/backends/external_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,53 @@ pub struct DesktopExternalInterfaceProvider {
pub spoof_url: Option<Url>,
}

struct FakeWindowLocationHrefToString(Url);
struct FakeLocationHrefToString(Url);

impl ExternalInterfaceMethod for FakeWindowLocationHrefToString {
impl ExternalInterfaceMethod for FakeLocationHrefToString {
fn call(&self, _context: &mut UpdateContext<'_, '_>, _args: &[ExternalValue]) -> ExternalValue {
ExternalValue::String(self.0.to_string())
}
}

fn is_location_href(code: &str) -> bool {
matches!(
code,
"document.location.href" | "window.location.href" | "top.location.href"
)
}

struct FakeEval(Option<Url>);

impl ExternalInterfaceMethod for FakeEval {
fn call(&self, _context: &mut UpdateContext<'_, '_>, args: &[ExternalValue]) -> ExternalValue {
if let Some(ref url) = self.0 {
if let [ExternalValue::String(ref code)] = args {
if is_location_href(code) {
return ExternalValue::String(url.to_string());
}
}
}

tracing::warn!("Trying to call eval with ExternalInterface: {args:?}");
ExternalValue::Undefined
}
}

impl ExternalInterfaceProvider for DesktopExternalInterfaceProvider {
fn get_method(&self, name: &str) -> Option<Box<dyn ExternalInterfaceMethod>> {
if let Some(ref url) = self.spoof_url {
if name == "window.location.href.toString" || name == "top.location.href.toString" {
return Some(Box::new(FakeWindowLocationHrefToString(url.clone())));
// Check for e.g. "window.location.href.toString"
if let Some(name) = name.strip_suffix(".toString") {
if is_location_href(name) {
return Some(Box::new(FakeLocationHrefToString(url.clone())));
}
}
}

if name == "eval" {
return Some(Box::new(FakeEval(self.spoof_url.clone())));
}

tracing::warn!("Trying to call unknown ExternalInterface method: {name}");
None
}
Expand Down

0 comments on commit 6af5a9f

Please sign in to comment.