10

I'm developing a backend to interact with a PostgreSQL database and am looking for some help preventing SQL injection. I understand the concept of SQL injection, and have found some examples online in preventing those attacks, but not sure if prevention techniques differ between SQL providers.

This is the function I use to query data:

var pg = require("pg");

var client = new pg.Client(connectionString);
client.connect();

module.exports = async function newQuery(query) {
        var result = await client.query({
        rowMode: 'array',
        text: query
        });
        return result.rows
}

And here are some standard queries using that function (query()):

SELECT

query("SELECT profilename, profiledescription, approved FROM profiledb 
WHERE usercompany='"+ req.query.userCompany +"';").then(data => {
        res.send(data)
    })

UPDATE

query("UPDATE profiledb SET approved='Approved' WHERE id='"+ req.query.id +"';").then(data =>
    res.send(data)
  )

INSERT

query("INSERT INTO profiledb (profilename, profiledescription, approved) VALUES ('"+ 
req.query.profileTitle +"', '"+ req.query.profileBody +"', 'Pending');");

What code can I use to query the data without risking SQL injection attack.

Thanks!!!

2 Answers 2

23

Use a parameterized query and pass your request arguments as values.

module.exports = async function newQuery(query, values) {
    var result = await client.query({
        rowMode: 'array',
        text: query,
        values
    });
    return result.rows
}

query("SELECT profilename, profiledescription, approved FROM profiledb WHERE usercompany=$1;", [req.query.userCompany]).then(data => {
    res.send(data)
});

query("UPDATE profiledb SET approved='Approved' WHERE id=$1;", [req.query.id]).then(data => {
    res.send(data)
})

query("INSERT INTO profiledb (profilename, profiledescription, approved) VALUES ($1, $2, 'Pending');", [req.query.profileTitle, req.query.profileBody]);
Sign up to request clarification or add additional context in comments.

8 Comments

Is it still possible to inject code with parameterized queries? Just confused how this technique prevents injections.
No, sqli is not possible with parameterised queries. The query text and the values are sent separately to the server, instead of interpolating them to a single query string. The SQL parser doesn't even get to see the values afaik.
@Bergi i am trying to pass column name in parameterized query is there limitation in that context like above example if we pass $1 as column and $2 as value would that work
@RizwanPatel Names (identifiers) cannot be parameterised, only values (literals) can. You need to escape them an build an sql string yourself, e.g. like this.
@TomasJansson Btw, pg-format does take injections into account, and properly escapes all data when building the query string
|
7

You should use parameterized queries or prepared statements, just don't concatenate strings yourself ever. the docs of this specific library are good so i suggest you read them in more details.

queries examples: docs and client.query signature: example

Your query could be written like this:

query("SELECT profilename, profiledescription, approved FROM profiledb 
WHERE usercompany = $1", [req.query.userCompany]).then(...)

same is for updates, and inserts etc. or you can just pass an object with properties: text and values like this

const queryOpts = {
  text: "SELECT profilename, profiledescription, approved FROM profiledb WHERE usercompany = $1",
  values: [req.query.userCompany]
}
query(queryOpts).then(...)

3 Comments

I like this but i'm new to node-postgres. Using your codes, how would you return the result in the callback?
@Grogu result will be present in the "then" block, for example .then(result => { console.log(result.rows)}). if you are new to js, definitely check this question: stackoverflow.com/questions/14220321/…, i think this is what you are asking
How to use %% with $1 I'm getting error, i want to search using ILIKE %$1%

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.