CLIPS漏洞扫描推荐程序无法处理用户输入及生成有效推荐求助
CLIPS漏洞扫描工具推荐程序问题排查与修复
核心问题拆解
多实例
user-preference事实导致规则不匹配
原代码中,选择扫描类型时断言一个仅含scan-type的user-preference事实,选择环境时又断言一个仅含environment的新事实。而推荐规则要求同一个事实同时具备scan-type和environment两个槽值,因此永远无法触发推荐逻辑。无效输入后提问流程中断
在环境提问规则中,输入非法值时未重置question-progress的stage状态,导致规则执行一次后就不再触发,用户无法重新输入正确值。规则触发顺序异常
no-solution规则与推荐规则的触发条件都包含question-progress (stage complete),默认情况下CLIPS可能优先执行no-solution,导致即使推荐规则能触发,也会先输出"No scanner recommendations"。
修复后的完整代码
(deftemplate user-preference (slot scan-type (type SYMBOL)) (slot environment (type SYMBOL))) (deftemplate scanner-recommendation (slot scanner-name (type STRING)) (slot description (type STRING))) (deftemplate question-progress (slot stage (type SYMBOL))) ;; Initialize question stage (defrule initialize-question-stage (not (question-progress)) => (assert (question-progress (stage next))) (printout t "Initialization complete. Stage set to 'next'." crlf)) ;; Rule to ask initial scan type (defrule ask-scan-type (not (user-preference (scan-type ?))) ?f <- (question-progress (stage next)) => (printout t "What type of scan are you interested in? (webapp/network/cloud/infrastructure): " crlf) (bind ?input (read)) (if (or (eq ?input webapp) (eq ?input network) (eq ?input cloud) (eq ?input infrastructure)) then (assert (user-preference (scan-type ?input) (environment nil))) (printout t "Scan type set to: " ?input crlf) (retract ?f) (assert (question-progress (stage follow-up))) else (printout t "Invalid input. Please enter 'webapp', 'network', 'cloud', or 'infrastructure'." crlf) (retract ?f) (assert (question-progress (stage next))))) ;; Ask environment for webapp scans (defrule ask-webapp-environment (user-preference (scan-type webapp) (environment nil)) ?f <- (question-progress (stage follow-up)) => (printout t "Are you looking for a comprehensive or entry-level webapp scanner? " crlf) (bind ?input (read)) (if (or (eq ?input comprehensive) (eq ?input entry-level)) then (modify (user-preference) (environment ?input)) (printout t "Environment set to: " ?input crlf) (retract ?f) (assert (question-progress (stage complete))) else (printout t "Invalid input. Please enter 'comprehensive' or 'entry-level'." crlf) (retract ?f) (assert (question-progress (stage follow-up))))) ;; Ask environment for network scans (defrule ask-network-environment (user-preference (scan-type network) (environment nil)) ?f <- (question-progress (stage follow-up)) => (printout t "Do you prefer deep or fast network scanning? " crlf) (bind ?input (read)) (if (or (eq ?input deep) (eq ?input fast)) then (modify (user-preference) (environment ?input)) (printout t "Environment set to: " ?input crlf) (retract ?f) (assert (question-progress (stage complete))) else (printout t "Invalid input. Please enter 'deep' or 'fast'." crlf) (retract ?f) (assert (question-progress (stage follow-up))))) ;; Ask environment for cloud scans (defrule ask-cloud-environment (user-preference (scan-type cloud) (environment nil)) ?f <- (question-progress (stage follow-up)) => (printout t "Are you focused on cloud security or container security? " crlf) (bind ?input (read)) (if (or (eq ?input cloud) (eq ?input container)) then (modify (user-preference) (environment ?input)) (printout t "Environment set to: " ?input crlf) (retract ?f) (assert (question-progress (stage complete))) else (printout t "Invalid input. Please enter 'cloud' or 'container'." crlf) (retract ?f) (assert (question-progress (stage follow-up))))) ;; Ask environment for infrastructure scans (defrule ask-infrastructure-environment (user-preference (scan-type infrastructure) (environment nil)) ?f <- (question-progress (stage follow-up)) => (printout t "Is this for IT infrastructure or endpoint security? " crlf) (bind ?input (read)) (if (or (eq ?input infrastructure) (eq ?input endpoint)) then (modify (user-preference) (environment ?input)) (printout t "Environment set to: " ?input crlf) (retract ?f) (assert (question-progress (stage complete))) else (printout t "Invalid input. Please enter 'infrastructure' or 'endpoint'." crlf) (retract ?f) (assert (question-progress (stage follow-up))))) ;; Recommendations based on user input (设置更高优先级确保先触发) (defrule recommend-invicti (salience 10) (user-preference (scan-type webapp) (environment comprehensive)) => (assert (scanner-recommendation (scanner-name "Invicti") (description "Best for comprehensive webapp scanning."))) (printout t "Recommendation rule triggered for Invicti." crlf)) (defrule recommend-stackhawk (salience 10) (user-preference (scan-type webapp) (environment entry-level)) => (assert (scanner-recommendation (scanner-name "StackHawk") (description "Best entry-level scanner for webapp security."))) (printout t "Recommendation rule triggered for StackHawk." crlf)) ;;; Other scan recommendations with same / similar code to Webapp scan reccommendations ;;; e.g. network, cloud and infrastructure ;; Output best solution if scanner recommendation exists (优先级高于no-solution) (defrule best-solution (salience 5) (question-progress (stage complete)) (scanner-recommendation (scanner-name ?name) (description ?desc)) => (printout t "Recommended Scanner: " ?name crlf) (printout t "Description: " ?desc crlf)) ;; No solution if no scanner-recommendation is found (defrule no-solution (salience 0) (question-progress (stage complete)) (not (scanner-recommendation (scanner-name ?))) => (printout t "No scanner recommendations based on your selections." crlf))
关键修复说明
- 统一
user-preference事实实例
- 初始化扫描类型时,断言一个包含
scan-type和默认environment nil的user-preference事实。 - 选择环境时,使用
modify命令更新已有user-preference事实的environment槽值,而非新建事实,确保同一个事实包含两个槽的有效值。
修复无效输入后的流程重置
在所有环境提问规则的错误分支中,添加retract ?f和assert (question-progress (stage follow-up)),确保用户输入错误后,规则能再次触发重新提问。调整规则优先级
给推荐规则(recommend-*)设置salience 10,best-solution设置salience 5,no-solution设置salience 0,确保推荐逻辑先执行,避免no-solution提前触发。
内容的提问来源于stack exchange,提问作者user28112888
相关产品推荐
相关产品推荐

