Report

CVE-2018-20483: wget --xattr leaks userinfo (user:password) into persistent extended attributes

17825afd-e58b-4817-8af5-9b42be44a94c

CVE-2018-20483. wget (versions <= 1.20) when run with --xattr writes the originally-requested URL into the user.xdg.origin.url extended file attribute (and the referrer into user.xdg.referrer.url) on every downloaded file. The URL string used is u->url, which is constructed via url_string(u, URL_AUTH_SHOW) and therefore retains any embedded user:password@ userinfo. set_file_metadata in src/xattr.c only passes this through escnonprint_uri(), which percent-escapes non-printable bytes but does NOT remove credentials. The result is that HTTP basic-auth credentials, FTP login info, and pre-signed query tokens (e.g. AWS sigv4 query params, SAS tokens) get persisted with the file and silently follow it through cp -a, tar --xattrs, package builds, web uploads, etc. Anyone with read access can recover them with getfattr -d <file>. Briefing said: bug class information-leak, call chain main -> retrieve_url -> fd_write_body -> set_file_metadata, hint about extended file attributes.

Steps:

  1. grep -rn set_file_metadata src/wget -> hits src/xattr.c (definition), src/xattr.h, src/http.c:3953/3955, src/ftp.c:1584.
  2. Read src/xattr.c set_file_metadata (lines 59-79): it calls write_xattr_metadata("user.xdg.origin.url", escnonprint_uri(origin_url), fp). Two red flags: (a) the parameter is a raw const char *origin_url, no struct url, so no chance to drop userinfo; (b) escnonprint_uri only handles non-printable chars (confirmed in src/log.c:887).
  3. Looked at the callers in http.c and ftp.c — they all pass u->url, the cached canonical string on the parsed URL.
  4. grep -n 'u->url = ' src/url.c shows u->url is rebuilt with url_string(u, URL_AUTH_SHOW) at url.c:954 and 1188. Read url_string (url.c:2158-2253) and the auth-mode enum (url.h:59-63: URL_AUTH_SHOW / URL_AUTH_HIDE_PASSWD / URL_AUTH_HIDE). Confirmed that URL_AUTH_SHOW emits user:passwd@host verbatim, while URL_AUTH_HIDE skips the userinfo block entirely. Other call sites (recur.c, ftp.c log lines, http.c log lines) already pass URL_AUTH_HIDE_PASSWD when displaying — only the xattr path uses the unsafe form.
  5. Confirmed the call chain matches the briefing: main -> retrieve_url -> http_loop/ftp_loop -> gethttp/getftp where #ifdef ENABLE_XATTR && opt.enable_xattr triggers set_file_metadata. The relevant guard is if (opt.enable_xattr) (i.e. the --xattr CLI flag).