ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SAP审计程序实战:从用户日志到ABAP报表的证据链固化

SAP审计程序实战:从用户日志到ABAP报表的证据链固化 简介面向SAP系统审计人员及企业内控、IT合规岗位的一份程序清单将审计流程按阶段拆解先从组织架构、安全策略、系统架构、接口与版本模块等维度完成总体了解再细化到SAP客户端、公司代码、业务范围、工厂、采购组织、销售组织等配置对象的核对并延伸至设计实施阶段的规划、人员配备、变更控制与项目治理评估。资源为1个doc文档约112KB内容以列表式检查项呈现同时标明了T000、T001、T024W等常用配置表的查询路径适合在正式审计前逐项梳理证据、制定访谈与测试计划。已有408人学习/下载。通过这套框架可快速定位需要获取的制度文档、系统表与配置参数形成可复用的SAP审计工作底稿基础尤其适合初次承担SAP审计任务或需要完善审计程序的团队参考。1. 审计程序没那么玄先在表里把“痕迹”找齐很多同事一提 SAP 审计程序就觉得应该有一套现成报表点一下就能导出“谁改了什么”。真实情况恰恰相反SAP 系统里的登录记录、权限变更、配置修改散落在几十张表里不同模块还有各自的日志切换开关直接看表经常得到一段零散的凭证号拼不出完整证据链。所谓审计程序本质是把这些痕迹按审计期间串成一条可验证的线索交给 Basis、财务审计和权限整改项目去回答“谁、在什么时候、通过什么入口、动过什么”。这篇文章不适合只想看概念的人适合已经接到审计任务、需要立刻知道先从哪些表入手以及准备自己写一段 ABAP 报表把审计结果固化下来的从业者。2. 审计程序要看哪些表从登录日志到变更凭证的取证地图2.1 登录、密码和锁定状态审计程序先查的几张表一次正经的 SAP 审计通常从“用户是否存在未使用的权限”开始。最常用的是USR02它是用户主数据里登录相关信息的汇总表。审计时重点关注几个字段UFLAG是用户的锁定状态很多系统里存在大量“已锁定但权限仍然有效”的账号这类账号在权限矩阵审计里是灰点USTYP是用户类型Dialog、Service、System、CPIC 等不同类型审计策略完全不同TRDAT是用户上次直接登录日期结合当前日期一算就能找出长期未登录但还没被锁定的账号GLTGV和GLTGB是账号的有效期起止。审计程序里最常做的一类检查就是把这些字段组合成一张“用户清单报表”再按日期区间过滤。表USR40则是系统级的非法密码表。严格的信息安全审计会要求把常见弱密码、默认密码往里灌但实际操作中很多项目只是象征性放几条审计程序应该把USR40的内容导出来核对入口配置。密码规则相关的参数也不该漏比如登录失败次数限制、密码有效期这些参数在 RZ11 里可以查到最好把参数名和当前值一并打印进审计底稿否则审计报告里写“密码策略未见异常”会显得没有依据。真正做过 SAP 审计的人都会先做这一层“用户画像盘点”再往下钻配置。表名作用审计关注点USR02用户登录状态与主数据信息锁定状态、最后登录日期、有效期USR40系统级拒绝密码表是否覆盖弱密码、密码是否未过期AGR_USERS用户与角色的直接分配关系角色分配是否超过有效期AGR_AGRS角色之间的组合关系是否存在角色互相嵌套、聚合后放大权限登录日志这块还有一个容易漏掉的细节USR02只能看到最近一次的登录日期历史登录行为要依赖系统安全审计日志也就是事务代码 SM19 和 SM20 的配置。审计人员通常要求 Security Audit Log 至少打开到中等级别否则只能证明“账号当前没登录过”无法证明“这个用户之前没做违规操作”。很多项目在初期实施时不考虑审计等到内审要求提供近三个月的登录记录才去补结果只能补到开关打开之后的数据这就是审计程序最典型的踩坑场景。2.2 变更文档谁改过配置和主数据靠 CDHDR/CDPOS 还原用户权限之外审计程序另一个硬需求是“谁改了什么”。SAP 里记录配置和主数据变更的标准机制是 change document也就是变更文档。表头是CDHDR记录了这一次变更发生在哪个对象类、哪个对象 ID、什么时间、哪个用户名、什么事务代码明细表是CDPOS记录到字段级旧值、新值、字段名。审计程序把这两张表关联起来才能还原出“张三在昨天上午十点把销售订单类型 A 的号码范围从 100000 改成了 200000”。但变更文档不是所有表都自动记录。很多开发者自己建的自定义表如果建表时没勾“记录数据更改”那这张表的任何修改都不会进CDHDR。这时候你在审计程序里查不到记录不代表没人改过只是系统根本没有留痕。判断方法非常简单在数据字典 SE11 里打开这张表看“更改文档”字段有没有打勾没勾的话要么补上这个设置并重新激活要么把这张表列入“无审计轨迹”的清单明确告诉业务方这属于审计盲区。业务表的变更文档检查和定位常用事务代码是SCAT它按对象类别列出哪个业务对象开启了变更文档。像是通过 SM30 维护的配置表只要对象本身支持变更文档入口方式其实不太重要不管你是用传统 SM30 还是 Fiori 里的配置维护应用落到后台都是同样的对象写日志。审计程序在制作“变更轨迹报表”时通常会要求把CDHDR的事务代码、用户、时间作为维度再挂CDPOS的字段级 diff。直接在CDHDR单表查会很空容易漏掉关键数据。2.3 权限审计起点SUIM 信息中心和标准用户清单报表权限审计如果从零手写工作量会失控因为 SAP 授权模型本身很复杂用户直接拿到角色角色里有复合角色复合角色展开到单角色单角色再映射到权限对象和字段级权限约束。真正决定用户能干哪些事务的是经过合法展开后的用户主权限。好在 SAP 给了现成的信息中心 SUIM官方定位就是给审计和权限管理员用的查询入口不用每一段都自己拼 SQL。操作层面用 SUIM 可以按事务代码查“哪些用户拥有某事务的执行权限”、按权限对象查“哪些角色拥有 S_TCODE 之外的敏感对象”、按角色查“角色分配给谁、继承关系是什么”。配合标准报表 RSUSR002、RSUSR003 等可以直接出用户列表和权限列表。实际项目里最常做的检查是“拥有敏感事务代码的用户清单”敏感事务代码通常包括创建用户、修改角色、直接修改表数据、传输请求导入等。即使是权限设置再混乱的 client也能通过 SUIM 把带S_TCODE的敏感项筛出来再回到USR02判断这些用户是否还在用。这样做的好处是审计程序不用完全从零造轮子先拿 SUIM 做初筛再用 ABAP 报表做二次加工和留档。3. 自己写一个 SAP 审计报表从数据探查到 ABAP 代码骨架3.1 先用 SE16N 做数据探查别急着写代码写审计程序之前我会建议先在 SE16N 里把目标表的字段构成、数据量级、日期范围摸一遍。直接写代码容易遇到“字段名写错但编译通过”“筛选条件把关键数据过滤掉”这类问题翻车成本比想象中高。SE16N 的入口路径是事务代码 SE16N输入表名后进入查询界面左侧点击字段选择可以把自己关心的字段添加到输出列表再在下方设置过滤条件。比如查USR02时先只过滤UFLAG 01之类表示锁定的标志看看锁定用户有多少再清空条件按TRDAT区间查最近登录用户数量。这个过程是为了确认审计程序需要处理的数据形态。要注意的是 SE16N 默认虽然能改数据但审计场景下千万不要用它在界面里直接更新字段那本身会成为新的审计风险点。观察数据时也建议使用按需读取字段不要一次把明细字段全部选中否则几百万行数据会把报表会话拖死。3.2 一个可跑的查用户清单报表用户类型、有效期、最后登录一次查清做审计报表时不会被翻车惯一个相对标准的 ABAP 骨架长这样。它的作用是把用户主数据、最后登录时间、当前有效期和角色分配塞进一张内表再输出 ALV 清单。以下代码是一段可编译的演示版本正式环境请加权限检查和错误处理。REPORT z_audit_users. TABLES: usr02, agr_users. SELECT-OPTIONS: s_bname FOR usr02-bname DEFAULT *, s_trdat FOR usr02-trdat, s_ustyp FOR usr02-ustyp. TYPES: BEGIN OF ty_user, bname TYPE usr02-bname, ustyp TYPE usr02-ustyp, trdat TYPE usr02-trdat, uflag TYPE usr02-uflag, gltgv TYPE usr02-gltgv, gltgb TYPE usr02-gltgb, roles TYPE string, END OF ty_user. DATA: gt_user TYPE TABLE OF ty_user, gs_user LIKE LINE OF gt_user, ls_agr TYPE agr_users, lv_roles TYPE string. START-OF-SELECTION. SELECT bname ustyp trdat uflag gltgv gltgb FROM usr02 INTO CORRESPONDING FIELDS OF TABLE gt_user WHERE bname IN s_bname AND trdat IN s_trdat AND ustyp IN s_ustyp. LOOP AT gt_user ASSIGNING FIELD-SYMBOL(fs_user). CLEAR: lv_roles, ls_agr. SELECT agr_name FROM agr_users INTO ls_agr-agr_name WHERE uname fs_user-bname AND agr_type S AND from_dat sy-datum AND to_dat sy-datum. IF lv_roles IS INITIAL. lv_roles ls_agr-agr_name. ELSE. CONCATENATE lv_roles ls_agr-agr_name INTO lv_roles SEPARATED BY ,. ENDIF. ENDSELECT. fs_user-roles lv_roles. ENDLOOP. LOOP AT gt_user INTO gs_user. WRITE: / gs_user-bname, gs_user-ustyp, gs_user-trdat, gs_user-uflag, gs_user-roles. ENDLOOP.这段代码核心是先按参数过滤USR02再通过AGR_USERS把每个用户直接分配的有效单角色拼成一串。AGR_TYPE S表示只看单角色复合角色先不展开这正是审计上常用的“先看直接分配再做派生分析”的思路。FROM_DAT和TO_DAT是角色有效期审计时通常只取当前生效的角色避免把过期角色也计算进去导致权限虚高。输出没有走 ALV真实场景建议把gs_user传进 SALV 模型审计人员可以按角色列过滤。3.3 把报表跑成变式审计期间、用户组、敏感权限过滤这套 ABAP 代码在不同审计口径下需要反复跑比如常规季度审计、专项权限整改、离任账号盘点。没必要每次都手工改筛选条件用变式存储参数就够了。执行程序进入选择屏幕后在浏览器或 SAP GUI 8.10 的工具栏里找“变式”按钮选择“保存”把当前筛选条件存成一个有业务含义的名字比如AUDIT_2025_Q1_EXCLUDE_GWS。我这边从老版本 GUI 到 8.10 都跑过类似程序关键是变式名要规范否则一年下来几十个变式没人分得清。参数设计上S_TRDAT是审计期间最常用的过滤项传日期区间就能看出谁在那段时间登录过。S_USTYP建议留空除非你想要专门排除通信用户。S_BNAME默认*但做离任审计时可以直接传一个用户名列表也可以排除 VIP 用户组。变式保存好之后后续还要配合后台作业做周期性审计留档这就能把“临时查一下”变成“每月定时出底稿”。从审计证据完整性角度看变式里最好固定一个“导出报告标题”把程序名、变式名、运行时间打进去免得后期对不上号。4. SAP 审计程序落地避坑指南日志丢失、结果脏、磁盘爆掉的真相4.1 日志查不到SM30 变更文档没开、CDHDR 进了归档现象审计程序跑完发现某个配置表在CDHDR里一张凭证都查不到但业务人员坚持说上个月改过。原因有两层。第一层是变更文档根本没开尤其是自定义表和部分维护视图系统从设计上就没有记录痕迹。第二层是历史数据被归档CDHDR和CDPOS这类日志表的数据量起来之后会做归档归档后再通过 SE16N 直查当然查不到旧数据它只是被挪到了归档文件里。这是 SAP Basis 体系中非常常见的仓库清理策略不是数据丢失。解决先查SCAT确认这个业务对象是否支持且开启了变更文档如果没开补上配置并让相关事务代码重新激活。如果是归档原因用事务代码SARA去查归档文件不能指望审计程序直接读在线表。遇到归档场景审计底稿里应同时保存“查询时间”和“数据可追溯区间”否则这张报表会被审计委员会判定为证据不完整。4.2 报表结果与实际权限不一致角色缓存和派生角色现象SUIM 或自写报表显示某用户拥有一个高危角色但用户在实际测试时打开事务代码提示没有权限反过来也出现过报表里看不到角色用户真能执行的情况。原因权限检查的运行时数据也就是用户主权限来源于角色展开后的授权配置不是简单的一张表。角色改了菜单、删了权限对象如果没做用户比较和权限生成用户主权限里还残留着旧授权相反如果通过后端表直接插了权限数据而没有走标准角色生成内存里可能已经用了新配置查询表里还没有。官方有一个比较过程一般通过 SU01 或权限调整批次去同步现场经常看到这一层没跑就去查表结果自然对不上。解决先做一次完整的用户权限比较让角色变更正确展开并写回USR04、UST04等相关表再重新跑审计报表。自写报表建议明确标注“来源权限主数据表”不要直接声称这就是有效权限。作为审计底稿要用实际事务代码的AUTHORITY-CHECK做抽样验证靠表结果一言堂很容易翻车。4.3 审计日志磁盘爆掉SM19/SM20 只开后不清理现象开启安全审计日志之后系统过几周突然出现大量写日志失败告警登录变慢甚至部分批处理报错。进 SM20 一看审计日志文件已经占满独立盘。原因安全审计日志本身受到严格写入保护不像普通应用日志能随便删除。很多人开了 SM19 审计级别后没有同步留意文件保留策略。审计日志按天写盘量小一天几百 MB量大的 client 一天几个 GB 都不奇怪一旦空间耗尽后面的证据会直接缺一段。解决做审计程序的人要把“日志留档策略”也当成程序的一部分。建议先确认审计日志所在挂载目录SAP Basis 收到空间告警时不要急着扩容先看 SM20 里的日志跨越时间段和文件大小。要把保留周期做成参数比如只保留 180 天超期文件转入归档系统。还要注意跨 client 场景多个 client 的日志会按不同规则写入只清理一个 client 不够。日志缺失时段要记录原因审计底稿里主动说明比被动被发现要好得多。4.4 传输请求和配置变更对不上E070 只看请求头没用现象审计时想验证“这个配置到底走没走传输”查 E070 能看到请求头但打开传输任务单里面只有程序对象没有业务配置数据于是断言该对象没有传输。原因传输请求分好几种对象类型程序、类、表结构走的是对象列表而配置表内容通常通过E071K记录“表名加表键”。E070 是请求头E071 是对象清单还要压到 E071K 才能看到具体是哪些配置条目被发到目标系统。很多业务配置表本身就是跨系统覆盖的请求头显示导入成功目标系统里却因为覆盖顺序问题被别的请求冲掉了。解决审计传输链路时至少同时核对E070、E071、E071K三段数据。还要检查目标系统侧的导入日志以及导入之后的覆盖规则。传输日志里带着修改者、请求任务、导入时间和系统 ID这才是审计上最硬的证据。只看 E070 的结果往往只能证明“有人建了请求”证明不了“目标系统真的生效”。4.5 直连数据库查表跨 client 与归档数据双重复合现象为了快速出审计数据有人不通过 SAP 应用层直接用外部工具连接底层数据库执行 SQL。结果发现同一张日志表的数据量和 SE16N 能看到的对不上最终审计结果被质疑。原因底层表几乎都带MANDT字段不同 client 的数据是按字段区分的。直连数据库时如果漏写 client 条件会把所有 client 的数据混在一张结果集里SE16N 则是默认登录 client 后自动带上的。此外直连数据库看不到逻辑归档状态可能在读已标记删除的历史行。对 SAP 审计场景而言这样的数据既不能通过标准权限控制也无法追踪用户登录上下文严格讲不应直接作为审计凭证。解决除非做紧急数据救援审计程序统一走应用层要么 SE16N、SUIM要么 ABAP 自写报表。这样系统中保留的授权检查、变更文档逻辑、client 上下文都会自动生效。如果确实必须底层取数要在导出脚本里强制限定MANDT 800并且和 SE16N 结果做抽样比对比对过关后再放进底稿。5. 把审计程序变成每月留档后台作业、路径命名、证据固化5.1 用后台作业把审计报表定期导出到应用服务器一个能重复执行的审计程序最后一定要能自动落地成文件。最简单的方式是先把程序输出打成 ABAP 列表通过打印到外部系统再转文本但这种方式在特殊字符多时不够稳。常见做法是直接在 ABAP 里用OPEN DATASET把结果写到应用服务器目录再通过后台作业每天或每月跑一次。DATA(lv_path) /usr/sap/audit/ sy-datlo _users.txt. OPEN DATASET lv_path FOR OUTPUT IN TEXT MODE ENCODING DEFAULT. LOOP AT gt_user INTO gs_user. TRANSFER gs_user-bname TO lv_path. ENDLOOP. CLOSE DATASET lv_path.这里注意不要用GUI_DOWNLOAD这类依赖前端会话的函数后台作业没有输入窗口用它会直接报错。路径里带上系统日期文件名规范成“程序名_日期_变式名”是审计底稿管理里最省心的习惯。防止一次后台作业异常导致文件覆盖比较好的做法是先写临时文件成功后再改名成正式文件名。5.2 给导出的审计结果算一个哈希值相当于给底稿吃了后悔药定期导出 ALV 列表只是第一步主持人还会问“你怎么证明这份文件没被事后改过”。我的做法是在导出文件旁边放一个摘要值用 SHA-256 之类算法跑一遍把摘要存进另一个人管理的路径或审计平台。等下次审计时再对一次摘要两边对不上就说明中间被改动过。SAP 里有哈希类函数可以调用也可以把文件拉下来后用独立脚本生成摘要。关键是这个动作必须在导出后立刻完成并和底稿分开放否则它就不叫证据链固化。做过的项目里最容易翻车的一环不是报表逻辑而是没人关心“这份数据到底有没有留下操作人”。我习惯在底稿第一页就写明程序名、变式名、运行时间、系统 ID、client、导出路径、文件哈希值。后来即使业务方和审计组吵架这串记录也能拿出来反推“当时谁按了什么条件跑了什么程序”。希望这一套步骤能帮你把 SAP 审计程序从临时报表变成真正的证据工具。本文还有配套的精品资源点击获取
返回列表