XX-net/XX-Net · warning

web control ref:%s host:%s

Error message

web control ref:%s host:%s

What it means

CSRF-style check in the POST handler of the web control console: if a Referer header is present and its netloc differs from the Host header and is not in config.allowed_refers, the request is dropped with this warning.

Source

Thrown at code/default/launcher/web_control.py:132

                "Access-Control-Allow-Origin": origin,
                "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS",
                "Access-Control-Allow-Headers": "Authorization,Content-Type",
            }
            return self.send_response(headers=header)
        except Exception as e:
            xlog.exception("options fail:%r", e)
            return self.send_not_found()

    def do_POST(self):
        self.headers = utils.to_str(self.headers)
        self.path = utils.to_str(self.path)

        refer = self.headers.get('Referer')
        if refer:
            refer_loc = urlparse(refer).netloc
            host = self.headers.get('Host')
            if refer_loc != host and refer_loc not in config.allowed_refers:
                xlog.warn("web control ref:%s host:%s", refer_loc, host)
                return

            self.set_CORS(CORS_header)

        try:
            content_type = self.headers.get('Content-Type', "")
            ctype, pdict = cgi.parse_header(content_type)
            if ctype == 'multipart/form-data':
                self.postvars = cgi.parse_multipart(self.rfile, pdict)
            elif ctype == 'application/x-www-form-urlencoded':
                length = int(self.headers.get('Content-Length'))
                content = self.rfile.read(length)
                self.postvars = parse_qs(content, keep_blank_values=True)
                self.postvars = self.unpack_reqs(self.postvars)
            elif ctype == 'application/json':
                length = int(self.headers.get('Content-Length'))
                content = self.rfile.read(length)
                self.postvars = json.loads(content)

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Use the exact same host:port in the browser address bar as the page/posts target.
  2. Add the referring origin to allowed_refers in config.
  3. Send requests without a Referer header or from the served UI itself.

Example fix

// config
"allowed_refers": ["localhost:8085", "127.0.0.1:8085"]
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
ref = urlparse(referer).netloc if referer else ''
if ref and ref != host and ref not in config.allowed_refers:
    raise PermissionError('cross-origin POST rejected')

Prevention

When it happens

Trigger: POSTing to the control API from a page served on a different origin (different host/port) that isn't whitelisted in allowed_refers.

Common situations: Accessing the SWUI via 127.0.0.1 while the page was loaded from localhost (or vice versa), a changed control_port, or third-party pages attempting cross-origin requests.

Related errors


AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27). Data as JSON: /api/errors/aa6974f1237fa2c7. Report an issue: GitHub.