Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isValidDate fails with patterns ending with "yyyy" #299

Closed
meg23 opened this issue Nov 13, 2014 · 16 comments
Closed

isValidDate fails with patterns ending with "yyyy" #299

meg23 opened this issue Nov 13, 2014 · 16 comments

Comments

@meg23
Copy link

meg23 commented Nov 13, 2014

From fagu...@gmail.com on February 14, 2013 05:48:25

What steps will reproduce the problem? 1.Instantiate a DateFormat with "dd/MM/yyyy" pattern
2.Call isValidDate method with "01/01/2AAA" as date What is the expected output? What do you see instead? I expected to get a false as result, but i got a true What version of the product are you using? On what operating system? Version 2.0.1 tested on Windows XP and Solaris both of them with java 1.6.0_33 Does this issue affect only a specified browser or set of browsers? No Please provide any additional information below. If I change the pattern to any other that don´t have "yyyy" at the end of the pattern i get a false as it´s expected.

Some examples:

  DateFormat df=new SimpleDateFormat("dd/MM/yyyy");      
  df.setLenient(true);
  System.out.println("Result:" + instance.isValidDate("Pruebas-", "01/01/2aaa", df, false));

Result:true

  df=new SimpleDateFormat("yyyy/dd/MM");      
  df.setLenient(true);
  System.out.println("Result:"  + instance.isValidDate("Pruebas-", "2aaa/01/01", df, false));

Result:false

  df=new SimpleDateFormat("dd/yyyy/MM");      
  df.setLenient(true);
  System.out.println("Result:"  + instance.isValidDate("Pruebas-", "01/2012'SELECT * FROM user_table'/01", df, false));

Result:false

  df=new SimpleDateFormat("dd/MM/yyyy");      
  df.setLenient(true);
  System.out.println("Result:"  + instance.isValidDate("Pruebas-", "01/01/2012'SELECT * FROM user_table'", df, false));

Result:true

  df=new SimpleDateFormat("dd/yyyy/MM");      
  df.setLenient(true);
  System.out.println("Result:"  + instance.isValidDate("Pruebas-", "01/2aaa/01", df, false));

Result:false

Original issue: http://code.google.com/p/owasp-esapi-java/issues/detail?id=293

@xeno6696
Copy link
Collaborator

@kwwall

After researching this issue, there is a bug... but it's in Java's SimpleDateFormat class.

   public void testIsValidDateToo(){
    	Validator instance = ESAPI.validator();
    	DateFormat df = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);      
    	df.setLenient(false);
    	assertEquals(false, instance.isValidDate("Pruebas-", "01/01/2aaa", df, false));
    	
		df=new SimpleDateFormat("yyyy/dd/MM", Locale.ENGLISH);      
		df.setLenient(false);
		assertEquals(false, instance.isValidDate("Pruebas-", "2aaa/01/01", df, false));
		
		df=new SimpleDateFormat("dd/yyyy/MM", Locale.ENGLISH);      
		df.setLenient(false);
		assertEquals(false, instance.isValidDate("Pruebas-", "01/2012'SELECT * FROM user_table'/01", df, false));
//		Result:false
		
		df=new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);      
		df.setLenient(false);
		assertEquals(false, instance.isValidDate("Pruebas-", "01/01/2012'SELECT * FROM user_table'", df, false));
//		Result:true
		
		df=new SimpleDateFormat("dd/yyyy/MM", Locale.ENGLISH);      
		df.setLenient(false);
		assertEquals(false, instance.isValidDate("Pruebas-", "01/2aaa/01", df, false));
//		Result:false
    }

@xeno6696
Copy link
Collaborator

Ugh... what a bear...

https://stackoverflow.com/q/16014488/557153

I'd been using JodaTime for so long that I completely forgot how god-awful SImpleDateFormat is.

@xeno6696
Copy link
Collaborator

Well, since our goal is to shed dependencies, I can't just fix this with JodaTime.

I think the only option is Java 1.8's new Time API.

@kwwall
Copy link
Contributor

kwwall commented Jul 26, 2017

@xeno6696 Huh; and all this time I figured it was because the bug creator was using setLenient(true).

So, you're saying there's nothing wrong with the Validator.isValidDate() and that the bug in SimpleDateFormat in the test is causing this? Or is the bug (also?) in Validator.isValidDate() because there is a similar bug in java.text.DateFormat as used by DateValidationRule? If only the test case is flawed (because of the SimpleDateFormat bug) I don't any choice but to write our own date parser (not going to happen, at least for this release), close this issue, or leave it open indefinitely until we finally get a JDK where SimpleDateFormat is fixed. What do you and @planetlevel think we ought to do here?

@kwwall
Copy link
Contributor

kwwall commented Jul 26, 2017 via email

@xeno6696
Copy link
Collaborator

@kwwall said"

So, you're saying there's nothing wrong with the Validator.isValidDate() and that the bug in SimpleDateFormat in the test is causing this?

Yep. We ultimately delegate validation to that class. So our method exposes the bad behavior in the original.

@xeno6696
Copy link
Collaborator

My suggestion would be to rewrite or extract the date validation interface such that we can change the underlying implementation at will.

Because of Java's longstanding Date nastiness I've always used JodaTime. We could make JodaTime a test-dependency so we can still apply our date related unit tests and then leave a recommendation that

@xeno6696
Copy link
Collaborator

users use a better implementation.

Not perfect but...

@kwwall
Copy link
Contributor

kwwall commented Jul 27, 2017

That sounds plausible, although we'll have to do so the old fashioned way (unless you can figure out a way to make it work via ObjFactory because ESAPI doesn't support dependency injection. (DI was one think that Chris and I both wanted for ESAPI 3.0. I looked a bit at using Google Guice vs. Spring to do it and Guice is much more lightweight in terms of dependencies, but that's a different topic for a different day.) If you want to spend that much time on it, I'd say go for it, but It's (JodaTime or whatever) has got to be merely a runtime dependency and can't be the default (although I guess it could have scope of 'test'). I don't want people complaining of yet another dependency.

@xeno6696
Copy link
Collaborator

Looks like a possible fix is to use ParsePosition

https://stackoverflow.com/a/15336373/557153

@xeno6696
Copy link
Collaborator

I also discovered that someone created an API to use java 1.8's time API in Java 6 and 7.

@xeno6696
Copy link
Collaborator

It's a small world: The author of Joda Time is also the author of Java 1.8's java.time API. And is also the author of threeten backport.

@kwwall I know that you and others are in an anti-dependency mindset, but this particular date issue could cause SQLi in target applications. I think we should seriously contemplate either JodaTime or this threeten backport to tighten that noose.

Writing a custom date parser seems like obvious overkill. Especially with the wide variety of possible date formats that are Implicitly accepted by our decision to delegate to SimpleDateFormat.

@xeno6696
Copy link
Collaborator

@kwwall
Copy link
Contributor

kwwall commented Jul 28, 2017

Whatever solution will pull in the least # of additional dependencies then. Sure, in theory this could result in SQLi, but chances are better than 50/50 that if they are using this to prevent it, there's probably a half-dozen places in their code where they are not using parametrized queries (e.g., PreparedStatements) at all. But OTOH, I don't want someone blaming ESAPI on them getting hacked even though this really caused by a SimpleDateFormat bug, so do what it takes to fix it. As long as you don't expose JodaTime or whatever you choose, we can always fix it later when we adopt JDK 8.

@xeno6696
Copy link
Collaborator

I think the problem is a bit more severe: implementers use isValidDate in our API under the auspice that it is secure...
It isn't .

I know for a fact I made a hack on a previous project mistakenly blaming ESAPI on an issue like this.

@kwwall
Copy link
Contributor

kwwall commented Jan 23, 2019

Closing as per merge of PR #468

@kwwall kwwall closed this as completed Jan 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants