Les formats de date doivent-ils être spécifiés dans les instructions SQL?


8

Je vois du code de développeurs utilisant une conversion de date implicite. Je voudrais une réponse définitive à la raison pour laquelle ils ne devraient pas faire cela.

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

1
Avez-vous des exemples?
FrustratedWithFormsDesigner

1
@Frustrated Ajout d'un exemple.
Leigh Riffel

J'irais même si loin que vous ne devriez pas non plus utiliser de noms de mois abrégés, sauf si le paramètre NLS_DATE_LANGUAGE est également utilisé dans un appel to_date ()
a_horse_with_no_name

Réponses:


15

Parce que '2012/12/1' États-Unis, c'est 11 mois après la même date de chaîne en Europe.

Autoriser les conversions implicites signifie que vous êtes à la merci des paramètres de localisation.

Si vous pouvez nommer une entreprise où 11 mois est une marge d'erreur acceptable, je serai impressionné.


6
En effet, '01 / 01/11 'pourrait avoir 10 ans de congé. +1
Leigh Riffel

@LeighRiffel: Ou même 110 ans de congé ...
ypercubeᵀᴹ

+1, il ne faut jamais se fier à la conversion DATE implicite (ou à tout casting de type de données implicite)
a_horse_with_no_name

2
«nommez une entreprise où 11 mois est une marge d'erreur acceptable» - les moteurs de généalogie ont tendance à accorder deux ans de chaque côté de l'année d'entrée lors de la recherche dans les registres.
onedaywhen

1
@onedaywhen bonne réponse - comme indiqué, je suis impressionné!
JNK

14

Des problèmes peuvent survenir si une session avec un format de date différent exécute le code.

Échec de la déclaration

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

Données incorrectes

  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;

Dans cette situation, car chacune des instructions alter / insert peut être effectuée par différents utilisateurs. Ils exécuteraient tous les mêmes déclarations, mais les dates résultantes seraient complètement différentes. Les instructions d'insertion peuvent être enfouies dans un package qui n'est appelé qu'indirectement. Puisqu'aucune erreur n'a été renvoyée, le problème peut ne pas être trouvé beaucoup plus tard.

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

Dans cette situation, un individu malveillant pourrait modifier le format de date de ses sessions de manière à lui donner accès à des données auxquelles il n'aurait normalement pas accès.


+1 mais je pense que le cas d'injection SQL est assez étroit.
JNK

1
@JNK Je suis d'accord, et cela risque d'autant plus d'être manqué dans une révision de code.
Leigh Riffel

1
Hors sujet, mais ce livre blanc sur l'injection SQL est génial: accuvant.com/capability/accuvant-labs/security-research/…
Philᵀᴹ
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.