0

I made a simplke add that detects whether http body is base64 endoded:


const connect = require('connect');

const base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/;
const isBase64 = (str) => base64RegExp.test(str)


const app = connect();


app.use(function(req,res,next){
     
    var body = [];

    req.on('data',(data) =>
    {
        console.log('Getting Body');
        body.push(data)
    });

    req.on('end',() => {
        body = body.toString();
        res.setHeader("Content-Type",'text/plain');
        res.writeHead(200);

        if(isBase64(body)){
            res.end("BOdy base64 encoded\n");
        } else {
            res.end("BOdy not base64 encoded\n");
        }
      
    });
});

app.listen(8090);

But once I do:

base64 ~/Εικόνες/IMG_20230124_114954.jpg | curl --request POST --data @-  http://127.0.0.1:8090

I get:

BOdy not base64 encoded

Meaning that the app, fails to recognize a base64 encoded string as base64 enbcoded string. Any idea why fails to do so?

I tried to use the approach mentioned upon this answer

Approach 1

Furthermore I tried to use:

  if(isBase64(body.replace("\n","").replace("\r",""))){
    res.end("BOdy base64 encoded\n");
  } else {
    res.end("BOdy not base64 encoded\n");
  }

Still I get same result.

approach 2:

I also tried this to fix it:


const connect = require('connect');

// const base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/;
const isBase64 = (str) => Buffer.from(str.replace("\n","").replace("\r",""), 'base64').toString('base64') === str

const app = connect();


app.use(function(req,res,next){
     
    var body = [];

    req.on('data',(data) =>
    {
        console.log('Getting Body');
        body.push(data)
    });

    req.on('end',() => {
        body = body.toString();
        res.setHeader("Content-Type",'text/plain');
        res.writeHead(200);

        if(isBase64(body.replace("\n","").replace("\r",""))){
            res.end("BOdy base64 encoded\n");
        } else {
            res.end("BOdy not base64 encoded\n");
        }
      
    });
});

app.listen(8090);

Same result despite sending base64 encoded data

Dimitrios Desyllas
  • 9,082
  • 15
  • 74
  • 164
  • Wouldn't it be easier to just parse the string and see if it errors? Also weird to use base64 encoding for something like this but alas. – Evert Apr 05 '23 at 18:29
  • Is your regex considering newlines? – Evert Apr 05 '23 at 18:30
  • I need in order to make a reverse Http proxy @Evert for aiding me development upon http. Therefore, I need to check whether string is base64 or not. – Dimitrios Desyllas Apr 05 '23 at 18:36

1 Answers1

1

curl sent the data as a URL-encoded form by default. The + characters in the Base64-encoded string were being interpreted as spaces, causing the regular expression test to fail. You needed to set the Content-Type header to application/octet-stream :

base64 ~/Εικόνες/IMG_20230124_114954.jpg | \
curl --request POST \
--data-binary @- \
--header "Content-Type: application/octet-stream" \
http://127.0.0.1:8090

Data received by the server could be split into chunks, which caused the regular expression test to fail. You needed to concatenate the chunks of data before converting them to a string and testing against regex :

req.on('end', () => {
  body = Buffer.concat(body).toString();
  // 
});

Additionally, you can make your isBase64 function more robust by stripping out newlines, carriage returns, and spaces:

const isBase64 = (str) => {
  const cleanedStr = str.replace(/[\n\r\s]+/g, '');
  return base64RegExp.test(cleanedStr);
};

Full code :

const connect = require('connect');

const base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/;

const isBase64 = (str) => {
  const cleanedStr = str.replace(/[\n\r\s]+/g, '');
  return base64RegExp.test(cleanedStr);
};

const app = connect();

app.use(function (req, res, next) {
  let body = [];

  req.on('data', (data) => {
    console.log('Getting Body');
    body.push(data);
  });

  req.on('end', () => {
    body = Buffer.concat(body).toString();
    res.setHeader('Content-Type', 'text/plain');
    res.writeHead(200);

    if (isBase64(body)) {
        console.log(body);
      res.end('Body base64 encoded\n');
    } else {
      res.end('Body not base64 encoded\n');
    }
  });
});

app.listen(8090);
Wahyu Kristianto
  • 8,719
  • 6
  • 43
  • 68