Я вижу код от разработчиков, использующих неявное преобразование даты. Я хотел бы получить окончательный ответ на вопрос, почему они не должны этого делать.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Я вижу код от разработчиков, использующих неявное преобразование даты. Я хотел бы получить окончательный ответ на вопрос, почему они не должны этого делать.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Ответы:
Потому что '2012/12/1'
в США это 11 месяцев после той же строковой даты в Европе.
Разрешение неявных преобразований означает, что вы находитесь в зависимости от настроек местоположения.
Если вы можете назвать компанию, где допустимая погрешность составляет 11 месяцев, я буду впечатлен.
Существуют проблемы, которые могут возникнуть, если код запускается в сеансе с другим форматом даты.
Сбой заявления
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
Плохие данные
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;
В этой ситуации, потому что каждый из операторов изменения / вставки может быть сделан разными пользователями. Все они будут использовать одни и те же утверждения, но итоговые даты будут совершенно другими. Операторы вставки могут быть похоронены в пакете, который вызывается только косвенно. Поскольку никакая ошибка не была возвращена, проблема не может быть найдена намного позже.
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();
В этой ситуации злоумышленник может изменить формат даты сеанса таким образом, чтобы предоставить им доступ к данным, к которым он обычно не имеет доступа.