| Bug #97664 | Connector Node.js rejects URI includes password with certain special characters | ||
|---|---|---|---|
| Submitted: | 16 Nov 2019 4:30 | Modified: | 18 Jan 2020 10:37 |
| Reporter: | Mitani Satoshi (OCA) | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | Connector for Node.js | Severity: | S3 (Non-critical) |
| Version: | 8.0.18 | OS: | Any |
| Assigned to: | Rui Quelhas | CPU Architecture: | Any |
[17 Nov 2019 5:28]
MySQL Verification Team
Hello Mitani, Thank you for the report and feedback. Verified as described. regards, Umesh
[18 Jan 2020 10:37]
Rui Quelhas
Sorry for the late answer and thank you for taking the time to write to us, but this is not a bug.
Connection strings or URIs are based on a convention that stems from RFC
3986. In such constructs, characters like the ones mentioned have a special
meaning, which means they need to be encoded somehow. In this case
'Password#123' would have to be encoded as 'Password%23123', where '#' is
encoded as '%23'. One way to do that in JavaScript, is by using the global
encodeURIComponent() function. So, the following would work as expected:
// using ES6 template strings
mysqlx.getSession(`mysqlx://appuser:${encodeURIComponent('Password#123')}@host
name:33060`)
// using string concatenation (for older ES versions)
mysqlx.getSession('mysqlx://appuser:' + encodeURIComponent('Password#123') +
'@hostname:33060')
Alternatively, one can also use the API based on plain JavaScript Objects to
specify the connection properties. In this case, the following also works:
mysqlx.getSession({ user: 'appuser', password: 'Password#123', host:
'hostname' })
Also, bear in mind that Connector/Node.js is a client based on the X
Protocol, which means it does not use libmysqlclient, and consequently, does
not use C API mentioned in the documentation. The following links provide
more details about Connector/Node.js, the X DevAPI and the X Protocol.
https://dev.mysql.com/doc/dev/connector-nodejs/8.0/
https://dev.mysql.com/doc/x-devapi-userguide/en/
https://dev.mysql.com/doc/internals/en/x-protocol.html

Description: Node.js connector rejects URI includes password with certain special characters. I have confirmed that #(hash), <(lt), >(gt), |(pipe), ^(hat), `(backquote) are rejected. $ node bug.js Error: Invalid userinfo segment at parse (/home/*/node_modules/@mysql/xdevapi/lib/DevAPI/Util/URIParser/parseUserInfo.js:59:15) at parse (/home/*/node_modules/@mysql/xdevapi/lib/DevAPI/Util/URIParser/index.js:67:22) at parseConnectionSpec (/home/*/node_modules/@mysql/xdevapi/index.js:80:20) at Object.exports.getSession (/home/*/node_modules/@mysql/xdevapi/index.js:101:22) at Object.<anonymous> (/home/*/bug.js:3:8) at Module._compile (internal/modules/cjs/loader.js:816:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10) at Module.load (internal/modules/cjs/loader.js:685:32) at Function.Module._load (internal/modules/cjs/loader.js:620:12) at Function.Module.runMain (internal/modules/cjs/loader.js:877:12) MySQL documents says any characters are accepted for password. https://dev.mysql.com/doc/refman/8.0/en/user-names.html > If the user name and password contain only ASCII characters, it is possible to connect to the > server regardless of character set settings. To enable connections when the user name or > password contain non-ASCII characters, client applications should call the mysql_options() > C API function with the MYSQL_SET_CHARSET_NAME option and appropriate character set > name as arguments. This causes authentication to take place using the specified character > set. Otherwise, authentication fails unless the server default character set is the same as the encoding in the authentication defaults. How to repeat: mysqlx = require('@mysql/xdevapi'); mysqlx.getSession('mysqlx://appuser:Password#123@hostname:33060').then(()=>{}).catch(err=>{console.log(err)}) Suggested fix: check URI syntax only. do not check password characters.