├── README.md ├── pom.xml └── src └── main ├── java └── hqli │ ├── core │ └── MyApplication.java │ ├── persistent │ ├── Constants.java │ ├── Post.java │ └── PostRepository.java │ └── web │ ├── PostController.java │ └── PostDto.java ├── resources └── META-INF │ └── persistence.xml └── webapp └── WEB-INF └── beans.xml /README.md: -------------------------------------------------------------------------------- 1 | ####HQLi playground 2 | I wrote this vulnerable application for studying JPQL/HQL injections. 3 | 4 | ####How I can use it 5 | - Install Apache Maven and build war package. 6 | 7 | `mvn install` 8 | 9 | - Download J2EE application server (WildFly, GlassFish, WebLogic, TomEE, WAS). Install JDBC driver for desired DBMS. 10 | - Create database and table with name 'post' in the database. 11 | - Create and configure datasource with name 'HQLiDS'. 12 | - Have fun! -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | hqli 8 | playground 9 | 1.0-0 10 | war 11 | 12 | 13 | 14 | 15 | javax 16 | javaee-api 17 | 7.0 18 | 19 | 20 | 21 | 22 | 23 | hqli.playground 24 | 25 | 26 | org.apache.maven.plugins 27 | maven-compiler-plugin 28 | 29 | 1.7 30 | 1.7 31 | 32 | 33 | 34 | maven-war-plugin 35 | 36 | false 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/java/hqli/core/MyApplication.java: -------------------------------------------------------------------------------- 1 | package hqli.core; 2 | 3 | import javax.ws.rs.ApplicationPath; 4 | import javax.ws.rs.core.Application; 5 | 6 | @ApplicationPath("/") 7 | public class MyApplication extends Application { 8 | } -------------------------------------------------------------------------------- /src/main/java/hqli/persistent/Constants.java: -------------------------------------------------------------------------------- 1 | package hqli.persistent; 2 | 3 | public class Constants { 4 | 5 | public static final String S_QUOTE = "'"; 6 | 7 | public static final String HQL_PART = "select * from Post where name = '"; 8 | 9 | public static final char C_QUOTE_1 = '\''; 10 | 11 | public static final char C_QUOTE_2 = '\047'; 12 | 13 | public static final char C_QUOTE_3 = 39; 14 | 15 | public static final char C_QUOTE_4 = 0x27; 16 | 17 | public static final char C_QUOTE_5 = 047; 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/hqli/persistent/Post.java: -------------------------------------------------------------------------------- 1 | package hqli.persistent; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name = "post") 7 | public class Post { 8 | 9 | @Id 10 | @GeneratedValue(strategy = GenerationType.IDENTITY) 11 | @Column(name = "id") 12 | private int id; 13 | 14 | @Column(name = "name") 15 | private String name; 16 | 17 | public Post() { 18 | } 19 | 20 | public Post(String name) { 21 | this.name = name; 22 | } 23 | 24 | public int getId() { 25 | return id; 26 | } 27 | 28 | public void setId(int id) { 29 | this.id = id; 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/hqli/persistent/PostRepository.java: -------------------------------------------------------------------------------- 1 | package hqli.persistent; 2 | 3 | import javax.ejb.LocalBean; 4 | import javax.ejb.Stateless; 5 | import javax.ejb.TransactionAttribute; 6 | import javax.ejb.TransactionAttributeType; 7 | import javax.persistence.EntityManager; 8 | import javax.persistence.PersistenceContext; 9 | import javax.persistence.Query; 10 | import javax.persistence.criteria.CriteriaBuilder; 11 | import javax.persistence.criteria.CriteriaQuery; 12 | import javax.persistence.criteria.Root; 13 | import java.util.List; 14 | 15 | @Stateless 16 | @LocalBean 17 | public class PostRepository { 18 | 19 | @PersistenceContext(unitName = "HQLiDS") 20 | private EntityManager em; 21 | 22 | @TransactionAttribute(TransactionAttributeType.REQUIRED) 23 | public void save(Post post) { 24 | em.persist(post); 25 | } 26 | 27 | public List getByName_Insecure(String name) { 28 | Query query = em.createQuery("SELECT p FROM Post p where p.name='" + name + "'", Post.class); 29 | return (List) query.getResultList(); 30 | } 31 | 32 | public List getByName_Secure(String name) { 33 | Query query = em.createQuery("SELECT p FROM Post p where p.name=:name", Post.class); 34 | query.setParameter("name", name); 35 | return (List) query.getResultList(); 36 | } 37 | 38 | public List getByName_Criteria(String name) { 39 | CriteriaBuilder builder = em.getCriteriaBuilder(); 40 | CriteriaQuery criteria = builder.createQuery(Post.class); 41 | Root pRoot = criteria.from(Post.class); 42 | criteria.where(builder.equal(pRoot.get("name"), name)); 43 | 44 | Query query = em.createQuery(criteria); 45 | return (List) query.getResultList(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/hqli/web/PostController.java: -------------------------------------------------------------------------------- 1 | package hqli.web; 2 | 3 | import hqli.persistent.Post; 4 | import hqli.persistent.PostRepository; 5 | 6 | import javax.ejb.Stateless; 7 | import javax.inject.Inject; 8 | import javax.ws.rs.*; 9 | import javax.ws.rs.core.MediaType; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | @Stateless 17 | @Path("/") 18 | public class PostController { 19 | 20 | @Inject 21 | private PostRepository postRepository; 22 | 23 | @GET 24 | @Path("/{name}") 25 | @Produces(MediaType.APPLICATION_JSON) 26 | public List doName_Insecure(@PathParam("name") String name) { 27 | 28 | List posts = postRepository.getByName_Insecure(name); 29 | 30 | List dtos = new ArrayList<>(); 31 | 32 | for (Post post : posts) { 33 | dtos.add(new PostDto(post.getId(), post.getName())); 34 | } 35 | 36 | return dtos; 37 | } 38 | 39 | @GET 40 | @Path("/secure/{name}") 41 | @Produces(MediaType.APPLICATION_JSON) 42 | public List doName_Secure(@PathParam("name") String name) { 43 | 44 | List posts = postRepository.getByName_Secure(name); 45 | 46 | List dtos = new ArrayList<>(); 47 | 48 | for (Post post : posts) { 49 | dtos.add(new PostDto(post.getId(), post.getName())); 50 | } 51 | 52 | return dtos; 53 | } 54 | 55 | 56 | @GET 57 | @Path("/secure2/{name}") 58 | @Produces(MediaType.APPLICATION_JSON) 59 | public List doName_Secure2(@PathParam("name") String name) throws Exception { 60 | 61 | List posts = postRepository.getByName_Criteria(name); 62 | 63 | List dtos = new ArrayList<>(); 64 | 65 | for (Post post : posts) { 66 | dtos.add(new PostDto(post.getId(), post.getName())); 67 | } 68 | 69 | return dtos; 70 | } 71 | 72 | @POST 73 | @Path("/{name}") 74 | @Produces(MediaType.APPLICATION_JSON) 75 | public Map doAdd(@PathParam("name") String name) { 76 | 77 | postRepository.save(new Post(name)); 78 | 79 | return new HashMap() {{ 80 | put("message", "ok"); 81 | }}; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/hqli/web/PostDto.java: -------------------------------------------------------------------------------- 1 | package hqli.web; 2 | 3 | import javax.xml.bind.annotation.XmlElement; 4 | import javax.xml.bind.annotation.XmlRootElement; 5 | 6 | @XmlRootElement 7 | public class PostDto { 8 | 9 | @XmlElement 10 | private int id; 11 | 12 | @XmlElement 13 | private String name; 14 | 15 | public PostDto(){ 16 | 17 | } 18 | 19 | public PostDto(int id, String name) { 20 | this.id = id; 21 | this.name = name; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | java:jboss/datasources/HQLiDS 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | --------------------------------------------------------------------------------