HTTP cookie httponly secure

rfc6265中描述

4.1.2.6.  The HttpOnly Attribute

   The HttpOnly attribute limits the scope of the cookie to HTTP
   requests.  In particular, the attribute instructs the user agent to
   omit the cookie when providing access to cookies via "non-HTTP" APIs
   (such as a web browser API that exposes cookies to scripts).

   Note that the HttpOnly attribute is independent of the Secure
   attribute: a cookie can have both the HttpOnly and the Secure
   attribute.

https://datatracker.ietf.org/doc/html/rfc6265

防止非HTTP的api访问,比如javascript,这部分需要相关客户端(如浏览器)的支持。

4.1.2.5.  The Secure Attribute

   The Secure attribute limits the scope of the cookie to "secure"
   channels (where "secure" is defined by the user agent).  When a
   cookie has the Secure attribute, the user agent will include the
   cookie in an HTTP request only if the request is transmitted over a
   secure channel (typically HTTP over Transport Layer Security (TLS)
   [

RFC2818

]).

   Although seemingly useful for protecting cookies from active network
   attackers, the Secure attribute protects only the cookie's
   confidentiality.  An active network attacker can overwrite Secure
   cookies from an insecure channel, disrupting their integrity ...

指定cookie需要在https环境中使用。

搭建环境使用浏览器验证。

下面是一个完整的 HttpOnlySecure Cookie 的例子,包括客户端和服务端的实现。我们使用 Node.jsExpress 来实现服务端,同时用 HTML + JavaScript 模拟客户端的行为。


1. 服务端:Node.js + Express

服务端通过设置 HttpOnlySecure 属性返回 Cookie。为了确保 Secure 属性生效,服务端必须运行在 HTTPS 协议下。

安装依赖

npm init -y
npm install express

代码示例

创建一个 server.js 文件,内容如下:

const express = require('express');
const https = require('https');
const fs = require('fs');
const path = require('path');

const app = express();

// 使用 HTTPS(需要 SSL 证书)
const sslOptions = {
key: fs.readFileSync(path.join(__dirname, 'ssl', 'key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'ssl', 'cert.pem')),
};

// 静态文件
app.use(express.static(path.join(__dirname, 'public')));

// 设置带 HttpOnly 和 Secure 的 Cookie
app.get('/set-cookie', (req, res) => {
res.cookie('session_id', 'abc123', {
httpOnly: true, // 禁止 JavaScript 访问
secure: true, // 仅在 HTTPS 下传输
maxAge: 24 * 60 * 60 * 1000, // 1 天有效期
});
res.send('Cookie 已设置');
});

// 模拟获取 Cookie
app.get('/check-cookie', (req, res) => {
const cookieHeader = req.headers.cookie || '没有 Cookie';
res.send(`收到的 Cookie: ${cookieHeader}`);
});

// 启动 HTTPS 服务器
https.createServer(sslOptions, app).listen(3000, () => {
console.log('Server is running on https://0.0.0.0:3000');
});

生成自签名证书

运行以下命令生成 SSL 证书,用于本地 HTTPS 服务:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

将生成的 key.pemcert.pem 放在 ssl/ 文件夹中。


2. 客户端:HTML + JavaScript

创建一个 public/index.html 文件,用于测试服务端的 Cookie。

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HttpOnly & Secure Cookie</title>
</head>
<body>
<h1>HttpOnly & Secure Cookie 示例</h1>

<button onclick="setCookie()">设置 Cookie</button>
<button onclick="checkCookie()">检查 Cookie</button>

<p id="result"></p>

<script>
// 设置 Cookie
function setCookie() {
fetch('/set-cookie', { method: 'GET', credentials: 'include' })
.then(response => response.text())
.then(data => {
document.getElementById('result').innerText = data;
});
}

// 检查 Cookie
function checkCookie() {
fetch('/check-cookie', { method: 'GET', credentials: 'include' })
.then(response => response.text())
.then(data => {
document.getElementById('result').innerText = data;
});
}

// 尝试访问 HttpOnly 的 Cookie
console.log('尝试访问 document.cookie:', document.cookie);
</script>
</body>
</html>

3. 测试步骤

3.1 启动服务端

运行以下命令启动 HTTPS 服务器:

node server.js

3.2 访问客户端

在浏览器中打开:

https://{ip}:3000

3.3 测试功能

1.设置 Cookie
– 点击 “设置 Cookie” 按钮,服务端将返回一个带有 HttpOnlySecure 属性的 Cookie。

2.检查 Cookie
– 点击 “检查 Cookie” 按钮,服务端会解析请求头中的 Cookie 并返回给客户端显示。

3.验证 HttpOnly
– 打开浏览器的开发者工具,在控制台输入:

console.log(document.cookie);

输出中不会显示 HttpOnlysession_id,因为 JavaScript 无法访问它, 相反如果将server.js代码的httponly设置成false,就可以访问了。

  1. 验证 Secure

– 将服务器切换到 HTTP 协议(移除 HTTPS 配置),再次访问,会发现 session_id 不会被传递,因为浏览器强制要求 Secure Cookie 只能通过 HTTPS 传输。


4. 关键点总结

1. HttpOnly
– 防止 JavaScript 访问 Cookie,减少 XSS 攻击的风险。
– 浏览器控制台的 document.cookie 无法显示带有 HttpOnly 的 Cookie。

2. Secure
– 确保 Cookie 只能在 HTTPS 环境中传输,防止中间人攻击窃取 Cookie。
– 在 HTTP 环境下,Secure 的 Cookie 不会被浏览器发送。

3. 跨域支持
– 在跨域请求时,需添加 credentials: 'include' 以确保 Cookie 被正确发送。

 

关于httponly,secure OWASP网站上两篇文章。

https://owasp.org/www-community/HttpOnly

https://owasp.org/www-community/controls/SecureCookieAttribute

图片from湯建雄

Comments are closed.