Search code examples
sqlnode.jsprepared-statementnode-sqlite3

NodeJS SQLite3 prepared statement with IN and AND


I have this API setup in Express but I cannot figure out how to correctly prepare the language filter with the IN statement using SQLite3 in node.js.

The first query applies the language filter correctly. I get the correct results but this could pose a sql injection risk.

The second query finds no results because of the language filter.

How do I correctly setup the db.prepare statement to accept both words, and language?

app.post('/api/languages/:language/getTextWords', (req, res) => {
    let words = req.body.map(word => word.toLowerCase())
    let wordMap = words.map(() => "?").join(',')
    let language = req.params.language.toLowerCase();

    // the language filter is applied correctly I get results but the statement is not fully prepared
    // let query = db.prepare(`SELECT * FROM words WHERE word IN (${wordMap}) AND language = '${language}'`, words) 
    
    // no results are found because of the language filter
    let query = db.prepare(`SELECT * FROM words WHERE word IN (${wordMap}) AND language = '?'`, words, language)
    query.all((err, rows) => {
        if (err) {
            res.status(500).send(err.message)
            throw err;
        }

        if (!rows) {
            res.json([])
        }

        if (rows) {
            res.json(rows)
        }
    })
})

Here is a screenshot of the DB table in question: words table


Solution

  • pass values as an array:

    let query = db.prepare(`SELECT * FROM words WHERE word IN (${wordMap}) AND language = ?`, [...words, language]);