前端安全防护做为保障业务稳定运行的关键环节。XSS(跨站脚本攻击)、CSRF(跨站请求伪造)和JWT(JSON Web Token)的安全性问题,一直是开发中的重点。
随着数字化转型的深入,超商企业的供应链系统日益复杂,前端承载的业务逻辑也越来越重。这使得前端成为了攻击者重点关注的目标。一个看似微小的安全漏洞,都可能导致用户数据泄露、资产损失甚至品牌声誉受损。特别是在供应链环境中,涉及多方数据交互和敏感信息传输,前端安全防护显得尤为重要。
我们的供应链系统需要处理大量的供应商数据、库存信息和交易记录。考虑到系统的敏感性和复杂性,我决定引入AI编程助手(主要使用GitHub Copilot和ChatGPT)来协助完成安全防护工作,重点解决XSS、CSRF和JWT安全这三大前端安全挑战。
本文将详细记录使用AI协作开发的真实过程,展示AI工具在项目开发、代码优化和安全问题排查中的实际应用,分享如何通过人机协作构建坚固的前端安全防护体系。
超商供应链系统具有以下特点:
在本项目中,我主要使用两种AI工具:
协作场景主要包括:
XSS(跨站脚本攻击)是供应链系统面临的主要威胁之一,攻击者可能通过注入恶意脚本窃取敏感的供应链数据或执行未授权操作。我的目标是实现全面的XSS防护,包括输入验证、输出编码和内容安全策略。
我向ChatGPT咨询了现代前端开发中的XSS最佳防护实践,它提供了基于React环境的综合防护方案,并解释了每种措施的有效性和局限性。
AI生成的基础代码:
// 输入验证函数 - 由GitHub Copilot生成初版
export const validateInput = (input, type = 'text') => {
const patterns = {
text: /^[a-zA-Z0-9\u4e00-\u9fa5\s@.,!?;:()-]{1,500}$/,
number: /^[0-9]{1,20}$/,
sku: /^[A-Z0-9-]{1,50}$/,
phone: /^1[3-9]\d{9}$/,
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,20}$/
};
if (!patterns[type]) return false;
return patterns[type].test(input.trim());
};
// 严格HTML标签过滤 - 基于AI建议增强
export const sanitizeHtml = (input) => {
const allowedTags = ['b', 'i', 'u', 'br', 'p', 'span'];
const allowedAttrs = ['class', 'style'];
const doc = new DOMParser().parseFromString(input, 'text/html');
// 移除非允许标签
doc.body.querySelectorAll('*').forEach(element => {
if (!allowedTags.includes(element.tagName.toLowerCase())) {
element.parentNode.removeChild(element);
return;
}
// 移除非允许属性
Array.from(element.attributes).forEach(attr => {
if (!allowedAttrs.includes(attr.name.toLowerCase())) {
element.removeAttribute(attr.name);
}
});
});
return doc.body.innerHTML;
};
架构解析:
设计思路:
重点逻辑:
参数解析:
input
: 需要验证或净化的输入内容type
: 输入类型,决定使用何种验证规则基于AI建议,我实现了上下文相关的输出编码:
// 输出编码函数 - 由AI提供优化建议
export const encodeOutput = (data, context = 'html') => {
if (data === null || data === undefined) return '';
const str = String(data);
switch(context) {
case 'html':
return str.replace(/[&<>"']/g, (char) => ({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}[char]));
case 'attribute':
return str.replace(/[&<>"']/g, (char) => ({
'"': '"',
"'": '''
}[char] || char));
case 'javascript':
return str.replace(/[\\"']/g, '\\$&')
.replace(/\//g, '\\/')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
case 'url':
return encodeURIComponent(str);
default:
return str;
}
};
// CSP设置中间件 - AI生成的Express中间件
export const cspMiddleware = (req, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self' 'unsafe-eval' https://trusted.cdn.com; " +
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
"img-src 'self' data: https:; " +
"font-src 'self' https://fonts.gstatic.com; " +
"frame-src 'none'; " +
"object-src 'none';" +
"base-uri 'self';" +
"form-action 'self';"
);
next();
};
设计思路:
最终效果:
通过AI辅助实现的XSS防护体系,成功拦截了测试阶段的所有XSS攻击尝试,包括存储型、反射型和DOM型XSS。AI工具不仅提供了代码实现,还解释了每种防护措施的原理和必要性,帮助我深入理解防御机制。
CSRF(跨站请求伪造)攻击在供应链系统中尤为危险,攻击者可能诱导已认证用户执行非预期的业务操作,如修改订单、确认发货等。我的目标是构建多层CSRF防护体系。
我向AI咨询了现代CSRF防护的最佳实践,它提供了基于Token验证和SameSite Cookie的综合方案,并解释了双重提交Cookie模式的工作原理。
AI生成的CSRF令牌管理代码:
// CSRF令牌生成与验证中间件 - AI生成初版+手动优化
import crypto from 'crypto';
export const csrfTokenMiddleware = (req, res, next) => {
// 生成令牌
if (req.method === 'GET' && !req.path.startsWith('/api')) {
const token = crypto.randomBytes(32).toString('hex');
res.cookie('XSRF-TOKEN', token, {
httpOnly: false,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 24 * 60 * 60 * 1000 // 24小时
});
// 将会话中的令牌与用户关联
if (req.session) {
req.session.csrfToken = token;
}
}
// 验证令牌
if (['POST', 'PUT', 'DELETE', 'PATCH'].includes(req.method)) {
const clientToken = req.headers['x-csrf-token'] || req.body._csrf;
const sessionToken = req.session?.csrfToken;
if (!clientToken || !sessionToken || clientToken !== sessionToken) {
return res.status(403).json({
error: '无效的CSRF令牌'
});
}
}
next();
};
// React前端令牌集成 - AI建议的方案
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.REACT_APP_API_URL
});
// 请求拦截器自动添加CSRF令牌
apiClient.interceptors.request.use((config) => {
const token = getCookie('XSRF-TOKEN');
if (token && ['post', 'put', 'delete', 'patch'].includes(config.method)) {
config.headers['X-CSRF-Token'] = token;
}
return config;
});
// 从Cookie中获取值的辅助函数
const getCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
};
架构解析:
设计思路:
重点逻辑:
参数解析:
req
: Express请求对象res
: Express响应对象config
: Axios请求配置对象基于AI建议,实施了深度防御策略:
// SameSite Cookie设置 - AI提供的配置
app.use(session({
secret: process.env.SESSION_SECRET,
cookie: {
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax', // 兼顾安全与用户体验
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
},
resave: false,
saveUninitialized: false
}));
// 关键操作二次认证中间件 - 自行设计+AI优化
export const criticalOperationValidation = (req, res, next) => {
if (isCriticalOperation(req.path, req.method)) {
// 检查额外认证头
const authHeader = req.headers['x-operation-confirmation'];
if (!authHeader || authHeader !== 'confirmed') {
return res.status(403).json({
error: '关键操作需要二次确认'
});
}
// 检查操作时间间隔(防止重放)
const operationTime = req.headers['x-operation-time'];
if (!operationTime || Date.now() - parseInt(operationTime) > 30000) {
return res.status(403).json({
error: '操作已过期,请重新确认'
});
}
}
next();
};
// 判断是否为关键操作
const isCriticalOperation = (path, method) => {
const criticalPaths = [
'/api/inventory/batch-delete',
'/api/orders/bulk-update',
'/api/suppliers/delete',
'/api/financial/confirm'
];
return criticalPaths.includes(path) && method === 'POST';
};
最终效果:
通过AI辅助实现的CSRF防护体系,结合了令牌验证、SameSite Cookie和关键操作保护三层防护。在测试中成功阻挡了所有CSRF攻击尝试,同时保持了良好的用户体验。AI工具帮助我理解了不同防护策略的优缺点,并提供了实现参考。
JWT(JSON Web Token)在供应链系统中用于身份验证和API授权,不安全的实现可能导致身份伪造或权限提升。我的目标是确保JWT的安全生成、传输和存储。
我向AI咨询了JWT安全最佳实践,它提供了密钥管理、令牌验证和安全存储的全面方案,并解释了各种攻击向量如令牌破解、重放攻击的防护方法。
AI生成的JWT工具类:
// JWT工具类 - AI生成基础+手动增强安全特性
import jwt from 'jsonwebtoken';
import crypto from 'crypto';
class JWTManager {
constructor() {
this.secretKey = process.env.JWT_SECRET || this.generateFallbackKey();
this.refreshSecret = process.env.JWT_REFRESH_SECRET || this.generateFallbackKey();
}
// 生成访问令牌
generateAccessToken(payload) {
return jwt.sign(payload, this.secretKey, {
expiresIn: '15m', // 短期访问令牌
issuer: 'supply-chain-api',
audience: 'supply-chain-web',
jwtid: crypto.randomUUID() // 唯一令牌ID
});
}
// 生成刷新令牌
generateRefreshToken(payload) {
return jwt.sign(payload, this.refreshSecret, {
expiresIn: '7d', // 长期刷新令牌
issuer: 'supply-chain-api',
audience: 'supply-chain-web',
jwtid: crypto.randomUUID()
});
}
// 验证访问令牌
verifyAccessToken(token) {
try {
return jwt.verify(token, this.secretKey, {
issuer: 'supply-chain-api',
audience: 'supply-chain-web'
});
} catch (error) {
throw new Error(`令牌验证失败: ${error.message}`);
}
}
// 验证刷新令牌
verifyRefreshToken(token) {
try {
return jwt.verify(token, this.refreshSecret, {
issuer: 'supply-chain-api',
audience: 'supply-chain-web'
});
} catch (error) {
throw new Error(`刷新令牌验证失败: ${error.message}`);
}
}
// 解码令牌而不验证(用于调试)
decodeToken(token) {
return jwt.decode(token, { complete: true });
}
// 生成回退密钥(仅开发环境使用)
generateFallbackKey() {
if (process.env.NODE_ENV === 'production') {
throw new Error('JWT密钥未配置,生产环境必须设置JWT_SECRET');
}
return crypto.randomBytes(32).toString('hex');
}
// 令牌黑名单管理(用于注销)
async addToBlacklist(tokenId, expiryTime) {
// 实际项目中应使用Redis等持久化存储
// 这里简化实现为内存存储
JWTManager.tokenBlacklist.set(tokenId, expiryTime);
}
// 检查令牌是否在黑名单中
async isTokenBlacklisted(tokenId) {
return JWTManager.tokenBlacklist.has(tokenId);
}
}
// 静态黑名单存储
JWTManager.tokenBlacklist = new Map();
export default new JWTManager();
架构解析:
设计思路:
重点逻辑:
参数解析:
payload
: 包含用户ID、角色等信息的对象token
: 需要验证或解码的JWT字符串基于AI建议,实现了安全的JWT存储方案:
// JWT安全存储Hook - React Context与Hook实现
import { createContext, useContext, useState, useEffect } from 'react';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [authState, setAuthState] = useState({
token: null,
refreshToken: null,
user: null
});
// 初始化从安全存储中恢复令牌
useEffect(() => {
const initializeAuth = async () => {
try {
const token = await secureStorage.getItem('jwt_token');
const refreshToken = await secureStorage.getItem('jwt_refresh_token');
const userData = await secureStorage.getItem('user_data');
if (token && refreshToken) {
setAuthState({
token,
refreshToken,
user: userData ? JSON.parse(userData) : null
});
}
} catch (error) {
console.error('认证初始化失败:', error);
await clearAuthData();
}
};
initializeAuth();
}, []);
// 登录处理
const login = async (token, refreshToken, user) => {
try {
// 存储到安全存储
await secureStorage.setItem('jwt_token', token);
await secureStorage.setItem('jwt_refresh_token', refreshToken);
await secureStorage.setItem('user_data', JSON.stringify(user));
// 更新状态
setAuthState({ token, refreshToken, user });
} catch (error) {
console.error('登录失败:', error);
throw error;
}
};
// 注销处理
const logout = async () => {
try {
// 将令牌加入黑名单
if (authState.token) {
const decoded = jwt.decode(authState.token);
await JWTManager.addToBlacklist(decoded.jti, decoded.exp * 1000);
}
// 清除存储
await clearAuthData();
// 更新状态
setAuthState({ token: null, refreshToken: null, user: null });
} catch (error) {
console.error('注销失败:', error);
}
};
// 清除认证数据
const clearAuthData = async () => {
await secureStorage.removeItem('jwt_token');
await secureStorage.removeItem('jwt_refresh_token');
await secureStorage.removeItem('user_data');
};
// 令牌刷新
const refreshToken = async () => {
try {
const response = await apiClient.post('/auth/refresh', {
refreshToken: authState.refreshToken
});
const { token, refreshToken: newRefreshToken } = response.data;
await login(token, newRefreshToken, authState.user);
return token;
} catch (error) {
await logout();
throw error;
}
};
return (
<AuthContext.Provider value={{
...authState,
login,
logout,
refreshToken
}}>
{children}
</AuthContext.Provider>
);
};
// 安全存储实现 - 使用加密存储替代localStorage
const secureStorage = {
// 使用IndexedDB或加密存储替代不安全的localStorage
async setItem(key, value) {
if (typeof window !== 'undefined' && window.crypto) {
// 实际项目中应使用加密存储,这里简化实现
localStorage.setItem(key, value);
}
},
async getItem(key) {
if (typeof window !== 'undefined') {
return localStorage.getItem(key);
}
return null;
},
async removeItem(key) {
if (typeof window !== 'undefined') {
localStorage.removeItem(key);
}
}
};
设计思路:
最终效果:
通过AI辅助实现的JWT安全方案,提供了全面的令牌管理、安全存储和自动刷新功能。在测试中成功防止了令牌篡改、重放攻击等安全威胁。AI工具帮助我理解了JWT的各种安全考虑,并提供了实现的最佳实践。
供应链系统面临独特的安全挑战:
AI协助实现的依赖安全检查:
// 依赖安全审计脚本 - AI生成基础+手动增强
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
class DependencyScanner {
constructor() {
this.packageJsonPath = path.join(process.cwd(), 'package.json');
this.lockfilePath = path.join(process.cwd(), 'package-lock.json');
this.vulnerabilityThreshold = {
high: 0, // 不允许高危漏洞
medium: 5, // 允许最多5个中危漏洞
low: 10 // 允许最多10个低危漏洞
};
}
// 检查依赖漏洞
async checkVulnerabilities() {
try {
console.log('正在检查依赖漏洞...');
// 运行npm audit
const auditResult = execSync('npm audit --json', { encoding: 'utf8' });
const auditData = JSON.parse(auditResult);
// 分析结果
const vulnerabilities = this.analyzeAuditData(auditData);
// 生成报告
this.generateReport(vulnerabilities);
// 检查是否超过阈值
const exceedsThreshold = this.checkThreshold(vulnerabilities);
if (exceedsThreshold) {
console.error('❌ 依赖漏洞超过安全阈值,请先修复再继续');
process.exit(1);
} else {
console.log('✅ 依赖漏洞在安全阈值内');
}
return vulnerabilities;
} catch (error) {
console.error('依赖检查失败:', error);
throw error;
}
}
// 分析审计数据
analyzeAuditData(auditData) {
const vulnerabilities = {
high: 0,
medium: 0,
low: 0,
details: []
};
if (auditData.vulnerabilities) {
for (const [severity, count] of Object.entries(auditData.vulnerabilities)) {
vulnerabilities[severity] = count;
}
}
return vulnerabilities;
}
// 检查是否超过安全阈值
checkThreshold(vulnerabilities) {
return (
vulnerabilities.high > this.vulnerabilityThreshold.high ||
vulnerabilities.medium > this.vulnerabilityThreshold.medium ||
vulnerabilities.low > this.vulnerabilityThreshold.low
);
}
// 生成SBOM(软件物料清单)
generateSBOM() {
try {
if (!fs.existsSync(this.packageJsonPath)) {
throw new Error('package.json不存在');
}
const packageData = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf8'));
const dependencies = {
...packageData.dependencies,
...packageData.devDependencies
};
const sbom = {
component: packageData.name,
version: packageData.version,
dependencies: Object.keys(dependencies).map(name => ({
name,
version: dependencies[name],
type: 'npm'
})),
generated: new Date().toISOString()
};
// 保存SBOM文件
const sbomPath = path.join(process.cwd(), 'sbom.json');
fs.writeFileSync(sbomPath, JSON.stringify(sbom, null, 2));
console.log(`✅ SBOM已生成: ${sbomPath}`);
return sbom;
} catch (error) {
console.error('SBOM生成失败:', error);
throw error;
}
}
}
export default new DependencyScanner();
架构解析:
将各项安全措施集成为完整体系:
AI协助的安全中间件集成:
// 应用安全中间件集成 - AI提供的最佳实践顺序
import express from 'express';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import cors from 'cors';
const app = express();
// 1. 基础安全防护
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-eval'", "https://trusted.cdn.com"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
imgSrc: ["'self'", "data:", "https:"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
objectSrc: ["'none'"],
frameSrc: ["'none'"],
baseUri: ["'self'"],
formAction: ["'self'"]
}
},
crossOriginEmbedderPolicy: true,
crossOriginResourcePolicy: { policy: "same-site" }
}));
// 2. CORS设置
app.use(cors({
origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : [],
credentials: true,
optionsSuccessStatus: 200
}));
// 3. 速率限制
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 每IP最多100次请求
message: '请求过于频繁,请稍后再试',
skip: (req) => {
// 跳过健康检查等接口的限制
return req.path === '/health' || req.path === '/api/health';
}
});
app.use(limiter);
// 4. 请求解析限制
app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ extended: true, limit: '1mb' }));
// 5. 安全中间件
app.use(cspMiddleware);
app.use(csrfTokenMiddleware);
app.use(criticalOperationValidation);
// 6. 路由注册
app.use('/api/auth', authRoutes);
app.use('/api/suppliers', supplierRoutes);
app.use('/api/inventory', inventoryRoutes);
app.use('/api/orders', orderRoutes);
// 7. 错误处理中间件
app.use((error, req, res, next) => {
console.error('未处理错误:', error);
// 不向客户端暴露堆栈信息
res.status(500).json({
error: process.env.NODE_ENV === 'production'
? '内部服务器错误'
: error.message
});
});
// 8. 404处理
app.use('*', (req, res) => {
res.status(404).json({ error: '接口不存在' });
});
export default app;
架构解析:
通过本次AI辅助的供应链系统前端安全防护实践,我成功构建了多层次、纵深防御的安全体系,有效防护了XSS、CSRF和JWT相关攻击。AI工具在开发过程中发挥了重要作用,提供了代码生成、方案优化和技术解释等多方面的支持。
本文详细记录了以下安全实践:
回顾整个过程,安全防护的核心不是"一次性加固",而是"持续迭代":随着业务发展(如引入新的富文本编辑器)、攻击手段演变(如新型XSS绕过技术),安全方案也需动态调整。而AI工具将成为这一过程中的"得力助手",帮助我们在"攻防对抗"中保持主动。
对于开发者而言,前端安全不再是"可选技能",而是"必备能力"。希望本文分享的实战经验,能为更多供应链系统、企业级应用的前端安全建设提供参考,让安全真正成为业务发展的"隐形护盾"。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。