当前位置: 首页 > 软件库 > Web应用开发 > Web框架 >

electrode-csrf-jwt

授权协议 View license
开发语言 JavaScript
所属分类 Web应用开发、 Web框架
软件类型 开源软件
地区 不详
投 递 者 凤经武
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Electrode Stateless CSRF

An electrode plugin that enables stateless CSRF protection using JWT in Electrode, Express, Hapi, or Koa 2 applications.

Why do we need this module?

CSRF protection is an important security feature, but in systems which don't have backend session persistence, validation is tricky. Stateless CSRF support addresses this need.

Please see the demo for a sample of using this in a web application with Hapi NodeJS server.

How do we validate requests?

CSRF attacks can be bad when a malicious script can make a request that can perform harmful operations through the user (victim)'s browser, attaching user specific and sensitive data in the cookies.

To prevent it, the technique used by this module is similar to the CSRF double submit cookie prevention technique, and relies on these two restrictions by the browsers:

  1. cross site scripts can't read/modify cookies.
  2. cross site scripts can't set headers.

The double submit cookie prevention technique rely on the fact that a unique token in cookie must match a token attached in a hidden form submit field. Since XSS cannot change cookies, the check prevents CSRF attacks.

Note that the first restriction has some loopholes and thus the double submit cookie technique is not completely secured. See https://www.owasp.org/images/3/32/David_Johansson-Double_Defeat_of_Double-Submit_Cookie.pdf

Double JWT CSRF tokens

For use with XMLHttpRequest and fetch, we extend the technique by using two JWT tokens for validation. One token in the cookies and the other in the HTTP headers. Since XSS cannot set HTTP headers also, it strengthens the security further.

So two JWT CSRF tokens are generated on the server side with the same payload but different types (see below), one for the HTTP header and one for the cookie. This makes two different tokens but uniquely paired with each other by the UUID.

headerPayload = { type: "header", UUID: "12345" };
cookiePayload = { type: "cookie", UUID: "12345" };

When a client makes a request, the JWT tokens must be sent in the cookie and headers, both are channels that cross site scripts have no control over.

Further, we set the cookie to be HTTP Only so any browser that supports it would prevent any scripts from accessing it at all.

On the server side, the tokens are decoded and validated to pair with each other to identify legitimate requests.

If a malicious script somehow manages to alter one of the tokens passed through the cookie or HTTP header, then they will not match. In order to forge a request on the victim's behalf, both restrictions must be circumvented.

Issues

There are some issues with our technique.

  1. We rely on client making all request through AJAX because of the requirement to set HTTP header.

  2. First call has to be a GET to prime the header token. Since the code that use XMLHttpRequest or fetch need to first acquire valid tokens through a non-mutable request like HTTP GET to populate its internal state, so if your first call has to be POST, then it's tricky.

  3. Similar to the cause in #2 above, multiple browser tabs could run into token mismatches, since cookies are shared across tabs but each tab's code keeps its own internal token for the HTTP header.

Issue 1 is the essential of how the technique works so that's just its limitation.

Issue 2 and 3 are tricky, but there are some solutions. See demo for reference.

Install

$ npm install --save electrode-csrf-jwt

Usage and Integration

Browser Integration

To protect your AJAX requests from the browser, your JavaScript code need to first make a GET call to acquire an initial pair of CSRF tokens. The HTTP only cookie token is dropped automatically. Your code has to extract the header token and save it to an internal variable.

In subsequent requests (GET or POST), you have to attach the header token acquired in the HTTP header x-csrf-jwt.

If you receive an error, then you should take the token from the error response and retry one more time.

Full Demo

You can reference a sample demo to use this for your webapp.

Serverside Integration

This module includes a plugin for Hapi (v16 or lower) and middleware for express and koa. They can be used with the following:

Options

First the options. Regardless of which server framework you use, the options remains the same when you pass it to the plugin or middleware.

Required Fields

  • secret: A string or buffer containing either the secret for HMAC algorithms, or the PEM encoded private key for RSA and ECDSA.

Optional Fields

  • cookieName: A string to use as name for setting the cookie token. Default: x-csrf-jwt
  • headerName: A string to use as name for setting the header token. Default: cookieName
  • cookieConfig: An object with extra configs for setting the JWT cookie token. Values set to undefined or null will delete the field from the default cookie config. See the respective server framework for info on what their cookie config should be.
    • path: Cookie path
    • isSecure: Whether cookie is pass secure of not
    • httpOnly: HTTP only.
  • tokenEngine: Experimental A string that specifies the token engine. Either the default "jwt" or "hash".

Optional uuidGen Field

This module by default uses the uuid module. However, it uses crypto.randomBytes, which "uses libuv's threadpool, which can have surprising and negative performance implications for some applications".

If that's an issue, then you can set the uuidGen option as follows to select another UUID generator:

  • "simple" - select a simple one from this module
  • "uuid" - the default: uses uuid
  • function - your own function that returns the ID, which should be a URL safe string

Optional Skip Callbacks

The following should be functions that take the request (or context for Koa) object and return true to skip their respective step for the given request:

  • shouldSkip: Completely skip the CSRF middleware/plugin
  • skipCreate: Skip creating the tokens for the response
  • skipVerify: Skip verifying the incoming tokens

JWT specific optional fields

Others are optional and follow the same usage as jsonwebtoken if the tokenEngine is jwt.

  • algorithm
  • expiresIn
  • notBefore
  • audience
  • subject
  • issuer
  • jwtid
  • subject
  • noTimestamp
  • headers

Electrode Server

electrode-server is a top level wrapper for Hapi. You can use the hapi-plugin in electrode-server by setting your configuration.

Example config/default.js configuration

{
  "plugins": {
    "electrode-csrf-jwt": {
      "options": {
        "secret": "shhhhh",
        "expiresIn": 60,
        shouldSkip: request => {
          // return true to skip CSRF JWT for given request
          return false;
        },
        skipCreate: request => {
          // return true to skip creating CSRF JWT Token for given request
          return false;
        },
        skipVerify: request => {
          // return true to skip verifying CSRF JWT Token for given request
          return false;
        }
      }
    }
  }
}

Express

Example app.js configuration

const csrfMiddleware = require("electrode-csrf-jwt").expressMiddleware;
const express = require("express");

const app = express();

const options = {
  secret: "shhhhh",
  expiresIn: 60,
  shouldSkip: request => {
    // return true to skip CSRF JWT for given request
    return false;
  },
  skipCreate: request => {
    // return true to skip creating CSRF JWT Token for given request
    return false;
  },
  skipVerify: request => {
    // return true to skip verifying CSRF JWT Token for given request
    return false;
  }
};

app.use(csrfMiddleware(options));

Hapi

Example server/index.js configuration

const csrfPlugin = require("electrode-csrf-jwt").register;
const Hapi = require("hapi");

const server = new Hapi.Server();
const options = {
  secret: "shhhhh",
  expiresIn: 60,
  shouldSkip: request => {
    // return true to skip CSRF JWT for given request
    return false;
  },
  skipCreate: request => {
    // return true to skip creating CSRF JWT Token for given request
    return false;
  },
  skipVerify: request => {
    // return true to skip verifying CSRF JWT Token for given request
    return false;
  }
};

server.register({ register: csrfPlugin, options }, err => {
  if (err) {
    throw err;
  }
});

Koa 2

Example app.js configuration

const csrfMiddleware = require("electrode-csrf-jwt").koaMiddleware;
const Koa = require("koa");

const app = new Koa();

const options = {
  secret: "shhhhh",
  expiresIn: 60,
  shouldSkip: context => {
    // return true to skip CSRF JWT for given context
    return false;
  },
  skipCreate: context => {
    // return true to skip creating CSRF JWT Token for given context
    return false;
  },
  skipVerify: context => {
    // return true to skip verifying CSRF JWT Token for given context
    return false;
  }
};

app.use(csrfMiddleware(options));

Fastify

Please register fastify-cookie plugin before electrode-csrf-jwt to add cookie support with fastify.

Example server.js configuration

const csrfPlugin = require("electrode-csrf-jwt").fastify;
const Fastify = require("fastify");
const fastifyCookie = require("fastify-cookie");

csrfPlugin[Symbol.for("skip-override")] = true;

const server = Fastify();
const options = {
  secret: "shhhhh",
  expiresIn: 60,
  shouldSkip: request => {
    // return true to skip CSRF JWT for given request
    return false;
  },
  skipCreate: request => {
    // return true to skip creating CSRF JWT Token for given request
    return false;
  },
  skipVerify: request => {
    // return true to skip verifying CSRF JWT Token for given request
    return false;
  }
};

server.register(fastifyCookie).register(csrfPlugin, options);
server.listen(3000, err => {
  if (err) throw err;
  console.log(`Server listening at http://localhost:${fastify.server.address().port}`);
});

HTTPS and cookies

When running in HTTPS, you will need to specify the cookie with secure=true. Use the cookieConfig option

{
   "cookieConfig": {
     "isSecure": true
   }
}

Client-side fetch

When doing client-side fetch to the server, it is preferable to use electrode-fetch.
Electrode-fetch will look for the x-csrf-jwt header from responses and use it as the new JWT token on subsequent fetches.
If you use your own fetch function, you will have to handle this yourself.

Built with ❤️ by Team Electrode @WalmartLabs.

  • 1. 关于CSRF Cross-site request forgery 在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 这也是为什么很多网站上点击外链会有提醒。 判断一个网站是否存在CSRF漏洞,其实就是判断其对关键信息(比如密码等敏感信息)的操作(增删改

  • 【转】https://blog.csdn.net/weixin_34413103/article/details/88262605 web服务中,用户输入用户名密码登入之后,后续访问网站的其他功能就不用再输入用户名和密码了。传统的身份校验机制为cookie-session机制: cookie-session机制 用户浏览器访问web网站,输入用户名密码 服务器校验用户名密码通过之后,生成sesso

  • 引入依赖 <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.14.0</version> </dependency> 提供者

  • import io.jsonwebtoken.Claims; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframe

  • 项目背景: 项目相关背景: 在日常项目开发过程中,很多敏感的数据接口都很容易被恶意访问和调用,这种情况下为了避免接口被跨页面攻击(以下统称:Cross-site request forgery(CSRF)),都会在请求接口出增加临时token,避免接口被恶意调用,但是很多框架只支持静态页面生成渲染CSRF TOKEN,对动态api接口并不友好(前后端分离); 业务代码: 以下是相关的示例代码,此代

  • 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF。 CSRF是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。 例如(CSR

  • 前言 有些师傅向我咨询WP,索性就发了吧,其实早就写好了,只是懒,在github仓库里囤着,有人说我写错了,这样吧群主改题也不是我能控制的,我能做的就是简简单单分享,也不想重做这些题仅参考 JWT简介 可以看看我的Github总结给自己看的,Y4tacker CTFSHOW Web345 首先打开题目,查看源码,接下来访问/admin被跳转回主页啥也没有发生 where is flag? <!--

  • 什么是CSRF? csrf又称跨域请求伪造,攻击方通过伪造用户请求访问受信任站点。CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI……而现在,互联网上的许多站点仍对此毫无防备,以至于安

  • filter package com.cwl.userdata.filter; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.cwl.userdata.content.Constants; import com.cwl.userdata.util.JwtTokenUtil

  • var csrftoken = $.cookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.tes

 相关资料
  • Electrode 是由沃尔玛开源的,构建具有标准化结构、最佳实践和现代技术的通用 React / Node.js 应用程序平台。Electrode 专注于性能,组件可重用性和对多个云提供商的简单部署,因此您可以专注于让应用更具个性。 核心 在几分钟内构建一个简单、灵活的支架,支持服务器端渲染并轻松部署到多个云提供商。 模块 折叠渲染、服务器端渲染缓存和无状态 CSRF 验证等功能升级您的应用程序

  • CSRF是指针对Web应用程序的跨站点伪造攻击。 CSRF攻击是系统的经过身份验证的用户执行的未授权活动。 因此,许多Web应用程序容易受到这些攻击。 Laravel以下列方式提供CSRF保护 - Laravel包含一个内置的CSRF插件,可为每个活动用户会话生成令牌。 这些令牌验证相关的经过身份验证的用户是否发送了操作或请求。 实现 (Implementation) 本节将详细讨论Laravel

  • CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对

  • 我已经在移动应用程序上使用了智威汤逊,但我将第一次在网站上实现它来进行身份验证,我有一点我仍然不明白: 如果将JWT令牌与localStorage一起使用,就有可能发生XSS攻击 如果我将JWT令牌与cookie一起使用,就有可能发生CRSF攻击

  • 简介 Laravel 可以轻松地保护应用程序免受 跨站点请求伪造 (CSRF) 攻击,跨站点请求伪造是一种恶意攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令。 Laravel 会自动为每个活跃用户的会话生成一个 CSRF「令牌」。该令牌用于验证经过身份验证的用户是否是向应用程序发出请求的用户。 无论何时,当您在应用程序中定义HTML表单时,都应该在表单中包含一个隐藏的CSRF标记字段,

  • Generate CSRF PoC This function can be used to generate a proof-of-concept (PoC) cross-site request forgery (CSRF) attack for a given request. To access this function, select a URL or HTTP request any