{"action":"closed","issue":{"url":"https://api.github.com/repos/dropwizard/dropwizard/issues/768","labels_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/768/labels{/name}","comments_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/768/comments","events_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/768/events","html_url":"https://github.com/dropwizard/dropwizard/issues/768","id":47949079,"number":768,"title":"Security issue: Data representation leaks because validation takes places before authentication","user":{"login":"X3Cutor","id":600075,"avatar_url":"https://avatars.githubusercontent.com/u/600075?v=3","gravatar_id":"","url":"https://api.github.com/users/X3Cutor","html_url":"https://github.com/X3Cutor","followers_url":"https://api.github.com/users/X3Cutor/followers","following_url":"https://api.github.com/users/X3Cutor/following{/other_user}","gists_url":"https://api.github.com/users/X3Cutor/gists{/gist_id}","starred_url":"https://api.github.com/users/X3Cutor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/X3Cutor/subscriptions","organizations_url":"https://api.github.com/users/X3Cutor/orgs","repos_url":"https://api.github.com/users/X3Cutor/repos","events_url":"https://api.github.com/users/X3Cutor/events{/privacy}","received_events_url":"https://api.github.com/users/X3Cutor/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dropwizard/dropwizard/labels/security","name":"security","color":"5319e7"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2014-11-06T10:54:20Z","updated_at":"2015-04-07T13:16:00Z","closed_at":"2015-04-07T13:16:00Z","body":"Reported this on the mailing list and was asked to create an issue. I'm attaching some basic code to illustrate the problem.\r\n\r\nMy application\r\n```\r\npublic class TestApplication extends Application<Configuration> {\r\n\r\n    public static void main(String[] args) throws Exception {\r\n        new TestApplication().run(args);\r\n    }\r\n    @Override\r\n    public void initialize(Bootstrap<Configuration> configurationBootstrap) {\r\n\r\n    }\r\n\r\n    @Override\r\n    public void run(Configuration configuration, Environment environment) throws Exception {\r\n        environment.jersey().register(new BasicAuthProvider(new SecuredResourcesAuthenticator(),\"SecuredEndpoints\"));\r\n        environment.getObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);\r\n        ValidatedResource resource = new ValidatedResource();\r\n        environment.jersey().register(resource);\r\n    }\r\n}\r\n```\r\n\r\nMy resource\r\n```\r\n@Produces(MediaType.APPLICATION_JSON)\r\n@Consumes(MediaType.APPLICATION_JSON)\r\n@Path(\"/greet\")\r\npublic class ValidatedResource {\r\n\r\n    @POST\r\n    @Timed\r\n    @ExceptionMetered\r\n    public Object createSolution(@Valid TransportObject validatedObject,@Auth Object userPlaceholder) throws JsonProcessingException {\r\n        String response = \"Hello\";\r\n        return response;\r\n    }\r\n}\r\n```\r\n\r\nThe object with \"secret\" internal representation I only want authenticated people to know about\r\n```\r\npublic class TransportObject {\r\n\r\n    @NotNull\r\n    @Size(min = 1)\r\n    @Pattern(regexp=\"some_regexp_here\")\r\n    private String given_name;\r\n\r\n    public String getGiven_name() {\r\n        return given_name;\r\n    }\r\n\r\n    public void setGiven_name(String given_name) {\r\n        this.given_name = given_name;\r\n    }\r\n}\r\n```\r\n\r\nThe class that \"handles\" authentication by denying everybody\r\n```\r\npublic class SecuredResourcesAuthenticator implements Authenticator<BasicCredentials,Object> {\r\n\r\n    @Override\r\n    public Optional<Object> authenticate(BasicCredentials credentials) throws AuthenticationException {\r\n        //Deny everybody access\r\n        return Optional.absent();\r\n    }\r\n}\r\n```\r\n\r\nI'm using dropwizard 0.7. A POST to http://localhost:8080/greet after the service has been started with an empty JSON body gives the following response:\r\n```\r\n{\r\nerrors: [1]\r\n0:  \"given_name may not be null (was null)\"\r\n-\r\n}\r\n```\r\n\r\nAfter  getting that info I POST\r\n```\r\n{\r\n    \"given_name\": \"\"\r\n}\r\n```\r\nAnd get basically the full internal representation of this rather simple resource\r\n```\r\n{\r\nerrors: [2]\r\n0:  \"given_name must match \"some_regexp_here\" (was )\"\r\n1:  \"given_name size must be between 1 and 2147483647 (was )\"\r\n-\r\n}\r\n```\r\nNow that I figured out how it works, I can POST\r\n```\r\n{\r\n    \"given_name\": \"some_regexp_here\"\r\n}\r\n```\r\nAnd only then am I asked for credentials, which I don't have (valid one's that is) in the first place.\r\n"}}