diff --git a/src/usr.sbin/ocspcheck/http.c b/src/usr.sbin/ocspcheck/http.c
index 46b01f1ec..1a8158f74 100644
--- apps/ocspcheck/http.c.orig
+++ apps/ocspcheck/http.c
@@ -1,4 +1,4 @@
-/*	$Id: http.c,v 1.17 2023/04/19 12:58:16 jsg Exp $ */
+/*	$Id: http.c,v 1.21 2026/10/16 06:42:46 kenjiro Exp $ */
 /*
  * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -34,6 +34,10 @@
 
 #include "http.h"
 
+#define HTTP_MAXHEADERLENGTH	(64 * 1024)
+
+#define HTTP_MAX_BODY_SIZE	(20 * 1024)
+
 /*
  * A buffer for transferring HTTP/S data.
  */
@@ -218,7 +222,7 @@ http_free(struct http *http)
 
 struct http *
 http_alloc(const struct source *addrs, size_t addrsz,
-    const char *host, short port, const char *path)
+    const char *host, short port, int use_tls, const char *path)
 {
 	struct sockaddr_storage ss;
 	int		 family, fd, c;
@@ -296,7 +300,7 @@ again:
 
 	/* If necessary, do our TLS setup. */
 
-	if (port != 443) {
+	if (!use_tls) {
 		http->writer = dosyswrite;
 		http->reader = dosysread;
 		return http;
@@ -416,6 +420,11 @@ http_body_read(const struct http *http, struct httpxfer *trans, size_t *sz)
 		else if (ssz == 0)
 			break;
 
+		if (trans->bbufsz > HTTP_MAX_BODY_SIZE ||
+		    (size_t)ssz > HTTP_MAX_BODY_SIZE - trans->bbufsz) {
+			warnx("%s: body too large", http->src.ip);
+			return NULL;
+		}
 		pp = recallocarray(trans->bbuf,
 		    trans->bbufsz, trans->bbufsz + ssz, 1);
 		if (pp == NULL) {
@@ -611,6 +620,10 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz)
 			return NULL;
 		else if (ssz == 0)
 			break;
+		if ((size_t)ssz > HTTP_MAXHEADERLENGTH - trans->hbufsz) {
+			warnx("%s: header too large", http->src.ip);
+			return NULL;
+		}
 		pp = realloc(trans->hbuf, trans->hbufsz + ssz);
 		if (pp == NULL) {
 			warn("realloc");
@@ -672,7 +685,7 @@ http_get_free(struct httpget *g)
 
 struct httpget *
 http_get(const struct source *addrs, size_t addrsz, const char *domain,
-    short port, const char *path, const void *post, size_t postsz)
+    short port, int use_tls, const char *path, const void *post, size_t postsz)
 {
 	struct http	*h;
 	struct httpxfer	*x;
@@ -682,7 +695,7 @@ http_get(const struct source *addrs, size_t addrsz, const char *domain,
 	int		 code;
 	char		*bod, *headr;
 
-	h = http_alloc(addrs, addrsz, domain, port, path);
+	h = http_alloc(addrs, addrsz, domain, port, use_tls, path);
 	if (h == NULL)
 		return NULL;
 
@@ -729,49 +742,3 @@ http_get(const struct source *addrs, size_t addrsz, const char *domain,
 	g->http = h;
 	return g;
 }
-
-#if 0
-int
-main(void)
-{
-	struct httpget	*g;
-	struct httphead	*httph;
-	size_t		 i, httphsz;
-	struct source	 addrs[2];
-	size_t		 addrsz;
-
-#if 0
-	addrs[0].ip = "127.0.0.1";
-	addrs[0].family = 4;
-	addrsz = 1;
-#else
-	addrs[0].ip = "2a00:1450:400a:806::2004";
-	addrs[0].family = 6;
-	addrs[1].ip = "193.135.3.123";
-	addrs[1].family = 4;
-	addrsz = 2;
-#endif
-
-	if (http_init() == -1)
-		errx(EXIT_FAILURE, "http_init");
-
-#if 0
-	g = http_get(addrs, addrsz, "localhost", 80, "/index.html");
-#else
-	g = http_get(addrs, addrsz, "www.google.ch", 80, "/index.html",
-	    NULL, 0);
-#endif
-
-	if (g == NULL)
-		errx(EXIT_FAILURE, "http_get");
-
-	httph = http_head_parse(g->http, g->xfer, &httphsz);
-	warnx("code: %d", g->code);
-
-	for (i = 0; i < httphsz; i++)
-		warnx("head: [%s]=[%s]", httph[i].key, httph[i].val);
-
-	http_get_free(g);
-	return (EXIT_SUCCESS);
-}
-#endif
diff --git a/src/usr.sbin/ocspcheck/http.h b/src/usr.sbin/ocspcheck/http.h
index 17541b436..a0392b8bb 100644
--- apps/ocspcheck/http.h.orig
+++ apps/ocspcheck/http.h
@@ -1,4 +1,4 @@
-/*	$Id: http.h,v 1.3 2017/01/25 13:52:53 inoguchi Exp $ */
+/*	$Id: http.h,v 1.4 2026/10/16 06:18:23 kenjiro Exp $ */
 /*
  * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -65,13 +65,13 @@ int		 http_init(void);
 
 /* Convenience functions. */
 struct httpget	*http_get(const struct source *, size_t,
-			const char *, short, const char *,
+			const char *, short, int, const char *,
 			const void *, size_t);
 void		 http_get_free(struct httpget *);
 
 /* Allocation and release. */
 struct http	*http_alloc(const struct source *, size_t,
-			const char *, short, const char *);
+			const char *, short, int, const char *);
 void		 http_free(struct http *);
 struct httpxfer	*http_open(const struct http *, const void *, size_t);
 void		 http_close(struct httpxfer *);
diff --git a/src/usr.sbin/ocspcheck/ocspcheck.c b/src/usr.sbin/ocspcheck/ocspcheck.c
index 7de764f6b..5d82ca88f 100644
--- apps/ocspcheck/ocspcheck.c.orig
+++ apps/ocspcheck/ocspcheck.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ocspcheck.c,v 1.37 2026/09/19 01:18:07 tb Exp $ */
+/* $OpenBSD: ocspcheck.c,v 1.41 2026/10/19 23:18:26 kenjiro Exp $ */
 
 /*
  * Copyright (c) 2017,2020 Bob Beck <beck@openbsd.org>
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 
+#include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
 #include <limits.h>
@@ -120,25 +121,45 @@ host_dns(const char *s, struct addr vec[MAX_SERVERS_DNS])
 	return vecsz;
 }
 
+static int
+ocsp_url_chars_only(const char *url)
+{
+	size_t	i, len;
+
+	/* Reject control characters before using the URL in an HTTP request. */
+	len = strlen(url);
+	for (i = 0; i < len; i++) {
+		if (!isascii((unsigned char)url[i]))
+			return 0;
+		if (!isalnum((unsigned char)url[i]) &&
+		    !ispunct((unsigned char)url[i]))
+			return 0;
+	}
+
+	return 1;
+}
+
 /*
  * Extract the domain and port from a URL.
  * The url must be formatted as schema://address[/stuff].
  * This returns NULL on failure.
  */
 static char *
-url2host(const char *host, short *port, char **path)
+url2host(const char *host, short *port, char **path, int *use_tls)
 {
 	char	*url, *ep;
 
 	/* We only understand HTTP and HTTPS. */
 
 	if (strncmp(host, "https://", 8) == 0) {
+		*use_tls = 1;
 		*port = 443;
 		if ((url = strdup(host + 8)) == NULL) {
 			warn("strdup");
 			return (NULL);
 		}
 	} else if (strncmp(host, "http://", 7) == 0) {
+		*use_tls = 0;
 		*port = 80;
 		if ((url = strdup(host + 7)) == NULL) {
 			warn("strdup");
@@ -312,11 +333,12 @@ static ocsp_request *
 ocsp_request_new_from_cert(const char *cadir, char *file, int nonce)
 {
 	X509 *cert;
-	int count = 0;
+	int count = 0, i;
 	OCSP_CERTID *id = NULL;
 	ocsp_request *request = NULL;
 	const EVP_MD *cert_id_md = NULL;
 	const X509 *issuer;
+	const char *url;
 	STACK_OF(OPENSSL_STRING) *urls = NULL;
 
 	if ((request = calloc(1, sizeof(ocsp_request))) == NULL) {
@@ -355,7 +377,15 @@ ocsp_request_new_from_cert(const char *cadir, char *file, int nonce)
 		warnx("Certificate in %s contains no OCSP url", file);
 		goto err;
 	}
-	if ((request->url = strdup(sk_OPENSSL_STRING_value(urls, 0))) == NULL)
+	for (i = 0; i < sk_OPENSSL_STRING_num(urls); i++) {
+		url = sk_OPENSSL_STRING_value(urls, i);
+		if (!ocsp_url_chars_only(url)) {
+			warnx("Invalid OCSP url from %s", file);
+			goto err;
+		}
+	}
+	url = sk_OPENSSL_STRING_value(urls, 0);
+	if ((request->url = strdup(url)) == NULL)
 		goto err;
 	X509_email_free(urls);
 	urls = NULL;
@@ -479,6 +509,10 @@ validate_response(char *buf, size_t size, ocsp_request *request,
 			warnx("Certificate revoked at: %s", ctime(&rev_t));
 		goto err;
 	}
+	if (cert_status != V_OCSP_CERTSTATUS_GOOD) {
+		warnx("Invalid OCSP reply: certificate status is not good");
+		goto err;
+	}
 	if ((this_t = parse_ocsp_time(thisupd)) == -1) {
 		warnx("unable to parse this update time in OCSP reply");
 		goto err;
@@ -552,7 +586,8 @@ main(int argc, char **argv)
 	    *instaple = NULL, *infile = NULL;
 	struct addr addrs[MAX_SERVERS_DNS] = {{0}};
 	struct source sources[MAX_SERVERS_DNS];
-	int i, ch, staplefd = -1, infd = -1, nonce = 1;
+	int i, ch, use_tls;
+	int staplefd = -1, infd = -1, nonce = 1;
 	ocsp_request *request = NULL;
 	size_t rescount, instaplesz = 0;
 	struct httpget *hget;
@@ -641,7 +676,7 @@ main(int argc, char **argv)
 
 	dspew("Built an %zu byte ocsp request\n", request->size);
 
-	if ((host = url2host(request->url, &port, &path)) == NULL)
+	if ((host = url2host(request->url, &port, &path, &use_tls)) == NULL)
 		errx(1, "Invalid OCSP url %s from %s", request->url,
 		    certfile);
 
@@ -649,7 +684,7 @@ main(int argc, char **argv)
 		/* Get a new OCSP response from the indicated server */
 
 		vspew("Using %s to host %s, port %d, path %s\n",
-		    port == 443 ? "https" : "http", host, port, path);
+		    use_tls ? "https" : "http", host, port, path);
 
 		rescount = host_dns(host, addrs);
 		for (i = 0; i < rescount; i++) {
@@ -661,7 +696,7 @@ main(int argc, char **argv)
 		 * Do an HTTP post to send our request to the OCSP
 		 * server, and hopefully get an answer back
 		 */
-		hget = http_get(sources, rescount, host, port, path,
+		hget = http_get(sources, rescount, host, port, use_tls, path,
 		    request->data, request->size);
 		if (hget == NULL)
 			errx(1, "http_get");
