惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
T
Tailwind CSS Blog
博客园 - 聂微东
小众软件
小众软件
J
Java Code Geeks
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
量子位
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
月光博客
月光博客
B
Blog RSS Feed
D
DataBreaches.Net
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cyberwarzone
Cyberwarzone
I
Intezer
The Register - Security
The Register - Security
博客园 - 【当耐特】
博客园 - 司徒正美
L
Lohrmann on Cybersecurity
U
Unit 42
N
News and Events Feed by Topic
S
Security Affairs
V
Visual Studio Blog
Y
Y Combinator Blog
Security Latest
Security Latest
Know Your Adversary
Know Your Adversary
Google DeepMind News
Google DeepMind News
大猫的无限游戏
大猫的无限游戏
S
Schneier on Security
P
Privacy International News Feed
TaoSecurity Blog
TaoSecurity Blog
Spread Privacy
Spread Privacy
G
Google Developers Blog
NISL@THU
NISL@THU
Project Zero
Project Zero
P
Palo Alto Networks Blog
Help Net Security
Help Net Security
宝玉的分享
宝玉的分享
Stack Overflow Blog
Stack Overflow Blog
S
Security @ Cisco Blogs
G
GRAHAM CLULEY
www.infosecurity-magazine.com
www.infosecurity-magazine.com

Fastly Blog

Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Fastly Six Common Live Streaming Mistakes (And How to Avoid Them) How Fastly and Skyfire Enable Trusted Agentic Commerce at the Edge Bot Defense is Table Stakes. Machine Traffic Requires a Business Strategy AI Traffic Grew 6.5x Faster Than Human Traffic This Year Python SDK Beta: How the Language of AI Runs Faster and Safer with Fastly Give AI Agents the Markdown They Actually Want How to Configure Local Logging for an On-Prem Next-Gen WAF Agent Accountability Without Control Is Breaking Security Leadership Fastly Joins the Agentic AI Foundation (AAIF) to Guide Edge AI Interoperability The E-commerce Industry in the AI Era: Has the Agentic Flood Hit? No Margin for Error: What the FIFA World Cup Teaches Us About Performance at the Edge Why iGaming Infrastructure is Breaking and What Comes Next The Publishing Industry in the AI Era: Why Bot Strategy is Now a Business Strategy Bad Performance Kills SaaS/PaaS Growth — Why Your CDN Matters Why your code is safe from Copy Fail on Fastly Compute Myth or Marvel: Claude Mythos and What it Means for Security Introducing Compliance Audit Reports Supporting Google Private AI Compute with Privacy-Preserving Edge Infrastructure Fastly Nearly Half the Web Isn’t Human: Inside Fastly’s Threat Insight Report Media over QUIC: Can Streaming Finally Have Both Scale and Low Latency? Introducing Fastly’s Redesigned Homepage: Your Central Hub for Actionable Insights The False Choice of Indiscriminate Blocking: Why Technical Precision is the New Standard for an Open Internet What is CVE-2026-23869? React Server Components Security Alert Fastly enables first-party tagging for Google Advertisers Shrink Your Bill With Efficient Software Your AI coding agent just got better at Fastly Fastly Ranked as a Leader in the 2026 Forrester Wave™ for Edge Development Platforms Fastly at RSAC 2026: New Advances in AppSec, Bot Management, and Deception Mastering the Edge: What Golf Can Teach Us About Speed, Precision, and Performance Real-Time CDN Monitoring for Live Events with Bronto Imperva Alternatives Fastly + Scalepost: Extending the Fastly platform to manage AI Crawlers Best content delivery networks for bot management Vibe Shift? Senior Developers Ship nearly 2.5x more AI Code than Junior Counterparts Maximizing Compute Performance with Log Explorer & Insights Fastly CDN Expands Scaling Fastly Network: Balancing Requests | Fastly Best Practices for Multi-CDN Implementations | Fastly Compute@Edge: Serverless Insights by Company | Fastly Fastly can teach you about the Wasm future in just 6 talks Fastly's Observability Unleashed: New Updates and Insights Optimizing your multi-CDN infrastructure to improve performance Stay ahead of attackers by pushing your security perimeter to the edge Are APIs the Key to Digital Innovation or a Trojan Horse? Fastly Academy: on-demand learning at your fingertips. | Fastly 30 Years of Web: Building for Tomorrow 4 Ways Legacy WAF Fails to Protect Your Apps Adobe boosts performance and MTTR with Epsagon and Fastly logs | Fastly Beta" A New Serverless Compute Environment Early TLS at Fastly Technical trainings & the future of edge delivery at Altitude 2016: a year in review Innovation Capacity Defined: Tech Stack Values | Fastly Deep Log Visibility Offered by Logentries | Fastly Increase Your Hit Ratio With This Simple Tip
Caching the Uncacheable: CSRF Security
2014-12-04 · via Fastly Blog

Cross-Site Request Forgery attacks are a risk for any web application that accepts user data. The best mitigation technique is to use an "authenticity token" that the server generates when building forms for the user and checks when the forms are submitted. Unfortunately, the presence of this token makes the page uncacheable. In this post, I investigate several strategies for maintaining security while improving cacheability. I use Ruby on Rails for the examples, but the techniques apply to nearly any web application framework.

Cross-Site Request Forgery

According to Open Web Application Security Project (OWASP), Cross-Site Request Forgery is: "an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. With a little help of social engineering (like sending a link via email/chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. If the targeted end user is a normal user, a successful CSRF attack can compromise sensitive data. If the targeted end user is the administrator account, this type of attack can compromise the entire web application."

The strongest protection against CSRF attacks is for the origin server to generate a unique token for each user, embed it in each generated page, and then assert that any request from the page that modifies data includes the secret token.

Ruby on Rails not only supports all of this, but enables it by default. It generates an authenticity_token for each user session. Whenever Rails generates an HTML page, it includes the following HTML:

<meta content="authenticity_token"
      name="csrf-param" />
<meta content="gv1xdpH2w4MYcMtoT52pRPV+tPoWFDSJhxNiBOC5idQ="
      name="csrf-token" />

Then, any <form> submission or AJAX request back to the server with an HTTP method other than GET includes that token as a query parameter or HTTP header. On the server, Rails checks the submitted token against the one it generated for the user. If there’s a mismatch, it discards the attempted update.

Cacheability

Rails is doing us a great service, but it poses a problem: these tokens are dynamic, user-specific content and thus make the whole page “uncacheable.” You certainly wouldn’t want one user getting another user’s authenticity token.

There are several different mechanisms we can use to keep the CSRF protection and restore caching.

Technique 1: ESI

Edge-Side Includes let you embed dynamic content within a cached page. In this case, you will use ESI for the CSRF meta tags that Rails produces. First, change the CSRF part of layouts/application.html.erb layout from

<head>
  <%= csrf_meta_tags %>
</head>       

to

<head>
  <esi:include src="/csrf_meta_tags.html" />
</head>

Then, create a new Rails template that contains just <%= csrf_meta_tags %> and tell Rails to route /csrf_meta_tags.html to that template. Be sure that the HTTP response headers tell Varnish not to cache this resource.

Of all the techniques I outline in this post, this is the fastest and most secure.

Technique 2: Cookie

If your caching layer doesn’t support ESI, a second option is to put the token in an HTTP cookie and then pull it out with JavaScript. With the right configuration, a cookie is a relatively secure and performant mechanism for communicating a small secret token from the server to the browser.

First, remove the <%= csrf_meta_tags %> call from layouts/application.html.erb. Then, ensure the cookie is only transmitted over HTTPS by adding secure to its attributes:

cookies[:csrftoken] = {
  value: form_authenticity_token,
  expires: 1.day.from_now,
  secure: true
}

This will generate something like

Set-Cookie: csrftoken=gv1xdpH2w4MYcMtoT52pRPV+tPoWFDSJhxNiBOC5idQ=; path=/; Expires=12/31/2014; secure;

Cookies have another layer of protection called httponly that tells the browser to send the cookie on each request, but block access from JavaScript. Unfortunately, access from JavaScript is exactly what we need in this case. Thus, it is strongly recommended that you put the CSRF token in one cookie rather than adding it the session cookie Rails provides by default.

The JavaScript in the browser now has access to the CSRF token. Making it available to the Rails JavaScript handlers requires a small script that runs on DOM-load:

// The following code assumes you have jQuery and https://github.com/carhartl/jquery-cookie

// On DOM-load, get the "authenticity-token" cookie and set up a <meta> tag for Rails:
jQuery(function($) {
  var token = $.cookie('authenticity-token');

  $('<meta>')
    .attr('name', "csrf-param")
    .attr('content', 'authenticity_token')
    .appendTo('head');

  $('<meta>')
    .attr('name', 'csrf-token')
    .attr('content', token)
    .appendTo('head');
});

The cookie-based approach has some downsides when compared to the ESI approach. Most notably, the additional cookie is sent on every request; it may be small, but it still wastes bandwidth and slows down the application. Additionally, unless you separate the token into its own cookie, having to remove the httponly control exposes your application to additional attack vectors.

Technique 3: Token Over XHR

A third option is to convey the token not via cookie but over a separate XHR request.

As above, first remove the <%= csrf_meta_tags %> call from layouts/application.html.erb. Next, create a new Rails action that returns the CSRF tags as JSON:

def csrf_meta
  respond_to do |format|
    format.json do
      render json: {
        param: request_forgery_protection_token,
        token: form_authenticity_token
      }
    end
  end
end

Finally, add some JavaScript to fetch the token and add it to the DOM:

jQuery(function($) {
  $.getJSON('/csrf_meta.json').then(function(json) {
    $('<meta>')
      .attr('name', "csrf-param")
      .attr('content', json.param)
      .appendTo('head');

    $('<meta>')
      .attr('name', 'csrf-token')
      .attr('content', json.token)
      .appendTo('head');
  });
});

The primary downside to this approach is that the XHR call will take some time. This means that the token won’t be available as soon as the page loads. If the user submits a form or clicks a “delete” button very quickly, it might fail due to the token being missing. You can fix this by marking the XHR as synchronous, but that further delays the page load. (Note that some browsers disallow synchronous XHR in the main thread.)

Recap

Cross-Site Request Forgery attacks are nasty. Fortunately, most web application frameworks provide a way to use an authenticity token to mitigate the risk. If you want to cache a page that has such a token, you will need to separate the token from the rest of the page. You can combine the pieces with Edge-Side Includes for optimum speed and security. Or, if your caching layer doesn’t support ESI, you can convey the token separately in an HTTP cookie or over an XHR request. Regardless, make sure to lock down the token as much as possible; anybody with access to tokens can impersonate users in your system.

Further Reading