I formati di data devono essere specificati nelle istruzioni SQL?


8

Vedo il codice degli sviluppatori che usano la conversione della data implicita. Vorrei una risposta definitiva al perché non dovrebbero farlo.

SELECT * from dba_objects WHERE Created >= '06-MAR-2012';

1
Hai qualche esempio?
FrustratedWithFormsDesigner

1
@Frustrated Aggiunto un esempio.
Leigh Riffel,

Vorrei anche andare così lontano che non dovresti usare neanche nomi abbreviati del mese a meno che non venga utilizzato anche il parametro NLS_DATE_LANGUAGE in una chiamata to_date ()
a_horse_with_no_name

Risposte:


15

Perché '2012/12/1'negli Stati Uniti è di 11 mesi dopo la stessa data stringa in Europa.

Consentire conversioni implicite significa che sei in balia delle impostazioni della posizione.

Se riesci a nominare un'azienda in cui 11 mesi rappresentano un margine di errore accettabile, rimarrò colpito.


6
In effetti, '01 / 01/11 'potrebbe essere di 10 anni. +1
Leigh Riffel

@LeighRiffel: O anche a 110 anni di pausa ...
ypercubeᵀᴹ

+1, non si dovrebbe mai fare affidamento sulla conversione DATE implicita (o su qualsiasi cast di tipi di dati impliciti che sia)
a_horse_with_no_name

2
"nomina un'azienda in cui 11 mesi rappresentano un margine di errore accettabile" - i motori di genealogia tendono a consentire due anni in entrambi i lati dell'anno di input durante la ricerca dei registri.
giorno

1
@onedayquando una buona risposta - come detto, sono impressionato!
JNK

14

Si verificano problemi se una sessione con un formato data diverso esegue il codice.

Dichiarazione non riuscita

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

Dati errati

  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;

In questa situazione perché ciascuna delle istruzioni alter / insert può essere fatta da utenti diversi. Avrebbero tutti eseguito le stesse dichiarazioni, ma le date risultanti sarebbero completamente diverse. Le istruzioni insert potrebbero essere sepolte in un pacchetto che viene chiamato solo indirettamente. Poiché non è stato restituito alcun errore, il problema potrebbe non essere trovato fino a molto tempo dopo.

SQL Injection

  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();

In questa situazione un individuo malintenzionato potrebbe modificare il formato della data delle sessioni in modo tale da consentire loro l'accesso ai dati a cui normalmente non avrebbero accesso.


+1 ma penso che il caso di iniezione SQL sia piuttosto stretto.
JNK,

1
@JNK Sono d'accordo, e questo rende ancora più probabile la perdita di una revisione del codice.
Leigh Riffel,

1
Fuori tema, ma questo white paper sull'iniezione di SQL è eccezionale: accuvant.com/capability/accuvant-labs/security-research/…
Phil
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.