OS X XQuartz Vulnerability Test Using R

March 7, 2016

(This article was first published on R – rud.is, and kindly contributed to R-bloggers)

It’s usually a good thing when my #rstats and infosec worlds collide. Unfortunately, this time it’s a script that R folk running on OS X can use to see if they are using a version of XQuartz that has a nasty vulnerability in the framework it uses to auto-update. If this test comes back with the warning, try to refrain from using XQuartz on insecure networks until the developers fix the issue.


Thanks to a gist prodding by @bearloga, here’s a script to scan all your applications for the vulnerability:

read_plist <- safely(readKeyValueDB)
safe_compare <- safely(compareVersion)
apps <- list.dirs(c("/Applications", "/Applications/Utilities"), recursive=FALSE)
# if you have something further than this far down that's bad you're on your own
for (i in 1:4) {
  moar_dirs <- grep("app$", apps, value=TRUE, invert=TRUE)
  if (length(moar_dirs) > 0) { apps <- c(apps, list.dirs(moar_dirs, recursive=FALSE)) }
apps <- unique(grep("app$", apps, value=TRUE))
pb <- txtProgressBar(0, length(apps), style=3)
suppressWarnings(map_df(1:length(apps), function(i) {
  x <- apps[i]
  setTxtProgressBar(pb, i)
  is_vuln <- FALSE
  version <- ""
  app_name <- sub("\.app$", "", basename(x))
  app_loc <- sub("^/", "", dirname(x))
  to_look <- c(sprintf("%s/Contents/Frameworks/Autoupdate.app/Contents/Info.plist", x),
               sprintf("%s/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist", x),
               sprintf("%s/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist", x))
  is_there <- map_lgl(c(sprintf("%s/Contents/Frameworks/Sparkle.framework/", x), to_look), file.exists)
  has_sparkle <- any(is_there)
  to_look <- to_look[which(is_there[-1])]
  discard(map_chr(to_look, function(x) {
    read_plist(x)$result$CFBundleShortVersionString %||% NA
  }), is.na) -> vs
  if (any(map_dbl(vs, function(v) { safe_compare(v, "1.16.1")$result %||% -1 }) < 0)) {
    is_vuln <- TRUE
    version <- vs[1]
  data_frame(app_loc, app_name, has_sparkle, is_vuln, version)
})) -> app_scan_results
select(arrange(filter(app_scan_results, has_sparkle), app_loc, app_name), -has_sparkle)

To leave a comment for the author, please follow the link and comment on their blog: R – rud.is.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.


Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)