Hi,
Arslan Kabeer (on the Internet) made me aware of clickjacking being done on
my site using OpenBSD httpd. This following patch implements a RFC 7034
protection called "noiframe" which disallows other sites (but not the same
site) to add an iframe to my site.
The config change is like this:
----->
location "/" {
directory index index.html
noiframe
}
<-----
The header that is added is the same that google.com adds and it is:
X-Frame-Options: SAMEORIGIN
but only if noiframe is set.
The small patch is against 7.2 openhttpd.
Best Regards,
-peter
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.161
diff -u -p -u -r1.161 httpd.h
--- httpd.h 15 Aug 2022 12:29:17 -0000 1.161
+++ httpd.h 7 Feb 2023 08:57:40 -0000
@@ -544,6 +544,8 @@ struct server_config {
int fcgistrip;
char errdocroot[HTTPD_ERRDOCROOT_MAX];
+ int noiframe;
+
TAILQ_ENTRY(server_config) entry;
};
TAILQ_HEAD(serverhosts, server_config);
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.128
diff -u -p -u -r1.128 parse.y
--- parse.y 27 Feb 2022 20:30:30 -0000 1.128
+++ parse.y 7 Feb 2023 08:57:40 -0000
@@ -140,7 +140,7 @@ typedef struct {
%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
%token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE
-%token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT
+%token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT NOIFRAME
%token ERRDOCS GZIPSTATIC
%token <v.string> STRING
%token <v.number> NUMBER
@@ -685,6 +685,7 @@ serveroptsl : LISTEN ON STRING opttls po
}
srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS;
}
+ | noiframe
;
optfound : /* empty */ { $$ = 0; }
@@ -697,6 +698,7 @@ hsts : HSTS '{' optnl hstsflags_l '}'
| HSTS
;
+
hstsflags_l : hstsflags optcommanl hstsflags_l
| hstsflags optnl
;
@@ -716,6 +718,11 @@ hstsflags : MAXAGE NUMBER {
}
;
+noiframe : NOIFRAME {
+ srv_conf->noiframe = 1;
+ }
+ ;
+
fastcgi : NO FCGI {
srv_conf->flags &= ~SRVFLAG_FCGI;
srv_conf->flags |= SRVFLAG_NO_FCGI;
@@ -1466,6 +1473,7 @@ lookup(char *s)
{ "max-age", MAXAGE },
{ "no", NO },
{ "nodelay", NODELAY },
+ { "noiframe", NOIFRAME },
{ "not", NOT },
{ "ocsp", OCSP },
{ "on", ON },
Index: server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.153
diff -u -p -u -r1.153 server_http.c
--- server_http.c 21 Sep 2022 05:55:18 -0000 1.153
+++ server_http.c 7 Feb 2023 08:57:40 -0000
@@ -1557,6 +1557,17 @@ server_response_http(struct client *clt,
if (kv_add(&resp->http_headers, "Server", HTTPD_SERVERNAME) == NULL)
return (-1);
+ /*
+ * X-Frame-Options header to prevent iframes/clickjacking
+ * As per RFC 7034 (Informational)
+ */
+
+ if (srv_conf->noiframe) {
+ if (kv_add(&resp->http_headers, "X-Frame-Options",
+ "SAMEORIGIN") == NULL)
+ return (-1);
+ }
+
/* Is it a persistent connection? */
if (clt->clt_persist) {
if (kv_add(&resp->http_headers,