wpscanteam/wpscan · error · WPScan::Error::BrowserFailed
SAML authentication needs an interactive terminal to wait fo
Error message
SAML authentication needs an interactive terminal to wait for login, but stdin is not a TTY. Run wpscan from a real shell when using --expect-saml.
What it means
WPScan::Error::BrowserFailed raised at the top of BrowserAuthenticator.authenticate (lib/wpscan/browser_authenticator.rb:13-17) when --expect-saml is used and $stdin is not a TTY. The SAML flow opens a visible browser, waits for you to complete the IdP login, then blocks on a bare 'gets' for you to press enter; without an interactive stdin that handshake is impossible, so it fails fast before launching anything.
Source
Thrown at lib/wpscan/browser_authenticator.rb:14
# frozen_string_literal: true
require 'ferrum'
module WPScan
module BrowserAuthenticator
# Characters that, if present in a cookie name or value, would corrupt the
# serialized Cookie header. Per RFC 6265 these are forbidden in cookie-octets,
# but a noncompliant IdP could still emit them.
COOKIE_DELIMITERS = /[;,\s]/
def self.authenticate(login_url)
unless $stdin.tty?
raise WPScan::Error::BrowserFailed,
'SAML authentication needs an interactive terminal to wait for login, but stdin is not a TTY. ' \
'Run wpscan from a real shell when using --expect-saml.'
end
cookies = run_login_session(login_url)
raise WPScan::Error::SAMLAuthenticationFailed if cookies.nil? || cookies.empty?
serialize_cookies(cookies)
end
# Drives the interactive browser session and returns the resulting cookie jar.
# Translates Ferrum failures into BrowserFailed with a context-specific message.
def self.run_login_session(login_url)
browser = Ferrum::Browser.new(headless: false)
puts 'SAML authentication needed. Log in via the browser window that just opened, then press enter.'
browser.goto(login_url)View on GitHub (pinned to 62c9cef471)
Solutions
- Run wpscan --expect-saml from a real interactive shell (stdin attached to a terminal)
- For containers/ssh allocate a TTY: docker run -it ... or ssh -t
- For automation, drop --expect-saml and authenticate another way the target permits (e.g. --http-auth) or capture cookies once interactively and reuse them per your setup
- If scripting the gem, gate the call: only enable SAML handling when $stdin.tty? is true
Example fix
# before (CI job, stdin is not a TTY) $ wpscan --url https://example.com --expect-saml # => BrowserFailed: SAML authentication needs an interactive terminal ... # after (interactive shell) $ wpscan --url https://example.com --expect-saml # browser opens, log in, press enter in the terminal
Defensive patterns
Strategy: validation
Validate before calling
# Gate the SAML flow on interactivity before invoking the scanner unless $stdin.tty? abort '--expect-saml needs an interactive terminal; re-run from a real shell or drop the flag' end
Try / catch
begin WPScan::BrowserAuthenticator.authenticate(login_url) rescue WPScan::Error::BrowserFailed => e abort e.message # TTY problem or browser problem: neither is retryable in-process end
Prevention
- Never schedule --expect-saml from cron/CI; SAML by definition needs a human at the IdP
- Detect the environment up front: $stdin.tty? and ENV['CI'] checks before building the command
- For containers always start with -it when an interactive flow is expected
When it happens
Trigger: Calling WPScan with expect_saml enabled from cron, systemd, CI runners, nohup, a piped shell (wpscan ... < file, curl ... | wpscan), ssh without -t, or a Docker container started without -t; programmatically calling WPScan::BrowserAuthenticator.authenticate(login_url) in a test or daemon where $stdin has been redirected.
Common situations: Trying to automate SAML-authenticated scans headlessly; running wpscan inside a pipeline stage; scheduled tasks that were tested interactively first; running under a process supervisor (supervisord, Kubernetes job) where stdin is /dev/null.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- SAML authentication is required to access this resource. Ple
- --expect-saml requires Chrome or Chromium to be installed an
- The browser was closed or failed before SAML authentication
- The option #{opt.to_long} is required
- One of the following options is required: #{opt.to_long}, --
AI-assisted analysis of wpscanteam/wpscan@62c9cef471 (2026-08-21).
Data as JSON: /api/errors/dde5d2aea1d50867.
Report an issue: GitHub.