找回密码
 立即注册
首页 业界区 安全 一些安全功能的过滤条件写法

一些安全功能的过滤条件写法

常士 2025-9-30 11:44:01
目录

  • 任意URL重定向防护
  • XSS过滤
  • SQL注入过滤
  • 个人敏感信息脱敏处理
  • 综合建议

以普通程序员的角度实现这些安全功能,然后从安全测试者的角度去分析可能的绕过方法。
任意URL重定向防护
  1. import re
  2. from urllib.parse import urlparse, urljoin
  3. def safe_redirect(url, allowed_domains=None):
  4.     """
  5.     安全的URL重定向验证
  6.     :param url: 要重定向的URL
  7.     :param allowed_domains: 允许的重定向域名列表
  8.     :return: 安全的URL或None
  9.     """
  10.     if not url:
  11.         return None
  12.    
  13.     # 默认允许当前域名和子域名
  14.     if allowed_domains is None:
  15.         # 在实际应用中应该从配置获取或设置为空
  16.         allowed_domains = ["example.com", "*.example.com"]
  17.    
  18.     # 解析URL
  19.     parsed = urlparse(url)
  20.    
  21.     # 检查是否为相对路径
  22.     if not parsed.netloc:
  23.         # 相对路径是安全的
  24.         return url
  25.    
  26.     # 检查协议
  27.     if parsed.scheme not in ('http', 'https', ''):
  28.         return None
  29.    
  30.     # 检查域名是否在白名单中
  31.     domain_allowed = False
  32.     for allowed in allowed_domains:
  33.         if allowed.startswith('*.'):
  34.             # 通配符子域名匹配
  35.             base_domain = allowed[2:]
  36.             if parsed.netloc.endswith('.' + base_domain) or parsed.netloc == base_domain:
  37.                 domain_allowed = True
  38.                 break
  39.         else:
  40.             # 精确匹配
  41.             if parsed.netloc == allowed:
  42.                 domain_allowed = True
  43.                 break
  44.    
  45.     if not domain_allowed:
  46.         return None
  47.    
  48.     return url
  49. # 使用示例
  50. redirect_url = safe_redirect("https://evil.com", ["example.com"])
  51. print(redirect_url)  # 输出: None
  52. safe_url = safe_redirect("/dashboard", ["example.com"])
  53. print(safe_url)  # 输出: /dashboard
复制代码
安全测试者视角:

  • 使用javascript:协议绕过: javascript:alert(1)
  • 使用双斜杠绕过: //evil.com
  • 使用数据URI: data:text/html,
  • 利用子域名解析漏洞: example.com.evil.com
  • 使用URL编码: %68%74%74%70%3a%2f%2f%65%76%69%6c%2e%63%6f%6d
XSS过滤
  1. import html
  2. def sanitize_input(input_str):
  3.     """
  4.     基本的XSS过滤
  5.     :param input_str: 用户输入
  6.     :return: 过滤后的安全字符串
  7.     """
  8.     if not input_str:
  9.         return ""
  10.    
  11.     # HTML转义
  12.     sanitized = html.escape(input_str)
  13.    
  14.     # 移除危险属性 (简单示例)
  15.     dangerous_attributes = ['onload', 'onerror', 'onclick', 'onmouseover']
  16.     for attr in dangerous_attributes:
  17.         sanitized = re.sub(rf'{attr}\s*=', 'xss-removed=', sanitized, flags=re.IGNORECASE)
  18.    
  19.     return sanitized
  20. # 使用示例
  21. user_input = '<img src=x onerror=alert(1)>'
  22. safe_output = sanitize_input(user_input)
  23. print(safe_output)  # 输出: <script>alert("XSS")</script><img src=x xss-removed=alert(1)>
复制代码
安全测试者视角:

  • 大小写绕过:
  • 使用HTML实体编码: <script>alert(1)</script> (如果解码不当)
  • 使用JavaScript伪协议: javascript:alert(1)
  • 利用事件处理程序:
    (如果过滤不完整)
  • 使用SVG标签:
SQL注入过滤
  1. import re
  2. def sanitize_sql(input_str):
  3.     """
  4.     基本的SQL注入过滤
  5.     :param input_str: 用户输入
  6.     :return: 过滤后的安全字符串
  7.     """
  8.     if not input_str:
  9.         return ""
  10.    
  11.     # 移除常见的SQL关键字
  12.     sql_keywords = ['union', 'select', 'insert', 'update', 'delete', 'drop',
  13.                    'exec', 'execute', 'where', 'or', 'and', 'like', 'sleep',
  14.                    'benchmark', '--', '/*', '*/', ';', "'", '"']
  15.    
  16.     sanitized = input_str
  17.     for keyword in sql_keywords:
  18.         # 使用正则表达式进行不区分大小写的匹配和替换
  19.         pattern = re.compile(re.escape(keyword), re.IGNORECASE)
  20.         sanitized = pattern.sub('', sanitized)
  21.    
  22.     return sanitized
  23. # 更好的做法是使用参数化查询
  24. def safe_query(cursor, query, params):
  25.     """
  26.     使用参数化查询防止SQL注入
  27.     """
  28.     cursor.execute(query, params)
  29.     return cursor.fetchall()
  30. # 使用示例
  31. user_input = "admin' OR 1=1--"
  32. safe_input = sanitize_sql(user_input)
  33. print(safe_input)  # 输出: admin OR 1=1
复制代码
安全测试者视角:

  • 双重编码绕过: admin%2527%20OR%201=1--
  • 使用注释拆分: /*!UNION*/ SELECT/*!*/
  • 使用异或操作: ' OR '1'='1' XOR '1'='0
  • 使用URL编码: %75%6e%69%6f%6e%20%73%65%6c%65%63%74
  • 使用非标准空格: UNION%0bSELECT
个人敏感信息脱敏处理
  1. import re
  2. def desensitize_info(text):
  3.     """
  4.     个人敏感信息脱敏处理
  5.     :param text: 包含敏感信息的文本
  6.     :return: 脱敏后的文本
  7.     """
  8.     if not text:
  9.         return text
  10.    
  11.     # 身份证号脱敏 (保留前4后4位)
  12.     text = re.sub(r'(\d{4})\d{10}(\d{4})', r'\1******\2', text)
  13.    
  14.     # 手机号脱敏 (保留前3后4位)
  15.     text = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)
  16.    
  17.     # 银行卡号脱敏 (保留前6后4位)
  18.     text = re.sub(r'(\d{6})\d{8,10}(\d{4})', r'\1********\2', text)
  19.    
  20.     # 邮箱脱敏
  21.     text = re.sub(r'(\w{2})[\w.-]*@(\w{2}[\w.-]*)', r'\1****@\2', text)
  22.    
  23.     # 姓名脱敏 (保留姓氏)
  24.     text = re.sub(r'([\u4e00-\u9fa5]{1})[\u4e00-\u9fa5]+', r'\1**', text)
  25.    
  26.     return text
  27. 使用示例
  28. sensitive_text = "张三的手机号是13812345678,身份证是510123199001011234,邮箱是zhangsan@example.com"
  29. desensitized_text = desensitize_info(sensitive_text)
  30. print(desensitized_text)
  31. # 输出: 张**的手机号是138****5678,身份证是5101****1234,邮箱是zh****@example.com
复制代码
安全测试者视角:

  • 使用特殊格式绕过: 身份证号中使用空格或连字符 510123-19900101-1234
  • 使用全角字符: 13812345678 (全角数字)
  • 使用HTML实体编码: 13812345678
  • 使用零宽字符: 138​1234​5678
  • 拆分敏感信息: "手机号是138" + "1234" + "5678"
综合建议

从安全测试者的角度来看,没有任何单一防护措施是完美的。最佳实践包括:

  • 多层防御: 在应用的各个层面实施安全措施
  • 白名单策略: 优先使用白名单而非黑名单
  • 参数化查询: 对于SQL注入,始终使用参数化查询
  • 内容安全策略(CSP): 对于XSS,实施CSP头部
  • 定期安全测试: 定期进行渗透测试和代码审计
  • 使用安全库: 使用经过验证的安全库而不是自己实现

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册