skip to Main Content

I am trying to make an updateItem call to DynamoDB from an Express server hosted on a Lambda. I am trying to update a nested field in the "users" table called "general" that itself has the fields "gender" and "about". This is my PATCH request so far:


app.patch("/profile/general", async function (req, res) {
  
  let params; 

  let newGender; 
  let newAbout;

  if (req.body.general){
    if (req.body.general.gender){
      newGender =  req.body.general.gender
    }
    if (req.body.general.about){
      newAbout =  req.body.general.about
    }

    params = {
      TableName: "users",
      Key: {
        'id': { 'S': req.user.sub },
      },
      UpdateExpression: `set general.gender = ${newGender}, general.about = ${newAbout}`, 
      ReturnValues: "ALL_NEW",
    };
  }

  try {
    let newUserObj = await dynamodb.updateItem(params).promise(); 
    console.log("newUserObj: ", newUserObj); 
    res.json({ "newData": newUserObj });
  } catch (err){
    console.log("error: ", err); 
    res.json({ "error": err });
  }
});

With this setup, I get an error if there is the word "like" within the incoming req.body.general.about string. For example, if the knew incoming string for req.body.general.about is "I like cookies", then I get the error "ValidationException: Invalid UpdateExpression: Syntax error; token: "like"" in CloudWatch. So, is there a way to account for request keywords and make the lambda treat them as just part of the incoming String field? Of course, there are probably many similar keywords that would trigger a similar error.

Thanks

2

Answers


  1. Use ExpressionAttributeNames and ExpressionAttributeValues always:

        params = {
          TableName: "users",
          Key: {
            'id': { 'S': req.user.sub },
          },
          UpdateExpression: `set #g.#gn = :ng, #g.#a = :na`, 
          ExpressionAttributeNames: {
             '#g': 'general', 
             '#gn': 'gender',
             '#a': 'about'
          },
          ExpressionAttributeValues: {
             ':ng': {'S': newGender}, 
             ':na': {'S': newAbout}, 
          },
          ReturnValues: "ALL_NEW",
        };
      }
    
    Login or Signup to reply.
  2. When you use values that contain reserved words, spaces or special characters you have to parameterize the expression. This is recommended anyway, to prevent attackers from injecting malicious commands. For details, take a look at the documentation.

    To solve this issue, you can modify your UpdateExpression and add ExpressionAttributeValues:

        // ...
    
        params = {
          TableName: "users",
          Key: {
            'id': { 'S': req.user.sub },
          },
          UpdateExpression: `set general.gender = :g, general.about = :a`,
          ExpressionAttributeValues: {
            ':g': { 'S': newGender },
            ':a': { 'S': newAbout },
          },
          ReturnValues: "ALL_NEW",
        };
    
        // ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search