i have a program that print reports using JasperReports 5.5.0. The report works perfectly but when I'm thinking about sql injection in my program i can fix it using prepareStatement. My problem is when I use JRDesignQuery to write query because it creates sql injection.
I'm stuck with code jasper report that looks like this
try{
JasperDesign jasperDesign = JRXmlLoader.load(PathSystem.getPath("rpt","report.jrxml"));
String sql = "SELECT * FROM Users WHERE UserId = '" + txtUser.getText() + "'";
JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(sql);
jasperDesign.setQuery(newQuery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,null, conn);
JasperViewer.viewReport(jasperPrint,false);
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e);
}
I can use sql injection with using input "' or 1='1" without the quotes.The sql looks like this :
SELECT * FROM Users WHERE UserId = '' or 1='1'
The report can print all UserId.
I have done research to solve it and found the way to avoid sql injection with using prepareStatement.
This is the code with using prepareStatement :
try {
JasperDesign jasperDesign = JRXmlLoader.load(PathSystem.getPath("rpt","report.jrxml"));
pst = conn.prepareStatement("SELECT * FROM Users WHERE UserId = ?");
pst.setString(1, txtUser.getText());
JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(pst.toString().split("\\:")[1]);
jasperDesign.setQuery(newQuery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,null, conn);
JasperViewer.viewReport(jasperPrint,false);
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e);
}
I wonder if there are any better way to avoid sql injection without using prepareStatement instead.