#15 记一次 XSS 漏洞发现过程
WebDev 安全 2019-04-09某用户委托安全公司对本司(SendCloud)短信发送业务做安全检测,发现咱们的上游通道某一环节的安全漏洞。
跟踪这个过程,真的十分有趣。
这是 XSS 第一次发生在我身边,怎么也不会想到有人会犯这么弱智的错误。最基本的页面输出转义都没做。
页面内容输出转义、SQL 防注入、表单的 CSRF token 校验,应该算是 Web 站点搭建的基础工作吧!
coding in a complicated world
某用户委托安全公司对本司(SendCloud)短信发送业务做安全检测,发现咱们的上游通道某一环节的安全漏洞。
跟踪这个过程,真的十分有趣。
这是 XSS 第一次发生在我身边,怎么也不会想到有人会犯这么弱智的错误。最基本的页面输出转义都没做。
页面内容输出转义、SQL 防注入、表单的 CSRF token 校验,应该算是 Web 站点搭建的基础工作吧!
本文讲的是 Tornado 框架中的 “secure cookie” 实现。
Apache,Nginx 都有缓存功能,再加上 Redis 做动态数据的缓存,再加上 CDN,所以我还没有用过专门的缓存服务。
但是这些服务真是大名鼎鼎,即便不用,我也可以先列出来做个简单的了解。
这套方案名气比较大,了解看看。
一般都是参考着 官网示例 写,修修改改就好了,挺方便。
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
class Application:
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='hello')
])
def hello(self, request):
text = 'Hello, World!'
response = Response(text, content_type='text/plain')
return response
@Request.application
def __call__(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
endpoint, values = adapter.match()
handler = getattr(self, endpoint)
return handler(request, **values)
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = Application()
run_simple('localhost', 5000, app)
async
/await
)Werkzeug 1.x 开始已经提供了对协程的支持。
PS:WSGI 规范是基于同步的设计,没有较好的适配异步编程,所以后面一些更年轻的框架选择了 ASGI(Async Server Gateway Interface)。
PS:2014/03/01, WSGI
PS:2021/11/06, 体验 ASGI
import asyncio
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
class Application:
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='hello')
])
async def hello(self, request):
text = 'Hello, World!'
response = Response(text, content_type='text/plain')
return response
@Request.application
async def __call__(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
endpoint, values = adapter.match()
handler = getattr(self, endpoint)
response = await handler(request, **values)
return response
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = Application()
run_simple('localhost', 5000, app)
版本 | 时间 |
---|---|
2.3.4 | May 9, 2023 |
2.3.3 | May 1, 2023 |
2.3.2 | Apr 29, 2023 |
2.3.1 | Apr 27, 2023 |
2.3.0 | Apr 26, 2023 |
2.2.3 | Feb 15, 2023 |
2.2.2 | Aug 9, 2022 |
2.2.1 | Jul 28, 2022 |
2.2.0 | Jul 24, 2022 |
2.1.2 | Apr 29, 2022 |
2.1.1 | Apr 2, 2022 |
2.1.0 | Mar 29, 2022 |
2.0.3 | Feb 8, 2022 |
2.0.2 | Oct 6, 2021 |
2.0.1 | May 18, 2021 |
2.0.0 | May 12, 2021 |
1.0.1 | Apr 1, 2020 |
1.0.0 | Feb 7, 2020 |
0.16.1 | Jan 27, 2020 |
0.16.0 | Sep 19, 2019 |
0.15.6 | Sep 5, 2019 |
0.15.5 | Jul 17, 2019 |
0.15.4 | May 15, 2019 |
0.15.3 | May 15, 2019 |
0.15.2 | Apr 3, 2019 |
0.15.1 | Mar 22, 2019 |
0.15.0 | Mar 20, 2019 |
0.14.1 | Jan 1, 2018 |
0.14 | Dec 31, 2017 |
0.13 | Dec 8, 2017 |
0.12.2 | May 16, 2017 |
0.12.1 | Mar 16, 2017 |
0.12 | Mar 10, 2017 |
0.11.15 | Dec 31, 2016 |
0.11.14 | Dec 31, 2016 |
0.11.13 | Dec 27, 2016 |
0.11.12 | Dec 26, 2016 |
0.11.11 | Aug 31, 2016 |
0.11.10 | May 24, 2016 |
0.11.9 | Apr 25, 2016 |
0.11.8 | Apr 15, 2016 |
0.11.7 | Apr 15, 2016 |
0.11.6 | Apr 14, 2016 |
0.11.5 | Mar 23, 2016 |
0.11.4 | Feb 15, 2016 |
0.11.3 | Dec 20, 2015 |
0.11.2 | Nov 12, 2015 |
0.11.1 | Nov 10, 2015 |
0.11 | Nov 8, 2015 |
0.10.4 | Mar 26, 2015 |
0.10.3 | Mar 26, 2015 |
0.10.2 | Mar 26, 2015 |
0.10.1 | Feb 4, 2015 |
0.10 | Jan 30, 2015 |
0.9.6 | Jun 7, 2014 |
0.9.5 | Jun 7, 2014 |
0.9.4 | Aug 26, 2013 |
0.9.3 | Jul 25, 2013 |
0.9.2 | Jul 18, 2013 |
0.9.1 | Jun 14, 2013 |
0.9 | Jun 13, 2013 |
0.8.3 | Feb 5, 2012 |
0.8.2 | Dec 16, 2011 |
0.8.1 | Sep 30, 2011 |
0.8 | Sep 30, 2011 |
0.7.2 | Sep 30, 2011 |
0.7.1 | Jul 26, 2011 |
0.7 | Jul 24, 2011 |
0.6.2 | Apr 24, 2010 |
0.6.1 | Apr 13, 2010 |
0.6 | Feb 19, 2010 |
0.5.1 | Jul 10, 2009 |
0.5 | Apr 25, 2009 |
0.4.1 | Jan 11, 2009 |
0.4 | Nov 23, 2008 |
0.3.1 | Jun 24, 2008 |
0.3 | Jun 15, 2008 |
0.2 | Feb 14, 2008 |
0.1 | Dec 10, 2007 |
这个组织下的每个项目单拿出来都是响当当的存在:
- Click — Beautiful, composable command line interface creation kit.
- Flask — a flexible and popular web development framework
- ItsDangerous — Safely pass trusted data to untrusted environments and back.
- Jinja — a full featured template engine for Python
- MarkupSafe — Safely add untrusted strings to HTML/XML markup.
- Quart — an async reimplementation of flask
- Werkzeug — The comprehensive WSGI web application library.
Nginx 商用版 1.5.7 (2013 年) 开始支持 sticky 指令。
文档: https://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky
Syntax: sticky cookie name [expires=time] [domain=domain] [httponly] [samesite=strict|lax|none] [secure] [path=path];
sticky route $variable ...;
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
Default: —
Context: upstream
开源版有 nginx-sticky-module。
C 语言写的,BSD 协议。
代码看起来并不复杂,如果需要用到的时候,可以进行一个粗略的 Review。
# 下载 nginx 源码 (2016-04-26)
wget http://nginx.org/download/nginx-1.10.0.tar.gz http://nginx.org/download/nginx-1.10.0.tar.gz.asc
gpg --verify nginx-1.10.0.tar.gz.asc
# 下载 nginx-sticky-module (2015-08-06)
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/1.2.6.zip
unzip 1.2.6.zip
cd nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d/
unzip nginx-1.10.0.zip
cd nginx-1.10.0/
# 其他参数按需添加
./configure --add-module=../nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d/
make && make install
# Configuration summary
# + using system PCRE library
# + OpenSSL library is not used
# + md5: using system crypto library
# + sha1: using system crypto library
# + using system zlib library
# nginx path prefix: "/usr/local/nginx"
# nginx binary file: "/usr/local/nginx/sbin/nginx"
# nginx modules path: "/usr/local/nginx/modules"
# nginx configuration prefix: "/usr/local/nginx/conf"
# nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
# nginx pid file: "/usr/local/nginx/logs/nginx.pid"
# nginx error log file: "/usr/local/nginx/logs/error.log"
# nginx http access log file: "/usr/local/nginx/logs/access.log"
# nginx http client request body temporary files: "client_body_temp"
# nginx http proxy temporary files: "proxy_temp"
# nginx http fastcgi temporary files: "fastcgi_temp"
# nginx http uwsgi temporary files: "uwsgi_temp"
# nginx http scgi temporary files: "scgi_temp"
upstream {
sticky;
server 127.0.0.1:9000;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h]
[hash=index|md5|sha1] [no_fallback] [secure] [httponly];
CentOS 下的安装:
sudo yum install -y httpd-utils
Debian/Ubuntu 下的安装:
sudo apt install -y apache2-utils
ab -n 请求数 -c 并发书 URL
常用参数:
-n
请求数-c
并发数-t
持续测试时间-k
启用 HTTP KeepAlive-H
设置请求头-m
请求方式-T
设置 Content-Type-p
设置 POST 数据文件如果 POST 请求:
echo 'key1=value1&key2=value2' > /tmp/postdata
-T 'application/x-www-form-urlencoded' -p postdata
echo '{"key1":"value1","key2":"value2"}' > /tmp/postdata
-T 'application/json' -p postdata
执行 ab -n100 -c10 https://www.baidu.com/
可以得到以下结果:
需要重要关注的数据做了标记,分别是:
测试持续时间 / 请求数
并发数 / 吞吐量
Update @ 2021-12-29
url="https://www.baidu.com/"
rm -rf /tmp/httpbench-*.log
for c in {1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,150,200,250,300,350,400,450,500,600,700,800,900,1000};
do echo "==== Concurrency Level: $c ===="; let n=$((c * 100)); ab -n $n -c $c $url > /tmp/httpbench-$c.log; sleep 10; done;
然后用 Python 脚本解析 ab 输出生成报告。
Python 代码就不贴了, 如果感兴趣可以打开看看: abReport.py
如果觉得我的方案不妥当,非常欢迎提出意见或建议。
Update @ 2021-12-30:
又对 abReport.py
做了调整 (abReport2.py),现在可以输出一个 ECharts 图表了(尽整些花里胡哨的东西)。