不用精通,但得读得懂:安全这行为什么绕不开编程

admin 2026-09-23 06:26:08 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文论证安全从业者需具备基础编程能力而非精通。招聘数据显示Python与自动化是安全岗位最稳定技能组合,NIST人才框架也将软件开发列为正式类目。文章通过工具开发失败、白盒审计、报告撰写三个案例说明编程能力是解决性能、误报、可执行性等问题的关键。提出四个能标准:能读、能改、能写、能说清,并给出三个月学习路径与可复用脚本骨架,强调边写边学、重视可观测性。 综合评分: 88 文章分类: 安全意识,安全开发,安全培训,实战经验


不用精通,但得读得懂:安全这行为什么绕不开编程

原创

Sink Sink

船山信安

2026年9月20日 17:17 湖南

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

工程观察 · ENGINEERING

不用精通,但得读得懂:安全这行为什么绕不开编程

开发视角 · 写给学安全的人

这个问题我被问过很多次,答案一直没变:不用精通,但得读得懂。不是让你去写几万行的系统,是让你在工具跑不出结果、在报告需要说清”改哪里”的时候,不至于只能点头。先把数据摆出来,比讲道理有说服力。

01招聘在考什么:Python 41%,渗透测试 14%

先看一份 2026 年针对 Cybersecurity Engineer 岗位的 JD 统计。它把技能按出现频率分了三档,其中”常见要求”这一档是这样排的:

| | | | | — | — | — | | 技能 | 出现频率 | 说明 | | 自动化 Automation | 44.5% | 所有技能里最高 | | Python | 41% | 唯一的通用编程语言 | | AWS / Azure / GCP | 37.6% / 30.8% / 21.9% | 多云叠加要求 | | CI/CD | 25.7% | 研发流程进安全岗 | | 渗透测试 Pentest | 14% | 与 OWASP 13.3% 同档 |

同一份统计里还写着一句话,我觉得比排名更值得琢磨:没有任何一项技能出现在超过一半的岗位里。作为对比,软件工程岗位里 Python 出现在 70% 以上、SQL 在 71% 以上。

安全岗位的要求是分散的,但“自动化 + Python”是最稳定的一对:两者的共现提升度是 1.49,意思是要求”自动化”的岗位,比随机概率高出 49% 会同时要求 Python。这两者其实是一个信号。

再说一个更底层的事实。NIST 的《网络安全人才框架》(NICE Framework,SP 800-181 Rev 1)里,”安全供给”大类下专门设了一个 软件开发(DEV) 特殊领域,下面挂着 Software Developer(SP-DEV-001)和 Secure Software Assessor(SP-DEV-002)两个岗位角色。也就是说,在这个沿用最广的人才标准里,写代码本身就是网络安全人才的一个正式类目,不是加分项。

口径提醒:不同机构的统计差异很大。另有基于 2025–2026 年招聘的统计给出 Python 58%、渗透测试 45%;SpecOps 对 Indeed 上 843 条职位的统计则显示”编码经验”仅占 11%、渗透测试 14%。差异来自岗位层级与统计方法。趋势是一致的:越往中高级、越靠近甲方建设类岗位,编程权重越高。

02第一堵墙:工具跑不出结果的那天

有位从渗透转安全开发的人,把自己的经历写成文章发出来了。第一个任务是做内部漏洞扫描插件,他的做法很典型:找开源的 POC,改一改,能跑通就行。

两个月后交付——支持 20 多种漏洞检测、并发 500、输出漂亮的 HTML 报告。他自认为很牛。

测试团队第一天就打回来了。原因很朴素:扫一个目标要 15 分钟,人家有 100 个目标,跑完要 25 个小时。根本没法用。

除了慢,还有两条更致命:扫出来的漏洞没有做利用验证,全是误报,测试人员一个个手工确认,比不扫还累;报告字段花里胡哨,唯独没有修复建议,运维拿到不知道该改哪里。

这三个问题——性能、误报、不可执行——没有一个是安全知识能解决的。它们是软件工程问题:并发控制、结果验证、输出设计。

他后来总结了一句我认为很对的话:安全工具首先是”工具”,其次才是”安全的”。

03第二堵墙:读不懂别人的代码

黑盒测试的天花板,是你只能猜后端长什么样。猜对了是运气,猜错了就是漏。白盒不一样,你能看见”它为什么会写成这样”。

这一点上,写过程序和没写过程序的人,读代码的方式是两套:

| | | | — | — | | 没写过代码的人在读什么 | 写过程序的人在读什么 | | 这段看起来像不像有漏洞的写法 关键词能不能对上字典 | 作者当时想解决什么问题 这样写在什么条件下会失效 | | 工具报了就算,工具没报就过 | 工具扫不到的地方在哪 这里该不该有校验 |

举个最常见的例子。一个查询接口,前面把身份校验做得很规范:token 校验、过期判断、失效重登,一样不少。然后拿着这个身份直接去数据库取数据了。中间没有任何一行问过:这条数据是这个人的吗。

这是典型的越权。它没有任何危险函数,没有任何可疑关键字,扫描器扫不出来。你要看出来,唯一的办法是读懂那三四十行代码在干什么——而”读懂”这件事,前提是你自己写过。

同样,做白盒审计时你要跟踪用户输入从入口到敏感函数的整条数据流,判断中间有没有过滤、转义、预编译。这要求你知道框架的参数绑定是怎么做的、ORM 的查询是怎么拼出来的、中间件的执行顺序是什么。这些没有一样是工具能替你看的。


ONE LINE        精通是给开发岗位的要求。熟悉,是给你自己留的退路。

04第三堵墙:你说不出”改哪里”

这份工作里,最容易被忽略、也最见功力的一环,是报告的最后一米。

| | | | — | — | | 常见写法 | 开发真正能用的写法 | | 存在 SQL 注入风险,建议对用户输入进行过滤 | OrderDao.java:147 用字符串拼接构造查询,改为预编译参数绑定;同文件 132 行已有正确写法可参照 | | 建议加强权限校验 | 该项目已有 @PreAuthorize 注解体系,此接口漏配;参考 UserController:58 |

差别不在措辞,在于你能不能落到一处 diff 上。你说”建议修复”,开发听到的任务是模糊的;你说”147 行,改成 132 行那个写法”,他的任务是确定的。

而能给出这种建议的前提,是你知道 132 行的写法叫什么、为什么好。这又是编程。

05要熟到什么程度:四个”能”

先把心理负担卸掉:你不需要写几万行的系统。公开分享里有人给过一组经验值(不是精确统计,但和我的体感一致):

域名爬虫的核心逻辑:20 行      一个能用的内网扫描脚本:50 行      单个漏洞的验证脚本:30–80 行

这些代码不需要你懂装饰器、元类、异步 IO。requests 加标准库,够解决八成的自动化需求。

具体要熟到什么程度,我的标准是四个”能”:

1能读

拿到一份陌生语言的代码,能找到入口,能把数据流跟到终点。

2能改

开源 POC 跑不通,你能自己把它改通——改编码、改协议、改适配,而不是换一个脚本重试。

3能写

用三五十行,把一件之前手动做的事自动化掉。

4能说清

告诉开发改哪一行、改成什么、旁边有没有现成的正确写法。

06一段能直接改的骨架

单个漏洞的验证脚本,拆开就是四段:目标输入、构造请求、发送、判断结果。下面这个骨架不到四十行,四个部分都在,换个 payload 和判断条件就能复用:

import requests, argparse from concurrent.futures
import ThreadPoolExecutor
def check(target, timeout=8):
# 1. 构造:payload 单独放,改漏洞时只动这一处
 url = f"{target.rstrip('/')}/api/export"
payload = {"filename": "../../etc/passwd"}
try:
# 2. 发送:一定带超时,别让一个死连接拖垮整批
r = requests.post(url, json=payload, timeout=timeout, verify=False)
 except requests.RequestException as e:
return target, "ERROR", str(e)[:60]
# 3. 判断:不要只看状态码,要看响应内容特征
if r.status_code == 200 and "root:" in r.text:
return target, "VULN", f"{len(r.text)} bytes"
return target, "SAFE", f"HTTP {r.status_code}"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("file", help="每行一个目标")
ap.add_argument("-w", "--workers", type=int, default=10)
args = ap.parse_args()
targets = [l.strip() for l in open(args.file) if l.strip()]
 # 4. 并发:先 10 个,别上来就开 500
with ThreadPoolExecutor(max_workers=args.workers) as pool:
for t, verdict, detail in pool.map(check, targets):
print(f"[{verdict:5}] {t}  {detail}")
if __name__ == "__main__":
main()

这段代码里真正值钱的不是语法,是四个细节:超时、异常兜底、并发收敛、判断看内容不看状态码。缺任何一条,它跑一百个目标就会出一次洋相——而这正是上一节那位同行的第一课。

07三个月怎么走

公开分享里有一条路径,我按自己的经验微调过。前提不是每天看两小时视频,而是每天至少写五十行:

| | | | | — | — | — | | 阶段 | 时间 | 标志性成果 | | 读懂 | 第 1–2 周 | 能指出一段登录代码的注入点 | | 改通 | 第 3–4 周 | 把开源脚本适配到自己的目标环境 | | 独立写 | 第 5–8 周 | 自动化掉一个之前手动做的工作流 | | 稳定产出 | 第 2–3 月 | 攒下 5–10 个自己写的脚本 |

两个必须避开的坑。

别等”学完了”再写。看两天语法就开始抄例子、改例子。边写边查的效率,比干看高得多。

别只盯着漏洞,忘了可观测性。那位同行后来做的 WAF 规则引擎上线后 CPU 动不动飙到 100%,却没有任何日志——他最后是靠在关键函数里加 print(time.time()) 一行行定位的。安全工具多半是 7×24 跑的底座组件,日志、指标、告警是必修课,不是附加题。


这行里,工具会替你跑,但不会替你判断。工具说”这里有漏洞”,你得知道依据是什么;工具说”这里没问题”,你得知道它漏掉了什么。

       而判断这件事,只对读得懂代码的人开放。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。

本文转载自:船山信安 Sink Sink《不用精通,但得读得懂:安全这行为什么绕不开编程》

评论:0   参与:  0