Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deps): update dependency hono to v4 [security] #24

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Feb 25, 2024

Mend Renovate

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
hono (source) ^3.4.3 -> ^4.0.0 age adoption passing confidence

GitHub Vulnerability Alerts

CVE-2023-50710

Impact

The clients may override named path parameter values from previous requests if the application is using TrieRouter. So, there is a risk that a privileged user may use unintended parameters when deleting REST API resources.

TrieRouter is used either explicitly or when the application matches a pattern that is not supported by the default RegExpRouter.

The code to reproduce it. The server side application:

import { Hono } from 'hono'
import { TrieRouter } from 'hono/router/trie-router'

const wait = async (ms: number) => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

const app = new Hono({ router: new TrieRouter() })

app.use('*', async (c, next) => {
  await wait(Math.random() * 200)
  return next()
})

app.get('/modules/:id/versions/:version', async (c) => {
  const id = c.req.param('id')
  const version = c.req.param('version')

  console.log('path', c.req.path)
  console.log('version', version)

  return c.json({
    id,
    version,
  })
})

export default app

The client code which makes requests to the server application:

const examples = [
  'http://localhost:8787/modules/first/versions/first',
  'http://localhost:8787/modules/second/versions/second',
  'http://localhost:8787/modules/third/versions/third',
]

const test = () => {
  for (const example of examples) {
    fetch(example)
      .then((response) => response.json())
      .then((data) => {
        const splitted = example.split('/')
        const expected = splitted[splitted.length - 1]

        if (expected !== data.version) {
          console.error(`Error: exprected ${expected} but got ${data.version} - url was ${example}`)
        }
      })
  }
}

test()

The results:

Error: exprected second but got third - url was http://localhost:8787/modules/second/versions/second
Error: exprected first but got third - url was http://localhost:8787/modules/first/versions/first

Patches

"v3.11.7" includes the change to fix this issue.

Workarounds

Don't use TrieRouter directly.

// DON'T USE TrieRouter
import { TrieRouter } from 'hono/router/trie-router'
const app = new Hono({ router: new TrieRouter() })

References

Router options on the Hono website: https://hono.dev/api/hono#router-option

CVE-2024-32869

Summary

When using serveStatic with deno, it is possible to directory traverse where main.ts is located.

My environment is configured as per this tutorial
https://hono.dev/getting-started/deno

PoC

$ tree
.
├── deno.json
├── deno.lock
├── main.ts
├── README.md
└── static
    └── a.txt

source

import { Hono } from 'https://deno.land/x/hono@v4.2.6/mod.ts'
import { serveStatic } from 'https://deno.land/x/hono@v4.2.6/middleware.ts'

const app = new Hono()
app.use('/static/*', serveStatic({ root: './' }))

Deno.serve(app.fetch)

request

curl localhost:8000/static/%2e%2e/main.ts

response is content of main.ts

Impact

Unexpected files are retrieved.


Release Notes

honojs/hono (hono)

v4.2.7

Compare Source

This release fixes "Restricted Directory Traversal in serveStatic with deno".

Full Changelog: honojs/hono@v4.2.6...v4.2.7

v4.2.6

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.2.5...v4.2.6

v4.2.5

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.2.4...v4.2.5

v4.2.4

Compare Source

What's Changed
New Contributors

Full Changelog: honojs/hono@v4.2.3...v4.2.4

v4.2.3

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.2.2...v4.2.3

v4.2.2

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.2.1...v4.2.2

v4.2.1

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.2.0...v4.2.1

v4.2.0

Compare Source

Hono v4.2.0 is now available! Let's take a look at the new features.

Added more algorithms for JWT

The number of algorithms that JWT util can handle has increased from only 3 to 13! This means that JWT util now implements many of the algorithms supported by JWT.

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512
  • ES256
  • ES384
  • ES512
  • EdDSA

You can use these algorithms from the JWT middleware or JWT helpers. Thanks @​Code-Hex!

Method Override Middleware

Method Override Middleware has been added. This middleware override the method of the real request with the specified method.

HTML form does not allow you to send a DELETE method request. Instead, by sending an input with name as _method and a value of DELETE, you can call the handler registered in app.delete().

const app = new Hono()

// If no options are specified, the value of `_method` in the form,
// e.g. DELETE, is used as the method.
app.use('/posts', methodOverride({ app }))

app.delete('/posts', (c) => {
  // ....
})

Trailing Slash Middleware

Trailing Slash Middleware resolves the handling of Trailing Slashes in GET requests. You can use appendTrailingSlash and trimTrailingSlash functions.

For example, it redirects a GET request to /about/me to /about/me/.

import { Hono } from 'hono'
import { appendTrailingSlash } from 'hono/trailing-slash'

const app = new Hono({ strict: true })

app.use(appendTrailingSlash())
app.get('/about/me/', (c) => c.text('With Trailing Slash'))

Thanks @​rnmeow!

Other features

All Updates

New Contributors

Full Changelog: honojs/hono@v4.1.7...v4.2.0

v4.1.7

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.1.6...v4.1.7

v4.1.6

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.1.5...v4.1.6

v4.1.5

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.1.4...v4.1.5

v4.1.4

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.1.3...v4.1.4

v4.1.3

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.1.2...v4.1.3

v4.1.2

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.1.1...v4.1.2

v4.1.1

Compare Source

What's Changed
New Contributors

Full Changelog: honojs/hono@v4.1.0...v4.1.1

v4.1.0

Compare Source

Hono v4.1.0 is now available! Let's take a look at the new features.

WebSocket Helper

Now Hono supports WebSockets! With WebSocket helper, you can easily handle WebSockets in your application. Currently, Cloudflare Workers / Pages, Deno, and Bun adapters are available.

const app = new Hono()

app.get(
  '/ws',
  upgradeWebSocket((c) => {
    return {
      onMessage(event, ws) {
        console.log(`Message from client: ${event.data}`)
        ws.send('Hello from server!')
      },
      onClose: () => {
        console.log('Connection closed')
      }
    }
  })
)

PRC mode is now also supported for WebSockets endpoints. The following is a demo.

WebSocket Helper

Thanks @​nakasyou!

Body Limit Middleware

Introducing Body Limit Middleware. This middleware can limit the file size of the request body.

const app = new Hono()

app.post(
  '/upload',
  bodyLimit({
    maxSize: 50 * 1024, // 50kb
    onError: (c) => {
      return c.text('overflow :(', 413)
    }
  }),
  async (c) => {
    const body = await c.req.parseBody()
    if (body['file'] instanceof File) {
      console.log(`Got file sized: ${body['file'].size}`)
    }
    return c.text('pass :)')
  }
)

Thanks @​EdamAme-x and @​usualoma!

ES2022

We made the target in the tsconfig.json as ES2022 instead of ES2020. So, the generated JavaScript files are now ES2022. That made the file size smaller! The following is the result of the minify and build of "Hello World" with Wrangler.

// ES2020
hono => Total Upload: 20.15 KiB / gzip: 7.42 KiB
hono/tiny => Total Upload: 12.74 KiB / gzip: 4.69 KiB
// ES2022
hono => Total Upload: 18.46 KiB / gzip: 7.09 KiB
hono/tiny => Total Upload: 11.12 KiB / gzip: 4.38 KiB

Performance has also been improved in some Node.js environments.

SS

Other features
All Updates
New Contributors

Full Changelog: honojs/hono@v4.0.10...v4.1.0

v4.0.10

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.9...v4.0.10

v4.0.9

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.8...v4.0.9

v4.0.8

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.0.7...v4.0.8

v4.0.7

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.6...v4.0.7

v4.0.6

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.5...v4.0.6

v4.0.5

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.4...v4.0.5

v4.0.4

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.3...v4.0.4

v4.0.3

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.2...v4.0.3

v4.0.2

Compare Source

This is a patch release. But, it includes a minor feature.

SSG helper now generates HTML files only if they are handling GET or ALL methods.

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.0.1...v4.0.2

v4.0.1

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.0.0...v4.0.1

v4.0.0

Compare Source

Going to full-stack.

Hono v4.0.0 is out! This major update includes some breaking changes and the addition of three major features.

  1. Static Site Generation
  2. Client Components
  3. File-based Routing

So Hono is going to full-stack. Let's take a look at the three features.

1. Static Site Generation

We introduce SSG Helper. With it you can generate static pages of your Hono applications.

To use this, create a separate file build.ts from the application and call the toSSG() function in it.

import fs from 'node:fs/promises'
import { toSSG } from 'hono/ssg'
import app from './src/index'

toSSG(app, fs)

There are adapters for Bun and Deno, so you can write shorter for Bun, for example.

import { toSSG } from 'hono/bun'
import app from './src/index'

toSSG(app)

And, just run it.

bun ./build.ts

Then HTML is generated.

$ ls static
about.html  index.html

You can easily deploy this page to Cloudflare Pages, etc.

$ wrangler pages deploy static
With Vite

We have created a plugin @hono/vite-ssg for Vite. By using this, you will be able to develop and build a static sites with just the vite command.

The configuration is the following:

import build from '@​hono/vite-ssg'
import devServer from '@​hono/vite-dev-server'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    build(),
    devServer({
      entry: 'src/index.tsx'
    })
  ]
})

If you want to develope, just run the command:

vite

If you want to build, just run the command:

vite build

In combination with the deployment mentioned above to Cloudflare Pages, you can develop, SSG build, and deploy non-stop. And each of them is extremely fast (the video is 2x faster).

Screen cast

2. Client Components

hono/jsx was originally designed to run server-side as an alternative to template engines such as Mustache. Server-side JSX is an interesting experiment, creating a new stack to combine with HTMX and Alpine.js. But that's not all.

Now, hono/jsx runs on the client as well. We call it hono/jsx/dom or Client Components.

The exact same code as React runs with Hono's JSX.

import { useState } from 'hono/jsx'
import { render } from 'hono/jsx/dom'

function Counter() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

function App() {
  return (
    <html>
      <body>
        <Counter />
      </body>
    </html>
  )
}

const root = document.getElementById('root')
render(<App />, root)

The Hooks listed below are also implemented and you can create Client Components just like in React.

  • useContext
  • useEffect
  • useState
  • useCallback
  • use
  • startTransition
  • useDeferredValue
  • useMemo
  • useLayoutEffect
  • Memo
  • isValidElement
startViewTransition family

In addition, the original APIs, startViewTransition family make the View Transition API easy to use.

import { useState, startViewTransition } from 'hono/jsx'
import { Style, css, keyframes } from 'hono/css'

const fadeIn = keyframes`
  from { opacity: 0; }
  to { opacity: 1; }
`

const App = () => {
  const [showTitleImage, setShowTitleImage] = useState(false)

  return (
    <>
      <button onClick={() => startViewTransition(() => setShowTitleImage((state) => !state))}>Click!</button>
      <div>
        {!showTitleImage ? (
          <img src="https://hono.dev/images/logo.png" />
        ) : (
          <div
            class={css`
              animation: ${fadeIn} 1s;
              background: url('https://hono.dev/images/logo-large.png');
              background-size: contain;
              background-repeat: no-repeat;
              background-position: center;
              width: 500px;
              height: 200px;
            `}
          />
        )}
      </div>
    </>
  )
}

You can easily create the animation.

SC

Ultra-small

The hono/jsx/dom is fast and ultra-small. It has a smaller JSX runtime dedicated to the DOM in addition to the common server and client ones. Just specify hono/jsx/dom instead of hono/jsx in tsconfig.json.

"jsx": "react-jsx",
"jsxImportSource": "hono/jsx/dom"

The above counter example is 2.8KB with Brotli compression.

SS

In comparison, React is 47.3 KB for the same thing.

SS

3. File-based Routing

Last is File-based Routing. This is not included in the hono package, but is provided in a separate package.

It is named HonoX.

HonoX

HonoX has the following features.

  • File-based routing - You can create a large application like Next.js.
  • Fast SSR - Rendering is ultra-fast thanks to Hono.
  • BYOR - You can bring your own renderer, not only one using hono/jsx.
  • Islands hydration - If you want interactions, create an island. JavaScript is hydrated only for it.
  • Middleware - It works as Hono, so you can use a lot of Hono's middleware.

You can try it now. One of create-hono's starter templates named "x-base" uses HonoX.

For detailed usage, please see the following HonoX repository.

https://github.com/honojs/honox

The core is still tiny

The addition of this feature has no impact on the core. "Hello World" in hono/tiny is still small, only 12KB minified.

Other new features

Breaking Changes

There are several breaking changes. Please see the Migration Guide below.

https://github.com/honojs/hono/blob/main/docs/MIGRATION.md

Thanks

Thanks to all contributors. Great job on all the hard work!

All Updates

@renovate renovate bot force-pushed the renovate/npm-hono-vulnerability branch from 868f7a4 to da0bd1b Compare April 23, 2024 19:30
@renovate renovate bot changed the title fix(deps): update dependency hono to v3.11.7 [security] fix(deps): update dependency hono to v4 [security] Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

0 participants