Skip to main content

跨源资源共享(CORS)配置不当导致安全漏洞

要避免 跨源资源共享(CORS) 配置不当导致安全漏洞,可以按照以下措施配置您的 Web 服务器或应用程序,以实现更安全的跨域资源共享设置。
关键安全措施
1. 明确指定允许的域名

    避免通配符:Access-Control-Allow-Origin: * 允许任何来源访问资源,这是一个常见的安全风险。
    正确配置:指定允许访问的可信域名。例如:

    Access-Control-Allow-Origin: https://trusted-domain.com

2. 限制凭证的跨域传递

    默认情况下禁用凭证:跨源请求的凭证(如 cookies 和 HTTP 认证)通常不需要被传递。
    仅在必要时启用:如果必须使用凭证跨域,则需设置 Access-Control-Allow-Credentials: true,并且不能使用通配符:

    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: https://trusted-domain.com

3. 限制允许的 HTTP 方法

    只允许必要的 HTTP 方法,避免暴露不必要的操作。例如:

    Access-Control-Allow-Methods: GET, POST

4. 限制允许的请求头

    控制客户端可以发送哪些自定义头,避免滥用。例如:

    Access-Control-Allow-Headers: Content-Type, Authorization

5. 设置预检请求的缓存时间

    使用 Access-Control-Max-Age 限制预检请求的缓存时间,避免长期缓存不安全的策略。例如:

    Access-Control-Max-Age: 600

6. 严格控制资源的跨域访问范围

    对于敏感资源,应限制 CORS 的使用,避免在未经验证的来源加载敏感数据。

Nginx 示例配置

以下是 Nginx 中的安全 CORS 配置示例:

server {
    listen 80;
    server_name api.example.com;

    location /api/ {
        add_header 'Access-Control-Allow-Origin' 'https://trusted-domain.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' '600';

        if ($request_method = 'OPTIONS') {
            return 204;
        }

        proxy_pass http://backend-server;
    }
}

Apache 示例配置

以下是 Apache 中的安全 CORS 配置示例:

<VirtualHost *:80>
    ServerName api.example.com

    Header set Access-Control-Allow-Origin "https://trusted-domain.com"
    Header set Access-Control-Allow-Methods "GET, POST"
    Header set Access-Control-Allow-Headers "Content-Type, Authorization"
    Header set Access-Control-Allow-Credentials "true"
    Header set Access-Control-Max-Age "600"

    <Location "/api/">
        # 允许预检请求返回 204
        <If "%{REQUEST_METHOD} == 'OPTIONS'">
            Header always set Content-Length "0"
            Header always set Content-Type "text/plain"
            Require all granted
        </If>
    </Location>
</VirtualHost>

后端动态 CORS 配置示例

在某些情况下,您可能需要动态确定允许的域名。以下是使用 Python Flask 实现的示例:

from flask import Flask, request, jsonify

app = Flask(__name__)

ALLOWED_ORIGINS = ["https://trusted-domain.com"]

@app.after_request
def add_cors_headers(response):
    origin = request.headers.get('Origin')
    if origin in ALLOWED_ORIGINS:
        response.headers['Access-Control-Allow-Origin'] = origin
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
    return response

@app.route('/api/data', methods=['GET', 'POST'])
def api_data():
    return jsonify({"message": "Hello, World!"})

if __name__ == "__main__":
    app.run()

额外建议

    定期审查和更新 CORS 配置:确保仅允许当前必要的域名、方法和请求头。
    启用 HTTPS:确保跨域访问时数据在传输中被加密。
    结合 CSRF 防护:对于跨域请求中涉及用户认证的操作,结合 CSRF 令牌验证机制。

通过以上措施,可以有效避免 CORS 配置不当带来的安全风险。