sequelize / sequelize/sequelize
[Reopen] Mismatch date value sql injection checking due to timezone problem in moment.js and moment-timezone.js when using oracle dialect for DataTypes.DATE
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 30.4k
- Forks
- 4.3k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 68
Description
/<!--
If you don't follow the issue template, your issue may be closed.
Remember to properly format your code in code blocks.
Please note this is an issue tracker, not a support forum.
For general questions, please use one of these:
- StackOverflow: https://stackoverflow.com/questions/tagged/sequelize.js
- GitHub discussions: https://github.com/sequelize/sequelize/discussions
-->
Issue Creation Checklist
- I understand that my issue will be automatically closed if I don't fill in the requested information
- I have read the contribution guidelines
Bug Description
In the "src/sql-string.js", found the mismatch of using "moment" for formatting date as compare to using "moment-timezone" in "src/dialects/oracle/data-types.js".
In "src/sql-string.js":
...
// Validate the date value using Moment.js with the expected format
const formattedDate = moment(dateValue).format('YYYY-MM-DD HH:mm:ss.SSS Z');
// If the formatted date doesn't match the input date value, throw an error
if (formattedDate !== dateValue) {
throw new Error("Invalid date value for TO_TIMESTAMP_TZ. Expected format: 'YYYY-MM-DD HH:mm:ss.SSS Z'");
...
In "src/dialects/oracle/data-types.js":
...
_stringify(date, options) {
const format = 'YYYY-MM-DD HH24:MI:SS.FFTZH:TZM';
date = this._applyTimezone(date, options);
const formatedDate = date.format('YYYY-MM-DD HH:mm:ss.SSS Z');
return `TO_TIMESTAMP_TZ('${formatedDate}','${format}')`;
}
_applyTimezone(date, options) {
if (options.timezone) {
if (momentTz.tz.zone(options.timezone)) {
date = momentTz(date).tz(options.timezone);
} else {
date = moment(date).utcOffset(options.timezone);
}
} else {
date = momentTz(date);
}
return date;
}
...
The stringify in oracle dialect data type "DATE" would use the "moment-timezone" for applying timezone, while in the "sql-string.js" checking of using "TO_TIMESTAMP_TZ" to prevent sql injection, it use "moment" with the default timezone in the environment.
There is some problem related to applying timezone for "Asia/Hong_Kong", below is the tested code:
import moment from "moment";
import momentTz from "moment-timezone";
const date = new Date("1904-01-01T00:00:00");
const date1 = moment(date).utcOffset("+00:00");
const date2 = momentTz(date).tz("+00:00");
const date3 = momentTz(date);
const date4 = moment(date).format("YYYY-MM-DD HH:mm:ss.SSS Z");
console.log("Date 1: " + date1.format("YYYY-MM-DD HH:mm:ss.SSS Z"));
console.log("Date 2: " + date2.format("YYYY-MM-DD HH:mm:ss.SSS Z"));
console.log("Date 3: " + date3.format("YYYY-MM-DD HH:mm:ss.SSS Z"));
console.log("Date 4: " + date4);
Outputs:
Date 1: 1903-12-31 16:23:18.000 +00:00
Date 2: 1904-01-01 00:00:00.000 +07:36
Date 3: 1904-01-01 00:00:00.000 +07:36
Date 4: 1904-01-01 00:00:00.000 +07:30
The problem lies into that there is 6 minutes difference between "moment" and "moment-timezone" when applying timezone for "Asia/Hong_Kong" for early dates. With these 6 minutes difference, the above "sql-string.js", "formattedDate" and "dateValue" will never match and throw exception.
You may try the above testing code located in the below link:
moment & moment-timezone test code
Reproducible Example
Here is the link to the SSCCE for this issue:
What do you expect to happen?
What is actually happening?
Environment
- Sequelize version: 6.37.7
- Node.js version: 22.16.0
- If TypeScript related: TypeScript version:
- Database & Version: Oracle DB EE 19c 19.18
- Connector library & Version: oracledb (6.10.0)
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time and I know how to start.
- Yes, I have the time but I will need guidance.
- No, I don't have the time, but my company or I are supporting Sequelize through donations on OpenCollective.
- No, I don't have the time, and I understand that I will need to wait until someone from the community or maintainers is interested in resolving my issue.
Indicate your interest in the resolution of this issue by adding the 👍 reaction. Comments such as "+1" will be removed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the date formatting and validation paths in src/sql-string.js and src/dialects/oracle/data-types.js, then run the linked moment and moment-timezone test code with the reported Oracle environment. Reproduce the early-date Asia/Hong_Kong mismatch and verify that valid Oracle DATE values no longer fail the TO_TIMESTAMP_TZ validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100