日期范围验证代码漏洞排查:为何错误范围未被拦截?
问题分析与修复方案
你的日期验证代码存在两个关键漏洞,导致错误的日期范围无法被正确检测:
1. JavaScript Date构造函数的月份是0索引的
JavaScript中new Date(year, month, day)的month参数是从0开始计数的(0对应1月,1对应2月,…,11对应12月)。你的ConvertForDate函数直接将拆分后的月份字符串dataArray[1]传入,没有减1,导致所有月份都被向后偏移了一个月,直接打乱了日期的真实顺序。
2. 无效日期的自动修正
当你传入一个不存在的日期(比如2月31日)时,JavaScript会自动将其修正为一个有效日期(比如2018年2月31日会被修正为2018年3月3日),这会让原本应该触发告警的错误日期范围(比如结束日期早于开始日期)被错误地判定为合法。
修复后的完整代码
function ValidateDates() { var data1 = $("#<%=txtDtSt.ClientID%>").val(); var data2 = $("#<%=txtDtEnd.ClientID%>").val(); var dateStart = ConvertForDate(data1); var dateEnd = ConvertForDate(data2); // 先校验日期转换是否成功(过滤无效日期格式) if (!dateStart || !dateEnd) { criarDivAlert("Alert", "Invalid date format."); exibirAlerta(false); return; } if (dateEnd < dateStart ) { criarDivAlert("Alert", "Range Incorrect."); exibirAlerta(false); $("#<%=txtDtEnd.ClientID %>").val(''); $("#<%=txtDtEnd.ClientID%>").focus(); } } function ConvertForDate(data) { var dataArray = data.split('/'); // 确保日期格式是预期的日/月/年结构 if (dataArray.length !== 3) return null; var day = parseInt(dataArray[0], 10); var month = parseInt(dataArray[1], 10) - 1; // 月份减1,适配Date的0索引规则 var year = parseInt(dataArray[2], 10); // 创建日期对象并验证是否为有效日期(避免自动修正无效值) var newDate = new Date(year, month, day); if (newDate.getFullYear() !== year || newDate.getMonth() !== month || newDate.getDate() !== day) { return null; // 返回null标记为无效日期 } return newDate; }
关键修复点说明
- 月份索引修正:在转换月份时执行
month = parseInt(dataArray[1], 10) - 1,确保1月对应0,12月对应11,还原日期的真实月份。 - 无效日期检测:创建Date对象后,验证其年、月、日是否与输入值完全一致,如果不一致说明是被自动修正的无效日期,返回
null并在验证函数中提示格式错误。 - 格式前置校验:先检查拆分后的数组长度是否为3,避免非预期的日期格式导致转换逻辑混乱。
以你的测试场景为例:
- 开始日期
02/01/2018会被正确转换为2018-01-02(1月2日) - 结束日期
31/01/2018会被正确转换为2018-01-31(1月31日),此时结束日期晚于开始日期,不会触发告警(符合规则预期)。如果你的测试场景实际是开始日期为31/01/2018,结束日期为02/01/2018,修复后的代码会准确检测到结束日期早于开始日期,触发告警提示。
内容的提问来源于stack exchange,提问作者Igor Carreiro
相关产品推荐
相关产品推荐

