Tôi thấy mã từ các nhà phát triển sử dụng chuyển đổi ngày ẩn. Tôi muốn một câu trả lời dứt khoát về lý do tại sao họ không nên làm điều này.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Tôi thấy mã từ các nhà phát triển sử dụng chuyển đổi ngày ẩn. Tôi muốn một câu trả lời dứt khoát về lý do tại sao họ không nên làm điều này.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Câu trả lời:
Bởi vì '2012/12/1'
ở Mỹ là 11 tháng sau ngày chuỗi tương tự ở châu Âu.
Cho phép chuyển đổi ngầm định có nghĩa là bạn đang tự hào về cài đặt vị trí.
Nếu bạn có thể đặt tên cho một doanh nghiệp trong đó 11 tháng là một lỗi sai có thể chấp nhận được, tôi sẽ rất ấn tượng.
Có những vấn đề sẽ xảy ra nếu một phiên có định dạng ngày khác chạy mã.
Tuyên bố thất bại
DROP TABLE t1;
CREATE TABLE t1 AS (SELECT sysdate mydate FROM dual WHERE 1=2);
ALTER SESSION SET NLS_DATE_FORMAT = 'MON-DD-RR';
INSERT INTO t1 VALUES ('01-02-12');
*
ERROR at line 1:
ORA-01843: not a valid month
Dữ liệu xấu
DROP TABLE t1;
CREATE TABLE t1 AS (SELECT sysdate mydate FROM dual WHERE 1=2);
--User 1
ALTER SESSION SET NLS_DATE_FORMAT = 'MM-DD-RR';
INSERT INTO t1 VALUES ('01-02-11');
--User 2
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-RR';
INSERT INTO t1 VALUES ('01-02-11');
--User 3
ALTER SESSION SET NLS_DATE_FORMAT = 'RR-MM-DD';
INSERT INTO t1 VALUES ('01-02-11');
SELECT to_char(mydate,'MM/DD/YYYY') FROM t1;
Trong tình huống này bởi vì mỗi câu lệnh thay đổi / chèn có thể được thực hiện bởi những người dùng khác nhau. Tất cả họ sẽ chạy cùng một tuyên bố, nhưng ngày kết quả sẽ hoàn toàn khác nhau. Các câu lệnh chèn có thể được chôn trong một gói chỉ được gọi gián tiếp. Bởi vì không có lỗi nào được trả về, vấn đề có thể không được tìm thấy cho đến sau này.
Tiêm SQL
CLEAR SCREEN;
DROP TABLE Secrets;
CREATE TABLE Secrets (RevealDate Date, Secret Varchar2(200));
INSERT INTO Secrets VALUES (trunc(sysdate), '*** Common Knowledge. ***');
INSERT INTO Secrets VALUES (trunc(sysdate+1), '*** Don''t Let Anyone know this. ***');
CREATE OR REPLACE PROCEDURE ShowRevealedSecrets IS
vStatement varchar2(200);
vOutput Varchar2(1000);
vDate date:=sysdate;
begin
vStatement:='SELECT secret FROM Secrets WHERE RevealDate = ''' || vDate || '''';
execute immediate vStatement INTO vOutput;
DBMS_Output.Put_Line(vOutput);
END;
/
--Normal Use.
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YY';
EXEC ShowRevealedSecrets();
--Explointing SQL Injection
ALTER SESSION SET NLS_DATE_FORMAT = '"'' OR RevealDate > sysdate--"';
EXEC ShowRevealedSecrets();
Trong tình huống này, một cá nhân độc hại có thể thay đổi định dạng ngày theo phiên để cung cấp cho họ quyền truy cập vào dữ liệu mà thông thường họ không có quyền truy cập.