I'm a few updates behind, currently testing on mIRC 7.67, but I don't see any changes to urlget besides the new "e" switch, so Unsure if this affects any newer versions, but it does for anything 7.67 and below.
I'm using a web-api that requires basic auth. The "username" is my email, and that's where the issue occurs. I'll do a mock-example below to illustrate, as I can't exactly paste a working example without including my userinfo. so We'll just use "localhost"
I first tried something along the lines of:
http://user@gmail.com:pass@localhost/?test=true
NOTE: link works fine in all browsers tested, "URL bar" aslo. 200 OK and some return data from the API call.
noop $urlget(%URI,gbi,&Update,Handle_Update)
results:
* url: (Redacted)
* redirect:
* method: get
* type: binvar
* target: &Update
* alias: Handle_Update
* id: 1026
* state: fail
* size: 1622
* resume: 0
* rcvd: 0
* time: 484
* reply: HTTP/1.1 404 Not Found
Cross-Origin-Resource-Policy: cross-origin
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Tue, 09 Jan 2024 01:20:48 GMT
Server: sffe
Content-Length: 1622
X-XSS-Protection: 0
This totally breaks and connects to gmail.com, makes my request, and naturally gets a 404 not found...
Somehow ignores the beginning and afterward of the URI extracting only the scheme (http) and the host to be "gmail.com" losing the actual host+port, yet somehow manages to retain the proper path to request...
Doing some reading: according to rfc3986 A URI is composed of 5 parts:
<scheme>://<authority>/<path>?<query>#<fragment>
These "tokens" such as <authority> have subsections to be broken down even further such as:
<userinfo>@<host>:<port>
each "token" must follow layout rules, there's reserved characters and unreserved characters. all "reserved" characters should be replaced by it's corresponding percent-encoded equivalent
So I decided to try this URI
http://user%40gmail.com:pass@localhost/?test=true
NOTE: link works fine in all browsers tested, "URL bar" aslo. 200 OK and some return data from the API call.
noop $urlget(%URI,gbi,&Update,Handle_Update)
results:
* url: (Redacted)
* redirect:
* method: get
* type: binvar
* target: &Update
* alias: Handle_Update
* id: 1027
* state: fail
* size: 0
* resume: 0
* rcvd: 0
* time: 1328
* reply: HTTP/1.1 401 Unauthorized
Server: nginx
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache, private
Date: Tue, 09 Jan 2024 01:23:22 GMT
WWW-Authenticate: Basic realm="Update API"
and again a fail, but this time it connected to the proper place! woohoo!
I'm not 100% sure but I assume what happens is the <userinfo> is mime encoded and sent as-is without percent-decoding which sends:
dXNlciU0MGdtYWlsLmNvbTpwYXNz
decoded: user%40gmail.com:pass
and NOT what it should:
dXNlckBnbWFpbC5jb206cGFzcw==
decoded: user@gmail.com:pass
for debug purposes here's the callback alias
alias Handle_Update {
var %id = $1 , %BV = $urlget(%id).target
echo -ai2 * url: $urlget(%id).url
echo -ai2 * redirect: $urlget(%id).redirect
echo -ai2 * method: $urlget(%id).method
echo -ai2 * type: $urlget(%id).type
echo -ai2 * target: $urlget(%id).target
echo -ai2 * alias: $urlget(%id).alias
echo -ai2 * id: $urlget(%id).id
echo -ai2 * state: $urlget(%id).state
echo -ai2 * size: $urlget(%id).size
echo -ai2 * resume: $urlget(%id).resume
echo -ai2 * rcvd: $urlget(%id).rcvd
echo -ai2 * time: $urlget(%id).time
echo -ai2 * reply: $urlget(%id).reply
if ($bvar(%BV,0)) { echo -ai2 * Data : $bvar(%BV,1-).text }
}
For now I have scripted a rather sizeable almost complete drop-in replacement for $urlget() called $wget() to do this with raw sockets. I can include if you'd like so you can test noop $urlget() vs noop $wget() as their syntax and usage is virtually identical. Might post it anyways after some more beta testing. May be handy for those on older versions of windows as well that can't use WinINet.