title: Is Java Spring JPA native query SQL injection proof?
body: <p>I'm writing this question because I didn't find any useful article about how to prevent SQL Injection in Spring Data JPA. All the tutorials are showing how to use these queries but they don't mentioned anything about these possible attacks.</p>
  
  <p>I'm having the following query:</p>
  
  <pre><code>@Repository
  public interface UserRepository extends CrudRepository&lt;User, Integer&gt; {
  
      @Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE %:emailAddress%")
      public ResponseList&lt;User&gt; getUsers(@Param("emailAddress") String emailAddress);
  }
  </code></pre>
  
  <p>The rest controller to deliver the request:</p>
  
  <pre><code>@RequestMapping(value = "/get-users", method = RequestMethod.POST)
  public Response&lt;StringResponse&gt; getUsers(WebRequest request) {
      return userService.getUsers(request.getParameter("email"));
  }
  </code></pre>
  
  <p>Are JPQL or native query parameters escaped before executing them?</p>
  
  <p>This is the query with SQL injection executed in my MySQL console which drops the users table:</p>
  
  <pre><code>SELECT * FROM users WHERE email LIKE '%'; DROP TABLE users; -- %';
  </code></pre>
  
  <p>I have tried to execute the SQL attack by sending a POST request to the server:</p>
  
  <pre><code>http://localhost:8080/get-users
  POST: key/value: "email" : "'; DROP TABLE users; --"
  </code></pre>
  
  <p>I have enabled Hibernate's sql logging and this is what the above request produced:</p>
  
  <pre><code>[http-nio-8080-exec-8] DEBUG org.hibernate.SQL - SELECT * FROM users WHERE email LIKE ?
  Hibernate: SELECT * FROM users WHERE email LIKE ?
  
  [http-nio-8080-exec-8] DEBUG org.hibernate.loader.Loader - bindNamedParameters() %'; DROP TABLE users; -- % -&gt; emailAddress [1]
  [http-nio-8080-exec-8] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%'; DROP TABLE users; -- %]
  </code></pre>
  
  <p>The table wasn't dropped (which is good) but why the parameter isn't escaped?</p>
  
  <p>What if I don't annotate the <code>@Param("emailAddress")</code> and I use indexed parameters?:</p>
  
  <pre><code>@Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE ?1")
  public ResponseList&lt;User&gt; getUsers(String email);
  </code></pre>