Vejo o código dos desenvolvedores usando a conversão implícita de datas. Eu gostaria de uma resposta definitiva para por que eles não deveriam fazer isso.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Vejo o código dos desenvolvedores usando a conversão implícita de datas. Eu gostaria de uma resposta definitiva para por que eles não deveriam fazer isso.
SELECT * from dba_objects WHERE Created >= '06-MAR-2012';
Respostas:
Porque '2012/12/1'
nos EUA 11 meses após a mesma data na Europa.
Permitir conversões implícitas significa que você está à mercê das configurações de localização.
Se você pode nomear uma empresa em que 11 meses é uma margem de erro aceitável, ficarei impressionado.
Existem problemas que ocorrerão se uma sessão com um formato de data diferente executar o código.
Falha na instrução
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
Dados inválidos
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;
Nesta situação, porque cada uma das instruções alter / insert pode ser feita por diferentes usuários. Todos eles executariam as mesmas instruções, mas as datas resultantes seriam completamente diferentes. As instruções de inserção podem estar ocultas em um pacote que está sendo chamado apenas indiretamente. Como nenhum erro foi retornado, o problema pode não ser encontrado até muito mais tarde.
Injeção 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();
Nessa situação, um indivíduo mal-intencionado pode alterar o formato da data das sessões de forma a fornecer acesso a dados aos quais normalmente não teriam acesso.