Commit 65aa08e0 authored by Lucas Fernandes de Oliveira's avatar Lucas Fernandes de Oliveira

Merge branch '20-evitar-sql-injection' into 'develop'

Resolve "Evitar SQL injection"

Closes #20

See merge request !17
parents e5b36158 55c0765e
Pipeline #20149 passed with stages
in 1 minute and 37 seconds
......@@ -4,8 +4,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.0.15 - 26-04-2019
### Added
- A QueryOptions interface, that is used on dbHandler's executeQuery #20
### Changed
- dbHandler's tests to fit into new interface
### Security
- Now dbHandler's executeQuery uses parametrized query to avoid SQL injection
## 0.0.13 - 26-04-2019
## 0.0.14 - 26-04-2019
### Removed
- Dummies files as Item and Collection #16 (Horstmann)
......@@ -15,7 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- A route to POST a form #10 (Horstmann)
- Tests on route POST (Horstmann)
### Changed
- dbHandler's tests to suit with new forms and inputs insertion
- dbHandler's tests to suit with new forms and inputs insertion
## 0.0.12 - 25-04-2019
......
{
"name": "form-creator-api",
"version": "0.0.14",
"version": "0.0.15",
"description": "RESTful API used to manage and answer forms.",
"main": "index.js",
"scripts": {
......
This diff is collapsed.
......@@ -27,6 +27,14 @@ import { EnumHandler, InputType, ValidationType } from "./enumHandler";
import { ErrorHandler} from "./errorHandler";
import { OptHandler } from "./optHandler";
/** Parameters used to create a parametrized query, to avoid SQL injection */
export interface QueryOptions {
/** query string to execute */
query: string;
/** Array of input. containing question */
parameters: any[];
}
/**
* Class of the SGBD from the Form Creator Api perspective. Used to
* perform all the operations into the database that the Form Creator Api
......@@ -55,7 +63,7 @@ export class DbHandler {
* @param cb.result - Query result.
*/
public executeQuery(query: string, cb: (err: Error, result?: QueryResult) => void): void{
public executeQuery(query: QueryOptions , cb: (err: Error, result?: QueryResult) => void): void{
this.pool.connect((err, client, done) => {
......@@ -64,7 +72,7 @@ export class DbHandler {
return;
}
client.query(query, [], (error, result) => {
client.query(query.query, query.parameters, (error, result) => {
// call 'done()' to release client back to pool
done();
cb(error, (result) ? result : null);
......@@ -76,20 +84,20 @@ export class DbHandler {
* Asynchronously ends a transaction
*/
public commit(cb: (err: Error, result?: QueryResult) => void){
this.executeQuery("COMMIT;", cb);
this.executeQuery({query: "COMMIT;", parameters: []}, cb);
}
/**
* Asynchronously rollback a transaction
*/
public rollback(cb: (err: Error, result?: QueryResult) => void){
this.executeQuery("ROLLBACK;", cb);
this.executeQuery({query: "ROLLBACK;", parameters: []}, cb);
}
/**
* Asynchronously starts a transaction
*/
public begin(cb: (err: Error, result?: QueryResult) => void){
this.executeQuery("BEGIN;", cb);
this.executeQuery({query: "BEGIN;", parameters: []}, cb);
}
/**
......@@ -99,7 +107,7 @@ export class DbHandler {
* @param cb.form - list of form or a empty list if there is no form on database.
*/
public listForms(cb: (err: Error, forms?: Form[]) => void){
const query: string = "SELECT id, title, description FROM form;";
const query: QueryOptions = {query: "SELECT id, title, description FROM form;", parameters: []};
const forms: Form[] = [];
this.executeQuery(query, (err: Error, result?: QueryResult) => {
......@@ -138,7 +146,9 @@ export class DbHandler {
* @param cb.form - Form or null if form not exists.
*/
public readForm(id: number, cb: (err: Error, form?: Form) => void){
const query: string = "SELECT id, title, description FROM form WHERE id=" + id + ";";
const queryString: string = "SELECT id, title, description FROM form WHERE id=$1;";
const query: QueryOptions = {query: queryString, parameters: [id]};
waterfall([
(callback: (err: Error, result?: QueryResult) => void) => {
......@@ -202,7 +212,8 @@ export class DbHandler {
* @param cb.inputs - Input array or an empty list if there is no input linked to form.
*/
private readInputWithFormId(id: number, cb: (err: Error, inputs?: InputOptions[]) => void){
const query: string = "SELECT id, placement, input_type, question, description FROM input WHERE id_form=" + id + ";";
const queryString: string = "SELECT id, placement, input_type, question, description FROM input WHERE id_form=$1;";
const query: QueryOptions = {query: queryString, parameters: [id]};
this.executeQuery(query, (err: Error, result?: QueryResult) => {
map(result.rows, (innerResult, callback) => {
......@@ -251,7 +262,11 @@ export class DbHandler {
* @param cb.validations - Validation array or an empty list if there is no validation for selected input.
*/
private readInputValidationWithInputId(id: number, cb: (err: Error, validations?: Validation[]) => void){
const query: string = "SELECT id, validation_type FROM input_validation WHERE id_input=" + id + ";";
const queryString: string = "SELECT id, validation_type FROM input_validation WHERE id_input=$1;";
const query: QueryOptions = {
query: queryString
, parameters: [id]
};
this.executeQuery(query, (err: Error, result?: QueryResult) => {
map(result.rows, (innerResult, callback) => {
......@@ -277,9 +292,13 @@ export class DbHandler {
* @param cb.argumentsArray - Validation Arguments array or an empty list if there is no validation argument for selected input.
*/
private readInputValidationArgumentWithInputValidationId(id: number, cb: (err: Error, argumentsArray?: any[]) => void){
const query: string = "SELECT id, argument, placement FROM \
const queryString: string = "SELECT id, argument, placement FROM \
input_validation_argument WHERE \
id_input_validation=" + id + ";";
id_input_validation=$1;";
const query: QueryOptions = {
query: queryString
, parameters: [id]
};
// cb(null);
......@@ -328,9 +347,14 @@ export class DbHandler {
*/
public writeForm(form: Form, cb: (err: Error, formResult?: Form) => void){
const query: string = "INSERT INTO form (title, description) VALUES\
( \'" + form.title + "\', \'" +
form.description + "\' ) RETURNING id;";
const queryString: string = "INSERT INTO form (title, description) VALUES( $1, $2 ) RETURNING id;";
const query: QueryOptions = {
query: queryString
, parameters: [
form.title
, form.description
]
};
waterfall([
(callback: (err: Error, result?: QueryResult) => void) => {
......@@ -389,12 +413,20 @@ export class DbHandler {
* @param cb.err - Error information when the method fails.
*/
private writeInputWithFormId(formId: number, input: Input, cb: (err: Error) => void){
const query: string = "INSERT INTO input (\
const queryString: string = "INSERT INTO input (\
id_form, placement, input_type, question, description)\
VALUES ( " + formId + ", " + input.placement +
", \'" + EnumHandler.stringfyInputType(input.type) +
"\', \'" + input.question + "\', \'" + input.description +
"\' ) RETURNING id;";
VALUES ( $1, $2, $3, $4, $5) RETURNING id;";
const query: QueryOptions = {
query: queryString
, parameters: [
formId
, input.placement
, EnumHandler.stringfyInputType(input.type)
, input.question
, input.description
]
};
this.executeQuery(query, (err: Error, result?: QueryResult) => {
if (err){
......@@ -427,10 +459,18 @@ export class DbHandler {
* @param cb.err - Error information when the method fails.
*/
private writeValidationWithInputId(inputId: number, validation: Validation, cb: (err: Error) => void){
const query: string = "INSERT INTO input_validation ( id_input, \
validation_type) VALUES ( " + inputId + ", \'" +
EnumHandler.stringfyValidationType(validation.type) +
"\' ) RETURNING id;";
const queryString: string = "INSERT INTO input_validation\
( id_input, validation_type) VALUES\
( $1, $2 ) RETURNING id;";
const query: QueryOptions = {
query: queryString
, parameters: [
inputId
, EnumHandler.stringfyValidationType(validation.type)
]
};
this.executeQuery(query, (err: Error, result?: QueryResult) => {
......@@ -464,10 +504,19 @@ export class DbHandler {
* @param cb.err - Error information when the method fails.
*/
private writeValidationArgumentWithInputIdAndPlacement(validationId: number, argument: string, placement: number, cb: (err: Error) => void){
const query: string = "INSERT INTO input_validation_argument \
( id_input_validation, argument, placement )\
VALUES ( \'" + validationId + "\', \'" +
argument + "\', \'" + placement + "\' ) RETURNING id;";
const queryString: string = "INSERT INTO input_validation_argument \
( id_input_validation, argument, placement ) VALUES\
( $1, $2, $3 ) RETURNING id;";
const query: QueryOptions = {
query: queryString
, parameters: [
validationId
, argument
, placement
]
};
this.executeQuery(query, (err: Error, result?: QueryResult) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment