down-csrf-token改造记录
1 csrf改造
前端代码:
【<head>
<script>
async function getCsrfToken() {
const response = await fetch('/get_csrf_token');
if (!response.ok) {
throw new Error('Failed to fetch CSRF token');
}
const { csrf_token } = await response.json();
return csrf_token;
}
window.addEventListener('DOMContentLoaded', async () => {
const csrfToken = await getCsrfToken();
document.querySelector('input[name="my_csrf_token"]').value = csrfToken;
});
</script>
.....
</head>
.....
<div id="container" class="mdui-card mdui-center">
<form id="form_url" >
<label for="video_link"> </label>
<input type="text" id="video_link" name="video_link" onfocus="this.value=''" value="请输入视频页面url 比如: https://v.test.com/UGQaf5o/" style="color: gray;">
<input type="hidden" name="my_csrf_token" value="">
<button id="download_btn" type="submit">Download</button>
<p id="error_message" style="display:none">Uh-Oh! 可能是没有,请更换url</p>
</form>
</div>
.....
<script>
document.getElementById("download_btn").addEventListener("click", async function() {
event.preventDefault(); // 阻止表单默认提交行为
document.getElementById("download_btn").innerText = "Downloading...";
document.getElementById("download_btn").setAttribute("disabled", "disabled");
const v = document.getElementById('video_link').value;
let regex;
if (v.includes("test")) {
regex = /http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&:\-\+\%]*[/]*/;
} else if (v.includes("test")) {
regex = /http[s]?:\/\/[\w.]+\/@[\w.-]+\/video\/\d+/;
}
const video_link = v.match(regex)[0];
const csrftoken = document.querySelector('input[name="my_csrf_token"]').value;
const formData = new FormData();
formData.append('video_link', video_link);
formData.append('my_csrf_token', csrftoken); // 将csrf_token作为表单数据发送
try {
const response = await fetch('/download', {
method: 'POST',
body: formData
});
if (!response.ok) {
document.getElementById("error_message").style.display = "block";
download_btn.innerText = "Download";
download_btn.removeAttribute("disabled");
return;
}
const jsonData = await response.json();
// Remove form_url
document.getElementById("form_url").style.display = "none";
// create and add the thumbnail image
const thumb = document.createElement("img");
const imageDiv = document.createElement("div");
thumb.src = jsonData.thumb;
thumb.classList.add("thumb-img");
imageDiv.classList.add("mdui-card-media");
imageDiv.appendChild(thumb);
.....
</script>】
后端代码:
【
from flask import Flask, request, jsonify, render_template_string
import requests
import json
import qrcode
from fake_useragent import UserAgent
from subprocess import run, PIPE
from flask_wtf.csrf import CSRFProtect, generate_csrf, CSRFError
from werkzeug.exceptions import BadRequest
app = Flask(__name__)
app.config['SECRET_KEY'] = '3D6SWx9deteds1' #随机密钥
csrf = CSRFProtect(app) # 初始化CsrfProtect
@app.errorhandler(CSRFError)
def handle_csrf_error(e):
return jsonify({"error": e.description}), 400
@app.route('/get_csrf_token', methods=['GET'])
def get_csrf_token():
return jsonify({'csrf_token': generate_csrf()})
#################################download start #################################
# 移除豁免装饰器 @csrf.exempt #如果不删除这个 400报错 Missing CSRF token
@app.route("/download", methods=["POST"])
def download():
csrf_token = request.form.get('my_csrf_token') # 假设CSRF令牌通过表单字段发送
if not csrf_token:
return jsonify({"error": "Missing CSRF token"}), 400
video_link = request.form.get("video_link") # 从表单数据中获取video_link
if not video_link:
return jsonify({"error": "Video link is required"}), 400
.....
】
csrf版本: /home/wwwroot/down/douyin/en/indexnot-csrf.html
2 token改造
怎样在下面给你的前后端代码的基础上 实现 https://analyse.layzz.cn/lyz/getAnalyse?token=uuic-qackd-fga-test 这个的功能呢。 比如 https://v.test.com/download?token=uuic-qackd-fga-test 如果请求后 次数不足返回 { “code”: “0002”, “method”: null, “message”: “您的次数不足 请联系作者微信 123456” } 假如请求成功。 返回之前的json 。可以使用的总次数减1. 你可以假定 uuic-qackd-fga-test 的信息暂时保存在txt文件中或者字典里面 。格式为: 假如存入字典 1 100 1 ] 1级【token种类 1为测试 2为正式】 100【为使用的次数】 1【1为可用 0为不可用】 前端代码:
【<head>
<script>
async function getCsrfToken() {
const response = await fetch('/get_csrf_token');
if (!response.ok) {
throw new Error('Failed to fetch CSRF token');
}
const { csrf_token } = await response.json();
return csrf_token;
}
window.addEventListener('DOMContentLoaded', async () => {
const csrfToken = await getCsrfToken();
document.querySelector('input[name="my_csrf_token"]').value = csrfToken;
});
</script>
.....
</head>
.....
<div id="container" class="mdui-card mdui-center">
<form id="form_url" >
<label for="video_link"> </label>
<input type="text" id="video_link" name="video_link" onfocus="this.value=''" value="请输入视频页面url 比如: https://v.test.com/UGQaf5o/" style="color: gray;">
<input type="hidden" name="my_csrf_token" value="">
<button id="download_btn" type="submit">Download</button>
<p id="error_message" style="display:none">Uh-Oh! 可能是没有,请更换url</p>
</form>
</div>
.....
<script>
document.getElementById("download_btn").addEventListener("click", async function() {
event.preventDefault(); // 阻止表单默认提交行为
document.getElementById("download_btn").innerText = "Downloading...";
document.getElementById("download_btn").setAttribute("disabled", "disabled");
const v = document.getElementById('video_link').value;
let regex;
if (v.includes("test")) {
regex = /http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&:\-\+\%]*[/]*/;
} else if (v.includes("test")) {
regex = /http[s]?:\/\/[\w.]+\/@[\w.-]+\/video\/\d+/;
}
const video_link = v.match(regex)[0];
const csrftoken = document.querySelector('input[name="my_csrf_token"]').value;
const formData = new FormData();
formData.append('video_link', video_link);
formData.append('my_csrf_token', csrftoken); // 将csrf_token作为表单数据发送
try {
const response = await fetch('/download', {
method: 'POST',
body: formData
});
if (!response.ok) {
document.getElementById("error_message").style.display = "block";
download_btn.innerText = "Download";
download_btn.removeAttribute("disabled");
return;
}
const jsonData = await response.json();
// Remove form_url
document.getElementById("form_url").style.display = "none";
// create and add the thumbnail image
const thumb = document.createElement("img");
const imageDiv = document.createElement("div");
thumb.src = jsonData.thumb;
thumb.classList.add("thumb-img");
imageDiv.classList.add("mdui-card-media");
imageDiv.appendChild(thumb);
.....
</script>】
后端代码:
from flask import Flask, request, jsonify, render_template_string
import requests
import json
import qrcode
from fake_useragent import UserAgent
from subprocess import run, PIPE
from flask_wtf.csrf import CSRFProtect, generate_csrf, CSRFError
from werkzeug.exceptions import BadRequest
app = Flask(__name__)
csrf = CSRFProtect(app) # 初始化CsrfProtect
@app.errorhandler(CSRFError)
def handle_csrf_error(e):
return jsonify({"error": e.description}), 400
@app.route('/get_csrf_token', methods=['GET'])
def get_csrf_token():
return jsonify({'csrf_token': generate_csrf()})
#################################download start #################################
# 移除豁免装饰器 @csrf.exempt #如果不删除这个 400报错 Missing CSRF token
@app.route("/download", methods=["POST"])
def download():
csrf_token = request.form.get('my_csrf_token') # 假设CSRF令牌通过表单字段发送
if not csrf_token:
return jsonify({"error": "Missing CSRF token"}), 400
video_link = request.form.get("video_link") # 从表单数据中获取video_link
ok
3 csrf破解
使用程序 获取csrf cookie 。 然后构造请求 把csrf cookie 带入 请求。 不过,有一个要注意的安全隐患:任何人都能获取CSRF令牌并发送请求。如果你的网站有些敏感操作,你可能需要对其进行额外的保护,简单的CSRF防护可能是不够的。这种情况下,你可能需要添加一些额外的措施,比如: 验证码:在敏感操作需要用户输入验证信息,例如短信验证码或邮箱链接等。 第二步验证:例如使用短信、邮件或者安全问题要求用户再次确认操作。 操作频率限制:比如同一用户(基于IP或者账号判断)一段时间内只允许进行有限次数的操作,可以有效防止滥用。 登录校验:未注册/登录用户无法进行操作。 综上,仅仅依赖CSRF防护可能是不够的,对于安全性要求高的操作,建议加入额外的安全措施。
如何添加验证码来增强CSRF保护? 什么是第二步验证?如何在网站上实现它? 如何设置操作频率限制以防止滥用?