├── .babelrc ├── .env.sample ├── .eslintrc.js ├── .github └── workflows │ ├── eslint.yml │ ├── releaseNotice.yml │ ├── reviewNotice.yml │ └── tests.yml ├── .gitignore ├── README.md ├── changelog.txt ├── composer.json ├── css ├── images │ ├── index.php │ ├── ui-icons_444444_256x240.png │ ├── ui-icons_555555_256x240.png │ ├── ui-icons_777620_256x240.png │ ├── ui-icons_777777_256x240.png │ ├── ui-icons_cc0000_256x240.png │ └── ui-icons_ffffff_256x240.png ├── index.php ├── jquery-ui.min.css ├── spbc-admin.min.css ├── spbc-dashboard-widget.min.css ├── spbc-icons.min.css ├── spbc-public.min.css ├── spbc-settings-media.min.css ├── spbc-settings.min.css ├── spbc-table.min.css └── src │ ├── spbc-admin.css │ ├── spbc-dashboard-widget.css │ ├── spbc-icons.css │ ├── spbc-public.css │ ├── spbc-settings-media.css │ ├── spbc-settings.css │ └── spbc-table.css ├── gulpfile.js ├── i18n ├── index.php ├── security-malware-firewall-ru_RU.mo ├── security-malware-firewall-ru_RU.po └── security-malware-firewall.pot ├── images ├── att_triangle.png ├── index.php ├── logo.png ├── logo_small.png ├── logo_small_gray.png ├── new_window.gif ├── no.png ├── no_gray.png ├── pbar-ani.gif ├── preloader.gif ├── preloader2.gif ├── yes.png └── yes_gray.png ├── inc ├── admin-bar.php ├── admin-templates │ └── field-templates │ │ ├── checkbox.php │ │ ├── hidden.php │ │ ├── number.php │ │ ├── radio.php │ │ ├── select.php │ │ ├── text.php │ │ ├── textarea.php │ │ └── time.php ├── fw-update.php ├── index.php ├── settings-react │ ├── spbct-settings-react.php │ └── spbct-sync-react.php ├── spbc-admin.php ├── spbc-auth.php ├── spbc-backups.php ├── spbc-firewall.php ├── spbc-pluggable.php ├── spbc-scanner.php ├── spbc-settings.php ├── spbc-tools.php └── spbc-wpcli.php ├── index.php ├── install ├── index.php └── security-malware-firewall-mu.php ├── js ├── cleantalk-modal.min.js ├── cleantalk-modal.min.js.map ├── index.php ├── lib │ ├── chart │ │ ├── index.php │ │ └── spbc-dashboard-widget--chartjs.min.js │ ├── index.php │ └── jquery │ │ └── jquery-ui.min.js ├── public │ ├── 15ffeee5b966fab6df1989be4592d89e.png │ ├── 26841eb4a862f951af20.svg │ ├── 2c86476ce0cd763460fe.eot │ ├── 4e40a2ec13c745fb3b02.woff │ ├── bae698082a959c23069f.ttf │ ├── d0e8437c6ac4a5a78136.woff2 │ ├── d5c82efc0abb71716dbee1efc933cc7d.png │ ├── fd8034fa5a0db295baf70cbc662c24e2.gif │ ├── index.php │ ├── spbc-react-bundle.js.LICENSE.txt │ └── spbct-react-bundle.js ├── spbc-admin.min.js ├── spbc-admin.min.js.map ├── spbc-common.min.js ├── spbc-common.min.js.map ├── spbc-cookie.min.js ├── spbc-cookie.min.js.map ├── spbc-dashboard-widget.min.js ├── spbc-dashboard-widget.min.js.map ├── spbc-modal.min.js ├── spbc-modal.min.js.map ├── spbc-scanner-plugin.min.js ├── spbc-scanner-plugin.min.js.map ├── spbc-settings.min.js ├── spbc-settings.min.js.map ├── spbc-settings_tab--backups.min.js ├── spbc-settings_tab--backups.min.js.map ├── spbc-settings_tab--fswatcher.min.js ├── spbc-settings_tab--fswatcher.min.js.map ├── spbc-settings_tab--scanner.min.js ├── spbc-settings_tab--scanner.min.js.map ├── spbc-settings_tab--security_log.min.js ├── spbc-settings_tab--security_log.min.js.map ├── spbc-settings_tab--settings_general.min.js ├── spbc-settings_tab--settings_general.min.js.map ├── spbc-settings_tab--summary.min.js ├── spbc-settings_tab--summary.min.js.map ├── spbc-settings_tab--traffic_control.min.js ├── spbc-settings_tab--traffic_control.min.js.map ├── spbc-table.min.js ├── spbc-table.min.js.map ├── spbc-upload.min.js ├── spbc-upload.min.js.map └── src │ ├── react │ ├── assets │ │ ├── fail.png │ │ ├── fonts │ │ │ ├── icons │ │ │ │ ├── icons.eot │ │ │ │ ├── icons.svg │ │ │ │ ├── icons.ttf │ │ │ │ ├── icons.woff │ │ │ │ ├── icons.woff2 │ │ │ │ └── index.php │ │ │ └── index.php │ │ ├── preloader2.gif │ │ ├── spbc-icons.min.css │ │ └── yes.png │ ├── components │ │ ├── App.js │ │ ├── Button │ │ │ ├── Button.js │ │ │ └── styles.css │ │ ├── ErrorBlock │ │ │ ├── ErrorBlock.js │ │ │ └── styles.css │ │ ├── InfoBlock │ │ │ ├── InfoBlock.js │ │ │ └── styles.css │ │ ├── LongDescriptionIco │ │ │ ├── LongDescriptionIco.js │ │ │ └── styles.css │ │ ├── Section │ │ │ ├── Section.js │ │ │ └── styles.css │ │ ├── SectionContent │ │ │ ├── SectionContent.js │ │ │ ├── SectionContentHtml.js │ │ │ └── SectionContentTable.js │ │ ├── SpbctAboutCT.js │ │ ├── SpbctPageNetworkDashboard.js │ │ ├── SpbctPageTabs.js │ │ ├── SvgIcons │ │ │ ├── CriticalUpdatesSvg.js │ │ │ ├── DashboardButtonSvg.js │ │ │ ├── FileSystemWatcherSvg.js │ │ │ ├── FirewallSvg.js │ │ │ ├── GeneralSettingsSvg.js │ │ │ ├── MalwareScannerSvg.js │ │ │ ├── SecurityLogSvg.js │ │ │ ├── SummarySvg.js │ │ │ ├── SupportButtonSvg.js │ │ │ └── SynchronizeSvg.js │ │ ├── Tab │ │ │ ├── Tab.js │ │ │ └── styles.css │ │ └── Table │ │ │ ├── Table.js │ │ │ ├── TableCell.js │ │ │ ├── TableHeading.js │ │ │ └── TableRow.js │ ├── config │ │ ├── Constants.js │ │ └── Tabs.js │ ├── hooks │ │ └── useSync.js │ ├── index.js │ ├── modules │ │ └── Http │ │ │ └── Ajax.js │ ├── pageElements │ │ ├── Header │ │ │ ├── Header.js │ │ │ └── styles.css │ │ ├── HiddenElements │ │ │ ├── HiddenElements.js │ │ │ └── styles.css │ │ ├── Sections │ │ │ ├── Sections.js │ │ │ └── styles.css │ │ ├── ServiceButtons │ │ │ ├── ServiceButtons.js │ │ │ └── styles.css │ │ └── Tabs │ │ │ ├── Tabs.js │ │ │ └── styles.css │ └── styles.css │ ├── spbc-admin.js │ ├── spbc-common.js │ ├── spbc-cookie.js │ ├── spbc-dashboard-widget.js │ ├── spbc-modal.js │ ├── spbc-scanner-plugin.js │ ├── spbc-settings.js │ ├── spbc-settings_tab--backups.js │ ├── spbc-settings_tab--fswatcher.js │ ├── spbc-settings_tab--scanner.js │ ├── spbc-settings_tab--security_log.js │ ├── spbc-settings_tab--settings_general.js │ ├── spbc-settings_tab--summary.js │ ├── spbc-settings_tab--traffic_control.js │ ├── spbc-table.js │ └── spbc-upload.js ├── lib ├── CleantalkSP │ ├── Common │ │ ├── API.php │ │ ├── CleantalkTools.php │ │ ├── Counter.php │ │ ├── Cron.php │ │ ├── DB.php │ │ ├── DB │ │ │ ├── SQLSchema.php │ │ │ └── index.php │ │ ├── DNS.php │ │ ├── Enqueue │ │ │ ├── Enqueue.php │ │ │ └── EnqueueDataDTO.php │ │ ├── Escape.php │ │ ├── HTTP │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ └── index.php │ │ ├── Helpers │ │ │ ├── Arr.php │ │ │ ├── CSV.php │ │ │ ├── Data.php │ │ │ ├── HTTP.php │ │ │ ├── Helper.php │ │ │ ├── IP.php │ │ │ └── index.php │ │ ├── LinkConstructor.php │ │ ├── Queue.php │ │ ├── RemoteCalls.php │ │ ├── Sanitize.php │ │ ├── Scanner │ │ │ ├── HeuristicAnalyser │ │ │ │ ├── Controller.php │ │ │ │ ├── DataStructures │ │ │ │ │ ├── ExtendedSplFixedArray.php │ │ │ │ │ ├── Token.php │ │ │ │ │ └── index.php │ │ │ │ ├── Exceptions │ │ │ │ │ ├── HeuristicScannerException.php │ │ │ │ │ └── index.php │ │ │ │ ├── HeuristicAnalyser.php │ │ │ │ ├── LICENSE.md │ │ │ │ ├── Modules │ │ │ │ │ ├── CodeStyle.php │ │ │ │ │ ├── Entropy.php │ │ │ │ │ ├── Evaluations.php │ │ │ │ │ ├── FunctionsDecryptorService.php │ │ │ │ │ ├── HTML.php │ │ │ │ │ ├── Includes.php │ │ │ │ │ ├── Mathematics.php │ │ │ │ │ ├── SQLs.php │ │ │ │ │ ├── Simplifier.php │ │ │ │ │ ├── Strings.php │ │ │ │ │ ├── Tokens.php │ │ │ │ │ ├── Transformations.php │ │ │ │ │ ├── Variables.php │ │ │ │ │ └── index.php │ │ │ │ ├── Structures │ │ │ │ │ ├── FileInfo.php │ │ │ │ │ ├── TokenGroups.php │ │ │ │ │ ├── Verdict.php │ │ │ │ │ └── index.php │ │ │ │ ├── Vendors │ │ │ │ │ ├── TiktokenPhp │ │ │ │ │ │ ├── LICENSE │ │ │ │ │ │ ├── data │ │ │ │ │ │ │ ├── characters.json │ │ │ │ │ │ │ ├── encoder.json │ │ │ │ │ │ │ ├── index.php │ │ │ │ │ │ │ └── vocab.bpe │ │ │ │ │ │ ├── index.php │ │ │ │ │ │ └── src │ │ │ │ │ │ │ ├── Encoder.php │ │ │ │ │ │ │ └── index.php │ │ │ │ │ └── index.php │ │ │ │ └── index.php │ │ │ └── SignaturesAnalyser │ │ │ │ ├── Controller.php │ │ │ │ ├── Exceptions │ │ │ │ ├── SignaturesScannerException.php │ │ │ │ └── index.php │ │ │ │ ├── LICENSE.md │ │ │ │ ├── Structures │ │ │ │ ├── FileInfo.php │ │ │ │ ├── Verdict.php │ │ │ │ └── index.php │ │ │ │ └── index.php │ │ ├── State.php │ │ ├── TT.php │ │ ├── Transaction.php │ │ ├── Validate.php │ │ └── index.php │ ├── Fpdf │ │ ├── Fpdf.php │ │ ├── Pdf.php │ │ ├── font │ │ │ ├── courier.php │ │ │ ├── courierb.php │ │ │ ├── courierbi.php │ │ │ ├── courieri.php │ │ │ ├── helvetica.php │ │ │ ├── helveticab.php │ │ │ ├── helveticabi.php │ │ │ ├── helveticai.php │ │ │ ├── index.php │ │ │ ├── symbol.php │ │ │ ├── times.php │ │ │ ├── timesb.php │ │ │ ├── timesbi.php │ │ │ ├── timesi.php │ │ │ └── zapfdingbats.php │ │ ├── img │ │ │ ├── index.php │ │ │ └── logo.png │ │ └── index.php │ ├── Monitoring │ │ ├── User.php │ │ └── index.php │ ├── Security │ │ ├── Firewall.php │ │ ├── Firewall │ │ │ ├── FirewallModule.php │ │ │ ├── FirewallModuleAbstract.php │ │ │ ├── Result.php │ │ │ └── index.php │ │ ├── LoginCollectingProtector.php │ │ ├── RenameLoginPage.php │ │ └── index.php │ ├── SpbctWP │ │ ├── API.php │ │ ├── Activator.php │ │ ├── AdjustToEnvironmentModule │ │ │ ├── AdjustToEnv │ │ │ │ ├── AdjustToEnvAbstract.php │ │ │ │ └── AdjustToEnvW3TotalCache.php │ │ │ ├── AdjustToEnvironmentHandler.php │ │ │ ├── AdjustToEnvironmentSettings.php │ │ │ └── Exceptions │ │ │ │ ├── ExceptionReverseAdjustClassNotExists.php │ │ │ │ └── ExceptionReverseAdjustNotIntervention.php │ │ ├── AdminBannersModule │ │ │ ├── AdminBanners │ │ │ │ ├── AdminBannerAbstract.php │ │ │ │ ├── AdminBannerCriticalFilesWarning.php │ │ │ │ ├── AdminBannerRenew.php │ │ │ │ ├── AdminBannerReview.php │ │ │ │ ├── AdminBannerTrial.php │ │ │ │ ├── AdminBannerWrongKey.php │ │ │ │ └── index.php │ │ │ ├── AdminBannersHandler.php │ │ │ └── index.php │ │ ├── CleantalkSettingsTemplates.php │ │ ├── Counters │ │ │ ├── FirewallCounter.php │ │ │ ├── SecurityCounter.php │ │ │ └── index.php │ │ ├── Cron.php │ │ ├── DB.php │ │ ├── DB │ │ │ ├── ColumnCreator.php │ │ │ ├── ColumnsAnalyzer.php │ │ │ ├── DbDataConverter.php │ │ │ ├── ObjectForOptionsInterface.php │ │ │ ├── SQLSchema.php │ │ │ ├── TablesAnalyzer.php │ │ │ ├── TablesCreator.php │ │ │ └── index.php │ │ ├── DTO │ │ │ ├── MScanFilesDTO.php │ │ │ ├── SecurityLogsDTO.php │ │ │ ├── SecurityLogsDataRowDTO.php │ │ │ └── index.php │ │ ├── Deactivator.php │ │ ├── Escape.php │ │ ├── FSWatcher │ │ │ ├── Analyzer │ │ │ │ ├── Analyzer.php │ │ │ │ └── index.php │ │ │ ├── Controller.php │ │ │ ├── Dto │ │ │ │ └── FSWatcherParams.php │ │ │ ├── Logger.php │ │ │ ├── Scan │ │ │ │ ├── Scan.php │ │ │ │ └── index.php │ │ │ ├── Service.php │ │ │ ├── Storage │ │ │ │ ├── FileStorage.php │ │ │ │ ├── Storage.php │ │ │ │ └── index.php │ │ │ ├── View │ │ │ │ ├── Phrases.php │ │ │ │ ├── View.php │ │ │ │ └── index.php │ │ │ └── index.php │ │ ├── FeatureRestriction │ │ │ ├── FeatureRestriction.php │ │ │ ├── FeatureRestrictionService.php │ │ │ ├── FeatureRestrictionState.php │ │ │ ├── FeatureRestrictionView.php │ │ │ └── index.php │ │ ├── Firewall.php │ │ ├── Firewall │ │ │ ├── BFP.php │ │ │ ├── FW.php │ │ │ ├── FirewallModule.php │ │ │ ├── FirewallState.php │ │ │ ├── TC.php │ │ │ ├── UploadChecker.php │ │ │ ├── WAF.php │ │ │ ├── WafBlocker.php │ │ │ ├── die_page_bfp.html │ │ │ ├── die_page_fw.html │ │ │ ├── die_page_tc.html │ │ │ ├── die_page_uploadchecker.html │ │ │ ├── die_page_waf.html │ │ │ └── index.php │ │ ├── G2FA │ │ │ ├── FixedBitNotation.php │ │ │ ├── GoogleAuthenticator.php │ │ │ └── index.php │ │ ├── HTTP │ │ │ ├── CDNHeadersChecker.php │ │ │ ├── Request.php │ │ │ └── index.php │ │ ├── Helpers │ │ │ ├── Arr.php │ │ │ ├── CSV.php │ │ │ ├── Data.php │ │ │ ├── HTTP.php │ │ │ ├── Helper.php │ │ │ ├── IP.php │ │ │ └── index.php │ │ ├── LinkConstructor.php │ │ ├── ListTable.php │ │ ├── Queue.php │ │ ├── RemoteCalls.php │ │ ├── RenameLoginPage.php │ │ ├── RestController.php │ │ ├── Sanitize.php │ │ ├── Scanner │ │ │ ├── Controller.php │ │ │ ├── Cure.php │ │ │ ├── CureLog │ │ │ │ ├── CureLog.php │ │ │ │ ├── CureLogRecord.php │ │ │ │ └── index.php │ │ │ ├── DBTrigger │ │ │ │ ├── DBTriggerModel.php │ │ │ │ ├── DBTriggerService.php │ │ │ │ └── DBTriggerView.php │ │ │ ├── DirectoryScan.php │ │ │ ├── FileInfoExtended.php │ │ │ ├── Frontend.php │ │ │ ├── Frontend │ │ │ │ ├── ModuleResult.php │ │ │ │ └── index.php │ │ │ ├── FrontendScan.php │ │ │ ├── Helper.php │ │ │ ├── IteratorResult.php │ │ │ ├── Links.php │ │ │ ├── OSCron │ │ │ │ ├── OSCronController.php │ │ │ │ ├── OSCronModel.php │ │ │ │ ├── OSCronTaskAnalyser.php │ │ │ │ ├── Objects │ │ │ │ │ └── OSCronTask.php │ │ │ │ ├── Shell │ │ │ │ │ ├── OSCronGetEnvCron.php │ │ │ │ │ └── OSCronSetEnvCron.php │ │ │ │ ├── Storages │ │ │ │ │ └── OsCronTasksStorage.php │ │ │ │ └── View │ │ │ │ │ ├── OSCronLocale.php │ │ │ │ │ └── OSCronView.php │ │ │ ├── ScanRepository.php │ │ │ ├── ScanStorage.php │ │ │ ├── ScannerInteractivity │ │ │ │ ├── RefreshDataDTO.php │ │ │ │ └── ScannerInteractivityData.php │ │ │ ├── ScannerQueue.php │ │ │ ├── ScanningLog │ │ │ │ ├── Repository.php │ │ │ │ ├── ScanningLogFacade.php │ │ │ │ ├── Template.php │ │ │ │ └── index.php │ │ │ ├── ScanningStagesModule │ │ │ │ ├── ScannerFileStatuses.php │ │ │ │ ├── ScanningStagesStorage.php │ │ │ │ ├── Stages │ │ │ │ │ ├── AutoCure.php │ │ │ │ │ ├── DBTriggerAnalysis.php │ │ │ │ │ ├── FileSystemAnalysis.php │ │ │ │ │ ├── FrontendAnalysis.php │ │ │ │ │ ├── GetApprovedHashes.php │ │ │ │ │ ├── GetCmsHashes.php │ │ │ │ │ ├── GetDeniedHashes.php │ │ │ │ │ ├── GetModulesHashes.php │ │ │ │ │ ├── HeuristicAnalysis.php │ │ │ │ │ ├── OSCronAnalysis.php │ │ │ │ │ ├── OutboundLinks.php │ │ │ │ │ ├── ScanningStageAbstract.php │ │ │ │ │ ├── ScheduleSendHeuristicSuspiciousFiles.php │ │ │ │ │ ├── SignatureAnalysis.php │ │ │ │ │ └── index.php │ │ │ │ └── index.php │ │ │ ├── Services │ │ │ │ └── SendFileToCloudService.php │ │ │ ├── Stages │ │ │ │ ├── CureStage.php │ │ │ │ ├── DTO │ │ │ │ │ ├── SendBackupDTO.php │ │ │ │ │ └── SendFilesDTO.php │ │ │ │ ├── Repositories │ │ │ │ │ ├── CriticalRepository.php │ │ │ │ │ ├── GlobalRepository.php │ │ │ │ │ ├── LinksRepository.php │ │ │ │ │ ├── SuspiciousRepository.php │ │ │ │ │ └── UnknownRepository.php │ │ │ │ ├── SendResultsStage.php │ │ │ │ ├── SignatureAnalysis │ │ │ │ │ ├── Repository.php │ │ │ │ │ ├── SignatureAnalysisFacade.php │ │ │ │ │ └── index.php │ │ │ │ └── index.php │ │ │ ├── Surface.php │ │ │ ├── UnsafePermissionsModule │ │ │ │ ├── UnsafePermissionFunctions.php │ │ │ │ ├── UnsafePermissionsContainer.php │ │ │ │ ├── UnsafePermissionsHandler.php │ │ │ │ └── index.php │ │ │ └── index.php │ │ ├── Settings │ │ │ ├── FilesScanDirExclusion.php │ │ │ └── FrontendScanDomainExclusion.php │ │ ├── SpbcEnqueue.php │ │ ├── State.php │ │ ├── Transaction.php │ │ ├── Upgrader.php │ │ ├── Validate.php │ │ ├── Variables │ │ │ ├── AltSessions.php │ │ │ ├── Cookie.php │ │ │ └── index.php │ │ ├── Views │ │ │ ├── Settings.php │ │ │ └── index.php │ │ ├── VulnerabilityAlarm │ │ │ ├── Assets │ │ │ │ ├── approved_psc.svg │ │ │ │ ├── index.php │ │ │ │ └── vulnerable.svg │ │ │ ├── Dto │ │ │ │ ├── ApiResults.php │ │ │ │ ├── ItemReport.php │ │ │ │ ├── PluginReport.php │ │ │ │ ├── ThemeReport.php │ │ │ │ └── index.php │ │ │ ├── Exceptions │ │ │ │ ├── VulnerabilityAlarmServiceException.php │ │ │ │ └── index.php │ │ │ ├── README.md │ │ │ ├── ResearchApi.php │ │ │ ├── View │ │ │ │ ├── PluginIsSafePSCBadge.html │ │ │ │ ├── PluginListAlarmLayout.html │ │ │ │ ├── ThemesListAlarmLayout.html │ │ │ │ ├── VulnerabilityAlarmTab.html │ │ │ │ ├── VulnerabilityAlarmTabItem.html │ │ │ │ └── index.php │ │ │ ├── VulnerabilityAlarm.php │ │ │ ├── VulnerabilityAlarmService.php │ │ │ ├── VulnerabilityAlarmView.php │ │ │ └── index.php │ │ └── index.php │ ├── Templates │ │ ├── DTO.php │ │ ├── Multiton.php │ │ ├── Singleton.php │ │ └── index.php │ ├── Updater │ │ ├── Updater.php │ │ ├── UpdaterScripts.php │ │ └── index.php │ ├── Variables │ │ ├── Cookie.php │ │ ├── Get.php │ │ ├── Post.php │ │ ├── Request.php │ │ ├── Server.php │ │ ├── ServerVariables.php │ │ └── index.php │ └── index.php ├── autoloader.php ├── index.php └── spbc-php-patch.php ├── package.json ├── psalm.xml ├── readme.txt ├── security-malware-firewall.php ├── spec ├── __tests__ │ ├── critical_upd_tab.test.js │ ├── login.test.js │ ├── login_collect_prevention.test.js │ ├── navbar.test.js │ ├── scan_work.test.js │ ├── settings_set_dir_exclusion.test.js │ ├── settings_tab.test.js │ └── topinfo.test.js ├── form.spec.js └── utils.js ├── templates ├── index.php ├── spbc_send_daily_report.php └── spbc_settings_main.php ├── tests ├── .phpcs.xml ├── CleantalkSP │ └── SpbctWP │ │ ├── Firewall │ │ └── FWTest.php │ │ └── UploadChecker │ │ ├── TestUploadChecker.php │ │ └── files │ │ ├── bad_source │ │ └── plugin_bad.php │ │ └── good_source │ │ └── plugin_good.php ├── Common │ ├── DeactivatorTest.php │ ├── EnqueueTest.php │ ├── Functions │ │ ├── ScannerFileSendTest.php │ │ └── SecurityLogClearTest.php │ ├── Helpers │ │ ├── HelperHTTPTest.php │ │ └── HelperIPTest.php │ ├── Scanner │ │ ├── Heuristic │ │ │ └── HeuristicScan.php │ │ ├── Signatures │ │ │ ├── SignaturesScan.php │ │ │ └── SignaturesUpdateTest.php │ │ └── Storage │ │ │ └── SetFileAsNotPendingQueueTest.php │ ├── SpbcCronTest.php │ └── Variables │ │ └── AltSessionsTest.php ├── Mock │ ├── FirewallStateMock.php │ └── Services │ │ └── SendFileToCloudServiceMock.php ├── Scanner │ ├── TestOSCron.php │ ├── testDBTriggerModel.php │ └── testDBTriggerService.php ├── SpbctWP │ ├── DTO │ │ ├── ExceptionDTOTest.php │ │ └── MScanFilesDTOTest.php │ └── Helpers │ │ ├── HelperTest.php │ │ └── IP │ │ ├── HelperGetIPClientIpTest.php │ │ ├── HelperGetIPCloudflareTest.php │ │ ├── HelperGetIPEzoicTest.php │ │ ├── HelperGetIPForwardedForTest.php │ │ ├── HelperGetIPGTranslateTest.php │ │ ├── HelperGetIPIcoForwardedForTest.php │ │ ├── HelperGetIPIncapTest.php │ │ ├── HelperGetIPOvhTest.php │ │ ├── HelperGetIPRealIpTest.php │ │ ├── HelperGetIPRemoteAddrTest.php │ │ ├── HelperGetIPStackpathTest.php │ │ ├── HelperGetIPSucuriTest.php │ │ ├── HelperGetIPTest.php │ │ └── README.md ├── Standalone │ ├── TestBFP.php │ ├── TestCDNChecker.php │ ├── TestRCServiceTemplateGet.php │ ├── TestSecFWPrivateRecordsHandler.php │ └── TestTC.php ├── StateTest.php ├── Surface │ ├── SurfaceTest.php │ ├── test_deep_directory │ │ ├── directory1 │ │ │ ├── directory11 │ │ │ │ ├── test1.php │ │ │ │ ├── test2.php │ │ │ │ └── test3.php │ │ │ ├── test1.php │ │ │ ├── test2.php │ │ │ └── test3.php │ │ ├── directory2 │ │ │ ├── directory21 │ │ │ │ ├── test1.php │ │ │ │ ├── test2.php │ │ │ │ └── test3.php │ │ │ ├── test1.php │ │ │ ├── test2.php │ │ │ └── test3.php │ │ ├── test1.php │ │ ├── test2.php │ │ └── test3.php │ └── test_just_root_directory │ │ ├── test1.php │ │ ├── test2.php │ │ └── test3.php ├── Tests │ └── CleantalkSP │ │ └── SpbctWP │ │ └── FeatureRestriction │ │ └── FeatureRestrictionServiceTest.php ├── Tools │ └── GlobalAnnotationsListener.php ├── bootstrap.php ├── phpunit.xml └── wp-test-setup.sh └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # This is a sample .env file for Jest configuration. 2 | JEST_VAR__APP_ROOT="" # URL to the WordPress admin page, example: "https://your-domain/wp-admin/options-general.php" 3 | JEST_VAR__WP_LOGIN="" # WordPress admin username 4 | JEST_VAR__WP_PASSWORD="" # WordPress admin password 5 | JEST_VAR__CHROME_EXECUTABLE="" # Path to the Chrome executable, example: "C:\Program Files\Google\Chrome\Application\chrome.exe" 6 | JEST_VAR__CHROME_SET_UA="" # User-Agent string to set for the browser, example: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 7 | JEST_VAR__HEADLESS="" # Set to "1" for headless mode, "0" for normal mode -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: 'google', 7 | ignorePatterns: [ 8 | // 'js/src/lib/*.js', 9 | // 'js/src/react/*.js', 10 | // 'js/src/spbc-admin.js', 11 | // 'js/src/spbc-common.js', 12 | // 'js/src/spbc-cookie.js', 13 | // 'js/src/spbc-dashboard-widget.js', 14 | // 'js/src/spbc-modal.js', 15 | // 'js/src/spbc-scanner-plugin.js', 16 | // 'js/src/spbc-settings.js', 17 | // 'js/src/spbc-settings_tab--backups.js', 18 | // 'js/src/spbc-settings_tab--scanner.js', 19 | // 'js/src/spbc-settings_tab--security_log.js', 20 | // 'js/src/spbc-settings_tab--settings_general.js', 21 | // 'js/src/spbc-settings_tab--summary.js', 22 | ], 23 | overrides: [], 24 | parserOptions: { 25 | ecmaVersion: 'latest', 26 | sourceType: 'module', 27 | }, 28 | rules: { 29 | 'indent': ['error', 4], 30 | 'max-len': ['error', {'code': 120}], 31 | 'prefer-const': 'off', 32 | 'no-invalid-this': 'off', 33 | }, 34 | globals: { 35 | 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /.github/workflows/eslint.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/eslint.yml 2 | 3 | name: ESLint # name of the action (displayed in the github interface) 4 | 5 | on: # event list 6 | push: # on push to each of these branches 7 | branches: 8 | - dev 9 | - fix 10 | - master 11 | pull_request: 12 | branches: 13 | - dev 14 | - master 15 | 16 | env: # environment variables (available in any part of the action) 17 | NODE_VERSION: 16 18 | 19 | jobs: # list of things to do 20 | linting: 21 | name: ESLint # job name (unique id) 22 | runs-on: ubuntu-latest # on which machine to run 23 | steps: # list of steps 24 | - name: Install NodeJS 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ env.NODE_VERSION }} 28 | 29 | - name: Code Checkout 30 | uses: actions/checkout@v2 31 | 32 | - name: Install Dependencies 33 | run: npm i 34 | 35 | - name: Code Linting 36 | run: npm run eslint 37 | 38 | - name: Matrix notify 39 | if: failure() 40 | uses: Glomberg/matrix-messenger-action@master 41 | with: 42 | server: ${{ secrets.MATRIX_SERVER }} 43 | to: ${{ secrets.MATRIX_EXTERNSION_ROOM }} 44 | token: ${{ secrets.MATRIX_USER_TOKEN }} 45 | message: | 46 | Hi, ${{ github.actor }}! Your commit for ${{ github.repository }} 47 | contains 💯 the best solution but it have to be fixed! 48 | Auto-Tests ESLint build failed ⛔! 49 | -------------------------------------------------------------------------------- /.github/workflows/releaseNotice.yml: -------------------------------------------------------------------------------- 1 | name: Notice about releases via Matrix 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Send Matrix message on release 13 | uses: Glomberg/matrix-messenger-action@master 14 | with: 15 | server: ${{ secrets.MATRIX_SERVER }} 16 | to: ${{ secrets.MATRIX_NEWS_ROOM }} 17 | token: ${{ secrets.MATRIX_USER_TOKEN }} 18 | message: | 19 | ${{ github.event.repository.description }} v${{github.event.release.name}} released 20 |
${{github.event.release.html_url}} 21 |
22 |
${{ github.event.release.body }}
23 | -------------------------------------------------------------------------------- /.github/workflows/reviewNotice.yml: -------------------------------------------------------------------------------- 1 | name: Notice about review approved via Matrix 2 | 3 | on: 4 | pull_request_review: 5 | types: [ submitted ] 6 | 7 | jobs: 8 | 9 | build: 10 | if: github.event.review.state == 'approved' && toJSON(github.event.pull_request.requested_reviewers) == '[]' 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Convert date format 14 | id: date 15 | run: echo "::set-output name=date::$(date -d "${{ github.event.pull_request.created_at }}" +"%Y-%m-%d")" 16 | - name: Send Matrix message on review approved 17 | uses: Glomberg/matrix-messenger-action@master 18 | with: 19 | server: ${{ secrets.MATRIX_SERVER }} 20 | to: ${{ secrets.MATRIX_EXTERNSION_ROOM }} 21 | token: ${{ secrets.MATRIX_USER_TOKEN }} 22 | message: | 23 | 💥🎉🎉🎉💥 Pull-request ${{ github.event.pull_request.title }} 24 | submitted by ${{ github.event.pull_request.user.login }} at ${{ steps.date.outputs.date }} 25 | 26 | was approved and is ready to merge ➡️ !!! 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | sync.ffs_db 2 | upload_new_asset* 3 | .7zignore 4 | backups 5 | .gitignore 6 | /package-lock.json 7 | /node_modules/ 8 | /.idea/ 9 | /quarantine/* 10 | /vendor/ 11 | composer.lock 12 | psalm.xml 13 | .editorconfig 14 | .env 15 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/tests/ 16 | /lib/CleantalkSP/Common/Scanner/SignaturesAnalyser/tests/ 17 | /lib/CleantalkSP/Common/Scanner/SignaturesAnalyser/.github/ 18 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/.github/ 19 | /lib/CleantalkSP/Common/Scanner/SignaturesAnalyser/composer.json 20 | /lib/CleantalkSP/Common/Scanner/SignaturesAnalyser/README.md 21 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/composer.json 22 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/README.md 23 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/Vendors/TiktokenPhp/composer.json 24 | /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/Vendors/TiktokenPhp/README.md 25 | /lib/CleantalkSP/Common/FSWatcher/Storage/data/ 26 | /lib/CleantalkSP/Common/FSWatcher/logs/ 27 | /lib/CleantalkSP/Common/Helpers/composer.json 28 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cleantalk/security-malware-firewall", 3 | "description": "Security & Malware scan by CleanTalk to protect your website from online threats and viruses. IP/Country FireWall, Web application FireWall. Detailed stats and logs to have full control.", 4 | "license": "GPL-3.0-or-later", 5 | "authors": [ 6 | { 7 | "name": "Cleantalk Team", 8 | "email": "plugins@cleantalk.org" 9 | } 10 | ], 11 | "require": { 12 | "cleantalk/spbct-heuristic-analyser": "*", 13 | "cleantalk/spbct-signatures-analyser": "*" 14 | }, 15 | "require-dev": { 16 | "vimeo/psalm": "^4.8", 17 | "phpunit/phpunit": "^7.5", 18 | "squizlabs/php_codesniffer": "3.*", 19 | "phpcompatibility/php-compatibility": "@dev", 20 | "yoast/phpunit-polyfills": "^1.0", 21 | "glomberg/wpdb-unsafe-methods": "^1.0" 22 | }, 23 | "scripts": { 24 | "test": [ 25 | "vendor/bin/phpunit --configuration tests/phpunit.xml", 26 | "vendor/bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility", 27 | "vendor/bin/phpcs --standard=tests/.phpcs.xml", 28 | "vendor/bin/psalm --no-cache --config=psalm.xml" 29 | ], 30 | "just_phpunit": [ 31 | "vendor/bin/phpunit --configuration tests/phpunit.xml --debug" 32 | ], 33 | "just_psalm": [ 34 | "vendor/bin/psalm --no-cache --config=psalm.xml --debug" 35 | ] 36 | }, 37 | "config": { 38 | "allow-plugins": { 39 | "cleantalk/spbct-installer": true, 40 | "dealerdirect/phpcodesniffer-composer-installer": true 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /css/images/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | settings[ $data['parent'] ] ? ' disabled="disabled"' : ''; ?> 11 | 12 | 13 | 14 | /> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/hidden.php: -------------------------------------------------------------------------------- 1 | 5 | /> 6 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/number.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |   5 | 6 | 7 | settings[ $data['parent'] ] ? ' disabled="disabled"' : '') 13 | . ' value="' . $data['value'] . '" ' 14 | . ' min="' . $data['min'] . '" ' 15 | . ' max="' . $data['max'] . '" ' 16 | . ($data['required'] ? ' required="required"' : '') 17 | . '>'; 18 | 19 | ?> 20 | 21 | 22 |   23 | 24 | 25 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/radio.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 |
15 | 16 | 17 | settings[ $data['parent'] ] ? ' disabled="disabled"' : '') 27 | . (! $data['children'] ? '' : ' children="' . implode(",", $data['children']) . '"') 28 | . (! $data['children'] ? '' : ' onchange="spbcSettingsDependencies(\'' . implode(",", $data['children']) . '\')"') 29 | . (! $data['children_by_ids'] ? '' : ' onchange="spbcSettingsDependenciesbyId([\'' . implode("','", $data['children_by_ids']) . '\'])"') 30 | . ($data['value'] == $option['val'] ? ' checked' : '') . ' />' 31 | . ''; 32 | echo '     '; 33 | } 34 | 35 | ?> 36 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/select.php: -------------------------------------------------------------------------------- 1 | 2 |   3 | 4 | 5 | '; 19 | 20 | foreach ($data['options'] as $option) { 21 | echo '' 26 | . $option['label'] 27 | . ''; 28 | } 29 | echo ''; 30 | ?> 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/text.php: -------------------------------------------------------------------------------- 1 | 2 |   3 | 4 | 5 | data['moderate'] ? ' disabled="disabled"' : '') 12 | . ($data['class'] ? ' class="' . $data['class'] . '"' : '') 13 | . ($data['required'] ? ' required="required"' : '') 14 | . 'value="' . ($data['value'] ?: $affiliate_short_code) . '" ' 15 | . $readonly 16 | . ($data['disabled'] || ($data['parent'] && ! $data['parent_value']) ? ' disabled="disabled"' : '') 17 | . (! $data['children'] ? '' : ' children="' . implode(",", $data['children']) . '"') 18 | . (! $data['children'] ? '' : ' onchange="spbcSettingsDependencies(\'' . implode(",", $data['children']) . '\')"') 19 | . ' />'; 20 | ?> 21 | 22 | 23 |   24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/textarea.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | settings[ $data['parent'] ] ? ' disabled="disabled"' : '') 19 | . ' class="spbc_setting__textarea"' 20 | . ' >' 21 | . ($data['value'] ?: '') 22 | . ''; 23 | ?> 24 | 25 | 26 |   27 | 28 | 29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /inc/admin-templates/field-templates/time.php: -------------------------------------------------------------------------------- 1 | settings[ $data['parent'] ] ? ' disabled="disabled"' : '') 9 | . ' value="' . $data['value'] . '" ' 10 | . ($data['required'] ? ' required="required"' : '') 11 | . '>'; 12 | -------------------------------------------------------------------------------- /inc/index.php: -------------------------------------------------------------------------------- 1 | spbcGetErrorMsgs().length&&(spbcErrorMsgCount=spbcGetErrorMsgs().length),setTimeout(spbcCheckNewFiles,1e3)}function spbcGetErrorMsgs(){var e=jQuery("#media-upload-error .error"),r=jQuery(".upload-error-message");return e.length?e:r.length?r:[]}function spbcGetLatestBlockedFile(){var e={action:"spbc_check_file_block",timestamp:spbcTimestamp()},r={callback:spbcCheckFileBlockCallback},s=spbcGetErrorMsgs().first();spbcSendAJAXRequest(e,r,s)}function spbcCheckFileBlockCallback(e,r,s,t){var c;e.blocked&&(c=e.pattern.CRITICAL||e.pattern.DANGER||e.pattern.SUSPICIOUS,t.html(e.warning+"
"+e.pattern_title+" "+c))}jQuery(document).ready(function(){setTimeout(spbcCheckNewFiles,1e3)}); 2 | //# sourceMappingURL=spbc-upload.min.js.map 3 | -------------------------------------------------------------------------------- /js/src/react/assets/fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleanTalk/security-malware-firewall/81e87789b21479482f4e3c62e142044c9987a427/js/src/react/assets/fail.png -------------------------------------------------------------------------------- /js/src/react/assets/fonts/icons/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleanTalk/security-malware-firewall/81e87789b21479482f4e3c62e142044c9987a427/js/src/react/assets/fonts/icons/icons.eot -------------------------------------------------------------------------------- /js/src/react/assets/fonts/icons/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleanTalk/security-malware-firewall/81e87789b21479482f4e3c62e142044c9987a427/js/src/react/assets/fonts/icons/icons.woff -------------------------------------------------------------------------------- /js/src/react/assets/fonts/icons/icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleanTalk/security-malware-firewall/81e87789b21479482f4e3c62e142044c9987a427/js/src/react/assets/fonts/icons/icons.woff2 -------------------------------------------------------------------------------- /js/src/react/assets/fonts/icons/index.php: -------------------------------------------------------------------------------- 1 | Loading...; 17 | } 18 | 19 | if (dataRoot.isNetworkAdminDashboard) { 20 | return ; 21 | } 22 | 23 | if (!dataTabs) { 24 | return
Loading...
; 25 | } 26 | 27 | return ( 28 |
29 |
30 | 31 | 32 | 33 |
34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /js/src/react/components/Button/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_manual_link { 2 | background: #fff; 3 | -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15); 4 | box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15); 5 | color: #026E88 !important; 6 | border-radius: 3px; 7 | -webkit-border-radius: 3px; 8 | -webkit-box-sizing: border-box; 9 | -moz-box-sizing: border-box; 10 | box-sizing: border-box; 11 | border-color: #026E88; 12 | display: inline-block; 13 | font-size: 13px; 14 | line-height: 26px; 15 | height: 28px; 16 | padding: 0 10px 1px; 17 | border-width: 1px; 18 | border-style: solid; 19 | -webkit-appearance: none; 20 | white-space: nowrap; 21 | margin: 0; 22 | text-decoration: none; 23 | cursor: pointer; 24 | } 25 | .spbc_page_buttons_links_basic_align { 26 | display: flex; 27 | align-items: center; 28 | justify-content: center; 29 | gap: 5px; 30 | } 31 | .--hide { 32 | display: none; 33 | } 34 | .spbc_preloader_button { 35 | height: 15px; 36 | vertical-align: text-top; 37 | display: none; 38 | margin-left: 5px; 39 | } -------------------------------------------------------------------------------- /js/src/react/components/ErrorBlock/ErrorBlock.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "./styles.css"; 3 | 4 | export default function ErrorBlock({data, supportLink, supportLinkText}) { 5 | const isArray = Array.isArray(data); 6 | 7 | if (isArray) { 8 | return ( 9 |
10 | {data.map((error, index) => ( 11 |

{error}

12 | ))} 13 |

14 | {supportLinkText}:  15 | 16 | {supportLink} 17 | 18 |

19 |
20 | ); 21 | } else { 22 | return ( 23 |
24 |

{data}

25 |
26 | ); 27 | } 28 | } -------------------------------------------------------------------------------- /js/src/react/components/ErrorBlock/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_page_header_info__block_label { 2 | top: 3px; 3 | left: 3px; 4 | position: relative; 5 | background: #f4f4f4; 6 | border: 1px solid #DDD; 7 | border-radius: 3px; 8 | padding: 2px 5px; 9 | font-size: 10px; 10 | color: gray; 11 | } 12 | .spbc_page_header_info__block_body { 13 | border: 1px solid #DDD; 14 | background: #f4f4f4; 15 | padding: 1%; 16 | } 17 | 18 | @media screen and (max-width: 782px) { 19 | .spbc_page_header_info__state_block { 20 | width: 100%; 21 | } 22 | } -------------------------------------------------------------------------------- /js/src/react/components/InfoBlock/InfoBlock.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "./styles.css"; 3 | 4 | export default function InfoBlock({children, blockTitle, width = 100}) { 5 | const isString = typeof children === 'string'; 6 | return ( 7 | <> 8 |
9 | 10 |
11 | {isString 12 | ? 13 | : children 14 | } 15 |
16 |
17 | 18 | ); 19 | } -------------------------------------------------------------------------------- /js/src/react/components/InfoBlock/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_page_header_info__block_label { 2 | top: 3px; 3 | left: 3px; 4 | position: relative; 5 | background: #f4f4f4; 6 | border: 1px solid #DDD; 7 | border-radius: 3px; 8 | padding: 2px 5px; 9 | font-size: 10px; 10 | color: gray; 11 | } 12 | .spbc_page_header_info__block_body { 13 | border: 1px solid #DDD; 14 | background: #f4f4f4; 15 | padding: 1%; 16 | } 17 | 18 | @media screen and (max-width: 782px) { 19 | .spbc_page_header_info__state_block { 20 | width: 100%; 21 | } 22 | } -------------------------------------------------------------------------------- /js/src/react/components/LongDescriptionIco/LongDescriptionIco.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import "./styles.css"; 3 | 4 | export default function LongDescriptionIco ({ description }) { 5 | const [descriptionShow, setDescriptionShow] = useState(false); 6 | const showLongDescription = () => { 7 | setDescriptionShow(true); 8 | } 9 | const hideLongDescription = () => { 10 | setDescriptionShow(false); 11 | } 12 | return ( 13 | <> 14 |
15 | 16 | {descriptionShow && 17 |
18 |
19 | 20 |

{description}

21 |
22 | } 23 |
24 | 25 | 26 | ); 27 | } -------------------------------------------------------------------------------- /js/src/react/components/Section/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_tab_section { 2 | display: none; 3 | } 4 | .spbc_tab_section--active { 5 | display: block; 6 | } 7 | .spbc_spinner_big { 8 | display: block; 9 | margin: 40px auto; 10 | } -------------------------------------------------------------------------------- /js/src/react/components/SectionContent/SectionContent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SectionContentTable from "./SectionContentTable"; 3 | import SectionContentHtml from "./SectionContentHtml"; 4 | 5 | export default function SectionContent({sectionId, sectionData}) { 6 | const dataType = sectionData.data_type; 7 | switch (dataType) { 8 | case 'table': 9 | return (); 10 | case 'html': 11 | default: 12 | return (); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /js/src/react/components/SectionContent/SectionContentHtml.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function SectionContentHtml({sectionId, sectionData}) { 4 | return ( 5 | <> 6 |
7 | 8 | ) 9 | }; 10 | -------------------------------------------------------------------------------- /js/src/react/components/SectionContent/SectionContentTable.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Table from '../Table/Table'; 3 | 4 | export default function SectionContentTable({sectionId, sectionData}) { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | }; 11 | -------------------------------------------------------------------------------- /js/src/react/components/SpbctPageNetworkDashboard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class SpbctPageNetworkDashboard extends React.Component{ 4 | constructor(props) { 5 | super(props); 6 | this.state = {date: new Date()}; 7 | } 8 | 9 | render() { 10 | const data = this.props.data; 11 | return ( 12 |
13 |
14 |
15 | ); 16 | } 17 | } 18 | 19 | export default SpbctPageNetworkDashboard; 20 | -------------------------------------------------------------------------------- /js/src/react/components/Tab/Tab.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "./styles.css"; 3 | 4 | export default function Tab({children, tabId, tabName, isActive}) { 5 | const isActiveClass = isActive ? 'spbc_tab_nav--active' : ''; 6 | return ( 7 | <> 8 |

9 | 10 | {children} 11 |
{tabName}
12 |
13 |

14 | 15 | ); 16 | } -------------------------------------------------------------------------------- /js/src/react/components/Tab/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_tab_nav { 2 | margin: 10px 0 0 .5em; 3 | padding: 5px 10px; 4 | height: 24px; 5 | font-size: 14px; 6 | line-height: 24px; 7 | cursor: pointer; 8 | font-weight: 400; 9 | } 10 | .spbc_tab_nav > a { 11 | display: flex; 12 | text-decoration: none; 13 | color: #555; 14 | } 15 | .spbc_tab_nav--active > a { 16 | color: #026E88; 17 | font-weight: 800; 18 | } 19 | .spbc_tab_nav--active, .spbc_tab_nav:hover { 20 | border-bottom: 2px solid #026E88; 21 | } 22 | .spbc_tab_nav-title { 23 | margin-left: 5px; 24 | width: max-content; 25 | } 26 | .spbc_tab_nav svg { 27 | stroke: #000; 28 | stroke-width: .5; 29 | } 30 | .spbc_tab_nav--active svg { 31 | stroke: #026E88; 32 | stroke-width: 1; 33 | } -------------------------------------------------------------------------------- /js/src/react/components/Table/Table.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TableHeading from "./TableHeading"; 3 | import TableRow from "./TableRow"; 4 | 5 | export default function Table({tableData}) { 6 | const columns = tableData.columns; 7 | const rows = tableData.rows; 8 | return ( 9 | <> 10 |
11 |
12 | 13 | 14 | 15 | 16 | {rows.map((row, idx) => )} 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | ) 25 | }; 26 | -------------------------------------------------------------------------------- /js/src/react/components/Table/TableCell.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function TableCell({cell, headingCell = false}) { 4 | return ( 5 | <> 6 | { headingCell 7 | ? {cell} 8 | : {cell} 9 | } 10 | 11 | ) 12 | }; 13 | -------------------------------------------------------------------------------- /js/src/react/components/Table/TableHeading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TableCell from "./TableCell"; 3 | 4 | export default function TableHeading({columns}) { 5 | const headings = Object.values(columns); 6 | return ( 7 | <> 8 | 9 | {headings.map((heading, idx) => )} 10 | 11 | 12 | ) 13 | }; 14 | -------------------------------------------------------------------------------- /js/src/react/components/Table/TableRow.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TableCell from "./TableCell"; 3 | 4 | export default function TableRow({row}) { 5 | let cells = []; 6 | for ( let item in row ) { 7 | cells.push(row[item]); 8 | } 9 | return ( 10 | <> 11 | 12 | {cells.map((cell, idx) => )} 13 | 14 | 15 | ) 16 | }; 17 | -------------------------------------------------------------------------------- /js/src/react/config/Constants.js: -------------------------------------------------------------------------------- 1 | export const DEFAULT_SECTION = 'firewall'; -------------------------------------------------------------------------------- /js/src/react/hooks/useSync.js: -------------------------------------------------------------------------------- 1 | import { sendAjaxRequest } from "../modules/Http/Ajax"; 2 | 3 | export async function runSync(onProgress) { 4 | const callStack = [ 5 | { 6 | data: { action: 'spbc_react_access_key_check' }, 7 | processing_msg: 'Checking access key...', 8 | }, 9 | { 10 | data: { action: 'spbc_react_secfw_update_init' }, 11 | processing_msg: 'Start updating firewall...', 12 | }, 13 | { 14 | data: { action: 'spbc_react_signatures_update' }, 15 | processing_msg: 'Update signatures...', 16 | }, 17 | { 18 | data: { action: 'spbc_react_settings_exclusions' }, 19 | processing_msg: 'Handling exclusions...', 20 | }, 21 | { 22 | data: { action: 'spbc_react_run_ajusting_env' }, 23 | processing_msg: 'Adjusting environment...', 24 | }, 25 | { 26 | data: { action: 'spbc_react_run_vulnerability_check' }, 27 | processing_msg: 'Running vulnerability check...', 28 | }, 29 | ]; 30 | 31 | let success = false; 32 | let response = null; 33 | let call; 34 | 35 | while (callStack.length) { 36 | call = callStack.shift(); 37 | if (onProgress) onProgress(call.processing_msg); 38 | response = await sendAjaxRequest(call.data, false); 39 | } 40 | success = true; 41 | return success; 42 | } -------------------------------------------------------------------------------- /js/src/react/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './components/App'; 4 | import './styles.css'; 5 | import './assets/spbc-icons.min.css'; 6 | 7 | addEventListener('DOMContentLoaded', () => { 8 | 9 | const spbctRootElement = document.getElementById('spbct-page--react'); 10 | const spbctTabsElement = document.getElementById('spbct-page-tabs--react'); 11 | 12 | if (!spbctRootElement || !spbctRootElement.dataset.data) { 13 | console.error('Element "spbct-page--react" or its data attribute is missing.'); 14 | return; 15 | } 16 | 17 | try { 18 | const dataRoot = JSON.parse(spbctRootElement.dataset.data); 19 | let dataTabs = null; 20 | 21 | if (spbctTabsElement && spbctTabsElement.dataset.data) { 22 | dataTabs = JSON.parse(spbctTabsElement.dataset.data); 23 | } 24 | 25 | const root = ReactDOM.createRoot(spbctRootElement); 26 | root.render(); 27 | } catch (error) { 28 | console.error('Failed to parse data attributes:', error); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /js/src/react/modules/Http/Ajax.js: -------------------------------------------------------------------------------- 1 | export async function sendAjaxRequest(data, isJson = false) { 2 | // Adding security code 3 | data.security = spbcSettings.ajax_nonce; 4 | data.no_cache = Math.random(); 5 | 6 | const response = await fetch( 7 | window.spbcPublic._ajax_url, 8 | { 9 | method: 'POST', 10 | headers: { 11 | 'Content-Type': 'application/x-www-form-urlencoded', 12 | }, 13 | body: new URLSearchParams(data), 14 | } 15 | ); 16 | return isJson ? response.json() : response.text(); 17 | } -------------------------------------------------------------------------------- /js/src/react/pageElements/Header/styles.css: -------------------------------------------------------------------------------- 1 | .spbct_settings_info_header_wrapper { 2 | display: flex; 3 | flex-wrap: wrap; 4 | justify-content: space-between; 5 | margin-bottom: 1%; 6 | } 7 | .spbc_page_header_info_left_column { 8 | width: 66%; 9 | } 10 | .spbc_page_header_info_right_column { 11 | width: 33%; 12 | } 13 | -------------------------------------------------------------------------------- /js/src/react/pageElements/HiddenElements/HiddenElements.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './styles.css'; 3 | 4 | export default function HiddenElements(props) { 5 | return ( 6 | <> 7 |
8 |
10 |
11 |
12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /js/src/react/pageElements/HiddenElements/styles.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleanTalk/security-malware-firewall/81e87789b21479482f4e3c62e142044c9987a427/js/src/react/pageElements/HiddenElements/styles.css -------------------------------------------------------------------------------- /js/src/react/pageElements/Sections/Sections.js: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState} from 'react'; 2 | import Section from "../../components/Section/Section"; 3 | import './styles.css'; 4 | import {TABS} from "../../config/Tabs"; 5 | import {DEFAULT_SECTION} from "../../config/Constants"; 6 | 7 | export default function Sections() { 8 | const [activeSection, setActiveSection] = useState(window.location.hash.substring(1) || 'firewall'); 9 | 10 | useEffect(() => { 11 | const handleHashChange = () => { 12 | setActiveSection(window.location.hash.substring(1) || DEFAULT_SECTION); 13 | }; 14 | 15 | window.addEventListener('hashchange', handleHashChange); 16 | 17 | return () => { 18 | window.removeEventListener('hashchange', handleHashChange); 19 | }; 20 | }, []); 21 | 22 | let sectionsInfo = []; 23 | TABS.map((tab) => { 24 | sectionsInfo.push({ 25 | sectionId: tab.tabId, 26 | isActive: activeSection === tab.tabId, 27 | }); 28 | }); 29 | 30 | return ( 31 | <> 32 |
33 | {sectionsInfo.map((sectionInfo) => { 34 | return
35 | })} 36 |
37 | 38 | ) 39 | ;} 40 | -------------------------------------------------------------------------------- /js/src/react/pageElements/Sections/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_tabs_sections_wrapper { 2 | background-color: #fff; 3 | padding: 15px; 4 | margin-top: 2px; 5 | } -------------------------------------------------------------------------------- /js/src/react/pageElements/ServiceButtons/ServiceButtons.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef } from 'react'; 2 | const { __, _x, _n, _nx } = wp.i18n; 3 | import './styles.css'; 4 | import Button from "../../components/Button/Button"; 5 | import DashboardButtonSvg from "../../components/SvgIcons/DashboardButtonSvg"; 6 | import SupportButtonSvg from "../../components/SvgIcons/SupportButtonSvg"; 7 | import SynchronizeSvg from "../../components/SvgIcons/SynchronizeSvg"; 8 | 9 | export default function ServiceButtons() { 10 | const syncButtonRef = useRef(null); 11 | 12 | useEffect(() => { 13 | if (spbcSettings && spbcSettings.key_changed && syncButtonRef.current) { 14 | syncButtonRef.current.click(); 15 | } 16 | }, []); 17 | 18 | return ( 19 | <> 20 |
21 | 28 | 35 | 41 |
42 | 43 | ); 44 | } -------------------------------------------------------------------------------- /js/src/react/pageElements/ServiceButtons/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_page_buttons_wrapper { 2 | display: flex; 3 | margin-bottom: 5px; 4 | gap: 7px; 5 | } -------------------------------------------------------------------------------- /js/src/react/pageElements/Tabs/Tabs.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | const { __, _x, _n, _nx } = wp.i18n; 3 | import './styles.css'; 4 | import Tab from "../../components/Tab/Tab"; 5 | import {TABS} from "../../config/Tabs"; 6 | import {DEFAULT_SECTION} from "../../config/Constants"; 7 | 8 | export default function Tabs() { 9 | const [activeTab, setActiveTab] = useState(window.location.hash.substring(1) || 'firewall'); 10 | 11 | useEffect(() => { 12 | const handleHashChange = () => { 13 | setActiveTab(window.location.hash.substring(1) || DEFAULT_SECTION); 14 | }; 15 | 16 | window.addEventListener('hashchange', handleHashChange); 17 | 18 | return () => { 19 | window.removeEventListener('hashchange', handleHashChange); 20 | }; 21 | }, []); 22 | 23 | let tabsInfo = []; 24 | TABS.map((tab) => { 25 | tabsInfo.push({ 26 | tabId: tab.tabId, 27 | tabName: tab.tabName, 28 | isActive: activeTab === tab.tabId, 29 | svgIcon: tab.svgIcon, 30 | }); 31 | }); 32 | 33 | 34 | return ( 35 | <> 36 |
37 | {tabsInfo.map((tabInfo) => { 38 | return {tabInfo.svgIcon} 39 | })} 40 |
41 | 42 | ); 43 | } -------------------------------------------------------------------------------- /js/src/react/pageElements/Tabs/styles.css: -------------------------------------------------------------------------------- 1 | .spbc_tabs_nav_wrapper { 2 | display: flex; 3 | background-color: #fff; 4 | overflow-x: auto; 5 | } -------------------------------------------------------------------------------- /js/src/react/styles.css: -------------------------------------------------------------------------------- 1 | #spbct_root { 2 | margin-right: 20px; 3 | } -------------------------------------------------------------------------------- /js/src/spbc-settings_tab--summary.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function() { 2 | console.log('TAB - SUMMARY'); 3 | }); 4 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/DB/index.php: -------------------------------------------------------------------------------- 1 | args = isset($params['args']) ? $params['args'] : false; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/HTTP/Response.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 22 | $this->processed = $raw; 23 | $this->info = $info; 24 | $this->error = ! empty($raw['error']) 25 | ? $raw 26 | : null; 27 | if (isset($this->info['http_code'])) { 28 | $this->response_code = (int)$this->info['http_code']; 29 | } 30 | } 31 | 32 | /** 33 | * @return mixed 34 | */ 35 | public function getError() 36 | { 37 | return $this->error; 38 | } 39 | 40 | /** 41 | * @return mixed 42 | */ 43 | public function getResponseCode() 44 | { 45 | return $this->response_code; 46 | } 47 | 48 | /** 49 | * @return mixed 50 | * @psalm-suppress PossiblyUnusedMethod 51 | */ 52 | public function getContentRaw() 53 | { 54 | return $this->raw; 55 | } 56 | 57 | /** 58 | * @return mixed 59 | */ 60 | public function getContentProcessed() 61 | { 62 | return $this->processed; 63 | } 64 | 65 | /** 66 | * @param mixed $processed 67 | */ 68 | public function setProcessed($processed) 69 | { 70 | $this->processed = $processed; 71 | } 72 | 73 | /** 74 | * @return mixed 75 | * @psalm-suppress PossiblyUnusedMethod 76 | */ 77 | public function getInfo() 78 | { 79 | return $this->info; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/HTTP/index.php: -------------------------------------------------------------------------------- 1 | tokens = $tokens; 25 | } 26 | 27 | 28 | public function analise() 29 | { 30 | if ( count($this->tokens->html) ) { 31 | foreach ( $this->tokens->html as $html ) { 32 | if ( strlen($html[1]) > $this->max_token_size_to_analise ) { 33 | continue; 34 | //throw new HeuristicScannerException('Analise limit exceeded'); 35 | } 36 | if ( preg_match('##', $html[1]) ) { 37 | $this->result = $html[0]; 38 | // @ToDo have to process not only one first founded suspicious html 39 | // @ToDo $this->result must be an array of founded suspicious html 40 | // @ToDo need to remove this return statement here 41 | return; 42 | } 43 | } 44 | } 45 | } 46 | 47 | private function simplifyHTMLToken($token) 48 | { 49 | $token[1] = preg_replace('##', '', $token[1]); // Strip comments 50 | $token[1] = preg_replace('#[\n\t\r]#', '', $token[1]); // Strip empty new lines and tabs 51 | 52 | return $token; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/Modules/index.php: -------------------------------------------------------------------------------- 1 | path = $path; 31 | $this->content = $content; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/Structures/Verdict.php: -------------------------------------------------------------------------------- 1 | path = $path; 34 | $this->full_hash = $full_hash; 35 | if ( $weak_spots ) { 36 | $this->weak_spots = $weak_spots; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Common/Scanner/SignaturesAnalyser/Structures/Verdict.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 11 | ?> 12 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Fpdf/font/courierb.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 11 | ?> 12 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Fpdf/font/courierbi.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 11 | ?> 12 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Fpdf/font/courieri.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 11 | ?> 12 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Fpdf/font/index.php: -------------------------------------------------------------------------------- 1 | login_slug = $login_slug; 43 | $this->redirect_slug = $redirect_slug; 44 | 45 | $this->request = parse_url(Server::get('REQUEST_URI', null, 'url')) ?: array(); 46 | $this->request['path'] = isset($this->request['path']) ? $this->request['path'] : ''; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Security/index.php: -------------------------------------------------------------------------------- 1 | id; 23 | } 24 | 25 | public function show() 26 | { 27 | if ( $this->needToShow() ) { 28 | $this->display(); 29 | } 30 | } 31 | 32 | abstract protected function needToShow(); 33 | 34 | abstract protected function display(); 35 | 36 | /** 37 | * Has the date of the last show expired? 38 | * 39 | * @return bool 40 | */ 41 | protected function isDismissed() 42 | { 43 | $dismissed_date = get_option($this->banner_id); 44 | 45 | if ( $dismissed_date !== false && Helper::dateValidate($dismissed_date) ) { 46 | $current_date = date_create(); 47 | $dismissed_date = date_create($dismissed_date); 48 | 49 | $diff = date_diff($current_date, $dismissed_date); 50 | 51 | if ( $diff->days <= static::HIDING_TIME ) { 52 | return true; 53 | } 54 | } 55 | 56 | return false; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/AdminBannersModule/AdminBanners/index.php: -------------------------------------------------------------------------------- 1 | 0, 19 | 'deny' => 0, 20 | ); 21 | 22 | protected function initCounters() 23 | { 24 | $this->current_interval_name__insert = Helper::getTimeIntervalStart(static::$default_time_interval__insert); 25 | $this->current_interval_name__get = Helper::getTimeIntervalStart(static::$default_time_interval__get); 26 | $this->data = get_option($this->option_name, array()); 27 | } 28 | 29 | protected function setCounters() 30 | { 31 | update_option($this->option_name, $this->data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Counters/SecurityCounter.php: -------------------------------------------------------------------------------- 1 | 0, 19 | 'deny' => 0, 20 | ); 21 | 22 | protected function initCounters() 23 | { 24 | $this->current_interval_name__insert = Helper::getTimeIntervalStart(static::$default_time_interval__insert); 25 | $this->current_interval_name__get = Helper::getTimeIntervalStart(static::$default_time_interval__get); 26 | $this->data = get_option($this->option_name, array()); 27 | } 28 | 29 | protected function setCounters() 30 | { 31 | update_option($this->option_name, $this->data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Counters/index.php: -------------------------------------------------------------------------------- 1 | obligatory_properties = array('auth_key', 'method_name', 'timestamp', 'data', 'rows'); 38 | parent::__construct($data); 39 | if ( empty($this->auth_key) ) { 40 | throw new \Exception(__CLASS__ . ': param "auth_key" is empty.'); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/DTO/index.php: -------------------------------------------------------------------------------- 1 | dir_to_watch, \RecursiveDirectoryIterator::SKIP_DOTS), 32 | \RecursiveIteratorIterator::SELF_FIRST, 33 | \RecursiveIteratorIterator::CATCH_GET_CHILD 34 | ); 35 | $storage = Controller::$storage; 36 | $storage::writeJournal($iterator, self::$params->extensions_to_watch, self::$params->exclude_dirs); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/FSWatcher/Scan/index.php: -------------------------------------------------------------------------------- 1 | name = $name; 29 | $this->on_moderate_fail = isset($on_moderate_fail) ? (bool) $on_moderate_fail : false; 30 | $this->on_key_fail = isset($on_key_fail) ? (bool) $on_key_fail : false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/FeatureRestriction/FeatureRestrictionState.php: -------------------------------------------------------------------------------- 1 | is_active = isset($is_active) ? (bool) $is_active : true; 32 | $this->info_html = isset($info_html) ? $info_html : ''; 33 | } 34 | 35 | /** 36 | * Sanitizes and escapes HTML output. 37 | * 38 | * This method uses the escKsesPreset() function from the Escape class 39 | * to sanitize and escape the given HTML output. 40 | * 41 | * @return string The sanitized and escaped HTML output. 42 | * @psalm-suppress PossiblyUnusedMethod 43 | */ 44 | public function sanitizedReasonOutput() 45 | { 46 | return \CleantalkSP\SpbctWP\Escape::escKsesPreset( 47 | $this->info_html, 48 | 'spbc_settings__feature_restrictions', 49 | array(), 50 | array('display') 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/FeatureRestriction/index.php: -------------------------------------------------------------------------------- 1 | queue = array( 17 | 'started' => time(), 18 | 'finished' => '', 19 | 'stages' => array(), 20 | ); 21 | return delete_option($this->option_name); 22 | } 23 | /** 24 | * Get the queue from DB 25 | * 26 | * @return mixed 27 | */ 28 | public function getQueue() 29 | { 30 | return get_option($this->option_name); 31 | } 32 | /** 33 | * Save the current state of queue in DB or whatever 34 | * 35 | * @param array|null $queue 36 | * 37 | */ 38 | public function saveQueue($queue = null) 39 | { 40 | update_option($this->option_name, $queue ?: $this->queue, false); 41 | } 42 | /** 43 | * Refreshes the $this->queue from the DB 44 | * 45 | * @param array|null $queue 46 | * 47 | */ 48 | public function refreshQueue($queue = null) 49 | { 50 | $this->queue = $this->getQueue(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/RestController.php: -------------------------------------------------------------------------------- 1 | namespace = 'cleantalk-security/v1'; 15 | } 16 | 17 | public function register_routes() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 18 | { 19 | 20 | register_rest_route($this->namespace, '/alt_sessions', array( 21 | array( 22 | 'methods' => 'POST', 23 | 'callback' => array(\CleantalkSP\SpbctWP\Variables\AltSessions::class, 'setFromRemote'), 24 | 'args' => array( 25 | 'cookies' => array( 26 | 'type' => 'array', 27 | 'required' => true, 28 | ), 29 | ), 30 | 'permission_callback' => '__return_true', 31 | ), 32 | array( 33 | 'methods' => 'GET', 34 | 'callback' => array(\CleantalkSP\SpbctWP\Variables\AltSessions::class, 'getFromRemote'), 35 | 'args' => array( 36 | 'name' => array( 37 | 'type' => 'string', 38 | 'required' => true, 39 | ), 40 | ), 41 | 'permission_callback' => '__return_true', 42 | ) 43 | )); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/CureLog/index.php: -------------------------------------------------------------------------------- 1 | verdict = self::hasRM($command); 19 | //add more checks here 20 | return $this; 21 | } 22 | 23 | /** 24 | * Checks if a command is dangerous. 25 | * 26 | * @param string $command The command to check. 27 | * @return bool True if the command is dangerous, false otherwise. 28 | */ 29 | private static function hasRM($command) 30 | { 31 | try { 32 | //implement command check here 33 | if (strpos($command, 'rm') !== false) { 34 | return true; 35 | } 36 | } catch (\Exception $e) { 37 | return false; 38 | } 39 | return false; 40 | } 41 | 42 | /** 43 | * @return bool 44 | */ 45 | public function getVerdict() 46 | { 47 | return $this->verdict; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/OSCron/Shell/OSCronGetEnvCron.php: -------------------------------------------------------------------------------- 1 | get_results( 20 | 'SELECT real_full_hash FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE status="APPROVED_BY_USER"', 21 | ARRAY_A 22 | ); 23 | } 24 | 25 | /** 26 | * Get queued to send to Cleantalk Cloud files 27 | */ 28 | public static function getPendingQueueFiles() 29 | { 30 | global $wpdb; 31 | 32 | return $wpdb->get_results( 33 | 'SELECT fast_hash, status FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE pscan_pending_queue = 1', 34 | ARRAY_A 35 | ); 36 | } 37 | 38 | /** 39 | * Get file info by fast_hash 40 | */ 41 | public static function getFileInfoByFastHash($fast_hash) 42 | { 43 | global $wpdb; 44 | 45 | $sql = $wpdb->prepare( 46 | 'SELECT fast_hash, path, source_type, source, source_status, version, mtime, weak_spots, 47 | full_hash, real_full_hash, status, checked_signatures, checked_heuristic 48 | FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE fast_hash = %s LIMIT 1', 49 | $fast_hash 50 | ); 51 | 52 | $sql_result = $wpdb->get_results($sql, ARRAY_A); 53 | 54 | return $sql_result[0]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScannerInteractivity/RefreshDataDTO.php: -------------------------------------------------------------------------------- 1 | self::$scanner_stage, 29 | 'refresh_data' => self::$refresh_data instanceof RefreshDataDTO 30 | ? self::getDataArray(self::$refresh_data) 31 | : array(), 32 | 'update_text' => __('Updated!', 'security_malware_firewall') 33 | ); 34 | } 35 | 36 | public static function getDataArray(RefreshDataDTO $refresh_data) 37 | { 38 | return array( 39 | 'do_refresh' => $refresh_data->do_refresh, 40 | 'control_tab' => $refresh_data->control_tab, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningLog/Repository.php: -------------------------------------------------------------------------------- 1 | prepare( 12 | 'INSERT INTO ' 13 | . SPBC_TBL_SCAN_RESULTS_LOG 14 | . ' (timestamp, content) VALUES' 15 | . ' (%d, %s);', 16 | array(time(), spbc_wp_kses($content, '')) 17 | )->execute(); 18 | } 19 | 20 | public static function getAll($limit = 0, $offset = 0) 21 | { 22 | global $wpdb; 23 | 24 | $sql = 'SELECT timestamp, content FROM ' . SPBC_TBL_SCAN_RESULTS_LOG . ' ORDER BY timestamp DESC LIMIT %d OFFSET %d;'; 25 | 26 | return DB::getInstance()->fetchAll( 27 | $wpdb->prepare($sql, $limit, $offset) 28 | ); 29 | } 30 | 31 | public static function clear() 32 | { 33 | return DB::getInstance()->execute( 34 | 'TRUNCATE TABLE ' 35 | . SPBC_TBL_SCAN_RESULTS_LOG 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningLog/ScanningLogFacade.php: -------------------------------------------------------------------------------- 1 | '; 17 | $template .= '
'; 18 | 19 | $template .= self::generateRows($data); 20 | 21 | $template .= '
'; 22 | $template .= ''; 23 | $template .= '
'; 24 | $template .= ''; 27 | $template .= '
'; 28 | 29 | return $template; 30 | } 31 | 32 | public static function generateRows($data) 33 | { 34 | global $spbc; 35 | 36 | $template = ''; 37 | $prev_item_content = ''; 38 | 39 | foreach ($data as $item) { 40 | if ($prev_item_content === $item['content']) { 41 | continue; 42 | } 43 | 44 | $template .= '

' 45 | . date("M d Y H:i:s", $item['timestamp'] + $spbc->data['site_utc_offset_in_seconds']) 46 | . ' ' 47 | . $item['content'] 48 | . '

'; 49 | 50 | $prev_item_content = $item['content']; 51 | } 52 | 53 | return $template; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningLog/index.php: -------------------------------------------------------------------------------- 1 | unknown = 0; 29 | $this->ok = 0; 30 | $this->approved_by_user = 0; 31 | $this->approved_by_ct = 0; 32 | $this->modified = 0; 33 | $this->infected = 0; 34 | $this->quarantined = 0; 35 | $this->statuses = array( 36 | 'unknown' => $this->unknown, 37 | 'ok' => $this->ok, 38 | 'approved_by_user' => $this->approved_by_user, 39 | 'approved_by_ct' => $this->approved_by_ct, 40 | 'modified' => $this->modified, 41 | 'infected' => $this->infected, 42 | 'quarantined' => $this->quarantined, 43 | 'error' => $this->error, 44 | ); 45 | } 46 | 47 | public function addStatus($status) 48 | { 49 | $status = strtolower($status); 50 | 51 | $this->statuses[$status]++; 52 | } 53 | 54 | public function getStatuses() 55 | { 56 | return $this->statuses; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/ScanningStagesStorage.php: -------------------------------------------------------------------------------- 1 | converter = $db_converter; 18 | } 19 | 20 | public function getStage($class) 21 | { 22 | return $this->converter->getObject($class); 23 | } 24 | 25 | public function saveToDb() 26 | { 27 | $this->converter->saveToDb(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/AutoCure.php: -------------------------------------------------------------------------------- 1 | count_files 23 | . '; ' 24 | . __('Cured ', 'security-malware-firewall') 25 | . $this->count_cured 26 | . '.'; 27 | } 28 | 29 | public function getName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getData() 35 | { 36 | return array( 37 | 'count_files' => $this->count_files, 38 | 'count_cured' => $this->count_cured 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/DBTriggerAnalysis.php: -------------------------------------------------------------------------------- 1 | scanned_count_files 22 | . '.'; 23 | } 24 | 25 | public function getName() 26 | { 27 | return __CLASS__; 28 | } 29 | 30 | public function getData() 31 | { 32 | return array(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/FileSystemAnalysis.php: -------------------------------------------------------------------------------- 1 | scanned_count_files 22 | . '.'; 23 | } 24 | 25 | public function getName() 26 | { 27 | return __CLASS__; 28 | } 29 | 30 | public function getData() 31 | { 32 | return array( 33 | 'scanned_count_files' => $this->scanned_count_files 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/FrontendAnalysis.php: -------------------------------------------------------------------------------- 1 | total_site_pages 25 | . '; ' 26 | . __('Total pages scanned ', 'security-malware-firewall') 27 | . $this->total 28 | . '.'; 29 | } 30 | 31 | public function getName() 32 | { 33 | return __CLASS__; 34 | } 35 | 36 | public function getData() 37 | { 38 | return array( 39 | 'total' => $this->total, 40 | 'total_site_pages' => $this->total_site_pages, 41 | 'success' => $this->success, 42 | 'processed' => $this->processed 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/GetApprovedHashes.php: -------------------------------------------------------------------------------- 1 | count_approved_hashes 23 | . '; ' 24 | . __('Approved hashes in db ', 'security-malware-firewall') 25 | . $this->count_approved_hashes_in_db 26 | . '.'; 27 | } 28 | 29 | public function getName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getData() 35 | { 36 | return array( 37 | 'count_approved_hashes' => $this->count_approved_hashes, 38 | 'count_approved_hashes_in_db' => $this->count_approved_hashes_in_db 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/GetCmsHashes.php: -------------------------------------------------------------------------------- 1 | expected_count_hashes 23 | . '; ' 24 | . __('Added hashes ', 'security-malware-firewall') 25 | . $this->added_count_hashes 26 | . '.'; 27 | } 28 | 29 | public function getName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getData() 35 | { 36 | return array( 37 | 'expected_count_hashes' => $this->expected_count_hashes, 38 | 'added_count_hashes' => $this->added_count_hashes 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/GetDeniedHashes.php: -------------------------------------------------------------------------------- 1 | count_denied_hashes 23 | . '; ' 24 | . __('Denied hashes in db ', 'security-malware-firewall') 25 | . $this->count_denied_hashes_in_db 26 | . '.'; 27 | } 28 | 29 | public function getName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getData() 35 | { 36 | return array( 37 | 'count_denied_hashes' => $this->count_denied_hashes, 38 | 'count_denied_hashes_in_db' => $this->count_denied_hashes_in_db 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/GetModulesHashes.php: -------------------------------------------------------------------------------- 1 | count_plugins 25 | . '; ' 26 | . __('Themes ', 'security-malware-firewall') 27 | . $this->count_themes 28 | . '; ' 29 | . __('Plugins without hashes ', 'security-malware-firewall') 30 | . $this->count_plugins_without_hashes 31 | . '; ' 32 | . __('Themes without hashes ', 'security-malware-firewall') 33 | . $this->count_themes_without_hashes 34 | . '.'; 35 | } 36 | 37 | public function getName() 38 | { 39 | return __CLASS__; 40 | } 41 | 42 | public function getData() 43 | { 44 | return array( 45 | 'count_plugins' => $this->count_plugins, 46 | 'count_themes' => $this->count_themes, 47 | 'count_plugins_without_hashes' => $this->count_plugins_without_hashes, 48 | 'count_themes_without_hashes' => $this->count_themes_without_hashes 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/OSCronAnalysis.php: -------------------------------------------------------------------------------- 1 | scanned_count_files 22 | . '.'; 23 | } 24 | 25 | public function getName() 26 | { 27 | return __CLASS__; 28 | } 29 | 30 | public function getData() 31 | { 32 | return array( 33 | // 'scanned_count_files' => $this->scanned_count_files 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/OutboundLinks.php: -------------------------------------------------------------------------------- 1 | total 23 | . '; ' 24 | . __('Founded outbound links ', 'security-malware-firewall') 25 | . $this->founded 26 | . '.'; 27 | } 28 | 29 | public function getName() 30 | { 31 | return __CLASS__; 32 | } 33 | 34 | public function getData() 35 | { 36 | return array( 37 | 'total' => $this->total, 38 | 'founded' => $this->founded 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/ScanningStageAbstract.php: -------------------------------------------------------------------------------- 1 | $value) { 12 | $this->$param = $value; 13 | } 14 | } 15 | } 16 | 17 | /** @psalm-suppress PossiblyUnusedMethod */ 18 | public function set($param, $value) 19 | { 20 | $this->$param = $value; 21 | } 22 | 23 | /** @psalm-suppress PossiblyUnusedMethod */ 24 | public function increase($param, $value) 25 | { 26 | $this->$param += $value; 27 | } 28 | 29 | /** @psalm-suppress PossiblyUnusedMethod */ 30 | public function decrease($param, $value) 31 | { 32 | $this->$param -= $value; 33 | } 34 | 35 | /** @psalm-suppress PossiblyUnusedMethod */ 36 | public function merge($param, $array) 37 | { 38 | foreach ($array as $key => $value) { 39 | $this_param = $this->$param; 40 | if (isset($this_param[$key])) { 41 | $this_param[$key] += $value; 42 | } else { 43 | $this_param[$key] = $value; 44 | } 45 | $this->$param = $this_param; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/ScheduleSendHeuristicSuspiciousFiles.php: -------------------------------------------------------------------------------- 1 | count_scheduled 22 | . '.'; 23 | } 24 | 25 | public function getName() 26 | { 27 | return __CLASS__; 28 | } 29 | 30 | public function getData() 31 | { 32 | return array( 33 | 'count_scheduled' => $this->count_scheduled 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/ScanningStagesModule/Stages/index.php: -------------------------------------------------------------------------------- 1 | spbc->settings['scanner__signature_analysis']) { 23 | return true; 24 | } 25 | 26 | return false; 27 | } 28 | 29 | /** 30 | * Getting data from the database 31 | * 32 | * @return array|object|null 33 | */ 34 | protected function catchResultData() 35 | { 36 | return $this->db->fetchAll( 37 | 'SELECT full_hash, mtime, size, source_type, source, source_status, path, status, severity' 38 | . ' FROM ' . SPBC_TBL_SCAN_FILES 39 | . ' WHERE' 40 | . ' severity = "CRITICAL" AND' 41 | . ' status <> "QUARANTINED" AND' 42 | . ' status <> "APPROVED_BY_USER" AND' 43 | . ' status <> "APPROVED_BY_CLOUD" AND' 44 | . ' status <> "APPROVED_BY_CT"' 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/Stages/Repositories/SuspiciousRepository.php: -------------------------------------------------------------------------------- 1 | spbc->settings['scanner__heuristic_analysis']) { 23 | return true; 24 | } 25 | 26 | return false; 27 | } 28 | 29 | /** 30 | * Getting data from the database 31 | * 32 | * @return array|object|null 33 | */ 34 | protected function catchResultData() 35 | { 36 | return $this->db->fetchAll( 37 | 'SELECT full_hash, mtime, size, source_type, source, source_status, path, status, severity' 38 | . ' FROM ' . SPBC_TBL_SCAN_FILES 39 | . ' WHERE' 40 | . ' severity = "SUSPICIOUS" AND' 41 | . ' status <> "QUARANTINED" AND' 42 | . ' status <> "APPROVED_BY_USER" AND' 43 | . ' status <> "APPROVED_BY_CLOUD" AND' 44 | . ' status <> "APPROVED_BY_CT"' 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/Stages/Repositories/UnknownRepository.php: -------------------------------------------------------------------------------- 1 | spbc->settings['scanner__list_unknown']) { 23 | return true; 24 | } 25 | 26 | return false; 27 | } 28 | 29 | /** 30 | * Getting data from the database 31 | * 32 | * @return array|object|null 33 | */ 34 | protected function catchResultData() 35 | { 36 | return $this->db->fetchAll( 37 | 'SELECT full_hash, mtime, size, path, source, severity, detected_at' 38 | . ' FROM ' . SPBC_TBL_SCAN_FILES 39 | . ' WHERE source IS NULL AND' 40 | . ' status <> "APPROVED_BY_USER" AND' 41 | . ' status <> "APPROVED_BY_CT" AND' 42 | . ' status <> "APPROVED_BY_CLOUD" AND' 43 | . ' detected_at >= ' . (time() - $this->spbc->settings['scanner__list_unknown__older_than'] * 86400) . ' AND' 44 | . ' path NOT LIKE "%wp-content%themes%" AND' 45 | . ' path NOT LIKE "%wp-content%plugins%" AND' 46 | . ' path NOT LIKE "%wp-content%cache%" AND' 47 | . ' (severity NOT IN ("CRITICAL","SUSPICIOUS") OR severity IS NULL)' 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/Stages/SignatureAnalysis/SignatureAnalysisFacade.php: -------------------------------------------------------------------------------- 1 | array( 16 | '/.htaccess' => '644', 17 | '/index.php' => '644', 18 | '/wp-config.php' => '644' 19 | ), 20 | 'dirs' => array( 21 | '/wp-admin' => '755', 22 | '/wp-includes' => '755', 23 | '/wp-content' => '755', 24 | '/wp-content/themes' => '755', 25 | '/wp-content/plugins' => '755', 26 | '/wp-content/uploads' => '755', 27 | ) 28 | ); 29 | 30 | /** 31 | * Get files 32 | */ 33 | public static function getFiles() 34 | { 35 | return self::$list['files']; 36 | } 37 | 38 | /** 39 | * Get files 40 | */ 41 | public static function getDirs() 42 | { 43 | return self::$list['dirs']; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/UnsafePermissionsModule/UnsafePermissionsHandler.php: -------------------------------------------------------------------------------- 1 | handle(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/Scanner/UnsafePermissionsModule/index.php: -------------------------------------------------------------------------------- 1 | '', // Dummy placeholder to prevent php notices 17 | 'app_names' => $modules_names, 18 | 'list_params' => 'id,CVE,date,slug,app_name,app_description,app_status,app_type,rs_app_version_min,rs_app_version_max,psc,research_url' 19 | ); 20 | 21 | return static::sendRequest($request); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/PluginIsSafePSCBadge.html: -------------------------------------------------------------------------------- 1 |
2 | Approved 3 |
4 |
5 |
6 | {{DESCRIPTION}} 7 |
8 | {{MORE_DETAILS_LINK}} 9 |
10 |
11 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/PluginListAlarmLayout.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |
10 |

11 | 12 | {{VULNERABILITY_TEXT}} {{MORE_DETAILS_LINK}} 13 |

14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/ThemesListAlarmLayout.html: -------------------------------------------------------------------------------- 1 |
2 | {{VULNERABILITY_TEXT}} 3 |

{{MORE_DETAILS_LINK}}

4 |
5 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/VulnerabilityAlarmTab.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |

{{CURRENT_STATE_TEXT}}

7 |
8 |
9 |
10 |

{{VULNERABILITIES_TITLE}}

11 |
{{VULNERABILITIES_SUBTITLE}}
12 |
13 |
    14 | {{VULNERABLE_ITEMS}} 15 |
16 |
17 |

{{PSC_TITLE}}

18 |
{{PSC_SUBTITLE}}
19 |
20 |
    21 | {{PSC_ITEMS}} 22 |
23 |
24 |
25 |
26 | {{DESCRIPTION_FEATURE}} 27 | {{DESCRIPTION_LEGEND}} 28 |
    29 |
  • {{LEGEND_KNOWN_V}}
  • 30 |
  • {{LEGEND_PSC}}
  • 31 |
32 |

{{LEGEND_DB_LINK}}

33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/VulnerabilityAlarmTabItem.html: -------------------------------------------------------------------------------- 1 |
  • 2 | {{VULNERABLE_NAME}}{{VULNERABLE_VERSIONS}} 3 | {{VULNERABLE_ALERT}} 4 |
  • 5 | -------------------------------------------------------------------------------- /lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/View/index.php: -------------------------------------------------------------------------------- 1 | isObligatoryParamsPresented($params) ) { 22 | throw new \Exception('No go!'); 23 | } 24 | 25 | foreach ( $params as $param_name => $param ) { 26 | if ( property_exists(static::class, $param_name) ) { 27 | $type = gettype($this->$param_name); 28 | $this->$param_name = $param; 29 | settype($this->$param_name, $type); 30 | } 31 | } 32 | } 33 | 34 | /** 35 | * @param $params 36 | * 37 | * @return bool 38 | * @since 1.1.0 39 | * 40 | */ 41 | private function isObligatoryParamsPresented($params) 42 | { 43 | return empty($this->obligatory_properties) || 44 | count(array_intersect($this->obligatory_properties, array_keys($params))) === count( 45 | $this->obligatory_properties 46 | ); 47 | } 48 | 49 | /** 50 | * Get array of all DTO properties as key-value, except obligatory_properties. 51 | * @return array 52 | */ 53 | public function getArray() 54 | { 55 | $array = array(); 56 | foreach (get_object_vars($this) as $key => $value) { 57 | $array[$key] = $value; 58 | } 59 | unset($array['obligatory_properties']); 60 | return $array; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Templates/Multiton.php: -------------------------------------------------------------------------------- 1 | init(...$params); 25 | } 26 | 27 | return static::$instances[$instance]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Templates/Singleton.php: -------------------------------------------------------------------------------- 1 | init(...$params); 34 | } 35 | 36 | return static::$instance[static::class]; 37 | } 38 | 39 | /** 40 | * Alternative constructor 41 | * 42 | * @param array $_params Parameters to initialize the instance 43 | */ 44 | protected function init(...$_params) 45 | { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/CleantalkSP/Templates/index.php: -------------------------------------------------------------------------------- 1 | } 8 | * @private 9 | */ 10 | async function __criticalUpdatesElementsExist() { 11 | await jestState.page.goto( 12 | jestState.envData.root + '/wp-admin/options-general.php?page=spbc&spbc_tab=critical_updates', 13 | {waitUntil: 'load'}, 14 | ); 15 | await jestState.page.waitForSelector('[id=spbc_tab-critical_updates]'); 16 | const criticalUpdatesElementsClasses = [ 17 | '.spbc_tab-critical_updates', 18 | '.spbc_critical_updates-legend', 19 | ]; 20 | for (let i = 0; i < criticalUpdatesElementsClasses.length; i++) { 21 | await jestState.page.$eval(criticalUpdatesElementsClasses[i], (el) => el.innerText); 22 | } 23 | } 24 | 25 | /** 26 | * Run Critical Updates tests. 27 | * This test is a wrapper for group of tests. 28 | * @param {boolean} doLogin 29 | * @return {void} 30 | */ 31 | export function groupCriticalUpdatesInfo(doLogin = true) { 32 | if (doLogin) { 33 | test('LOGIN', async () => { 34 | await __runLogin(); 35 | }, jestState.globals.globalTimeout); 36 | } 37 | test('CRITICAL UPDATES ELEMENTS EXISTS', async () => { 38 | await __criticalUpdatesElementsExist(); 39 | }, jestState.globals.globalTimeout); 40 | // more test there 41 | } 42 | -------------------------------------------------------------------------------- /spec/__tests__/login.test.js: -------------------------------------------------------------------------------- 1 | // Version: 1.0.0 2 | import {jestState} from '../form.spec'; 3 | /** 4 | * Run login process. 5 | * Standalone test to perform login before further actions. 6 | * @return {Promise} 7 | * @private 8 | */ 9 | export async function __runLogin() { 10 | await jestState.page.goto(jestState.envData.root + '/wp-login.php', {waitUntil: 'load'}); 11 | await jestState.page.waitForSelector('[id=loginform]'); 12 | await jestState.page.click('input[id=user_login]'); 13 | await jestState.page.type('input[id=user_login]', jestState.envData.wp_login); 14 | await jestState.page.click('input[id=user_pass]'); 15 | await jestState.page.type('input[id=user_pass]', jestState.envData.wp_password); 16 | await jestState.page.click('input[id=wp-submit]'); 17 | await jestState.page.waitForSelector('#wp-admin-bar-my-account'); 18 | } 19 | -------------------------------------------------------------------------------- /spec/__tests__/settings_set_dir_exclusion.test.js: -------------------------------------------------------------------------------- 1 | import {test} from '@jest/globals'; 2 | import {__runLogin} from './login.test'; 3 | import {jestState} from '../form.spec'; 4 | 5 | export async function __settingsSetDirExclusion() { 6 | await jestState.page.goto( 7 | jestState.envData.root + '/wp-admin/options-general.php?page=spbc&spbc_tab=settings_general', 8 | {waitUntil: 'load'}, 9 | ); 10 | 11 | let field = '#spbc_setting_scanner__dir_exclusions_view'; 12 | await jestState.page.waitForSelector(field); 13 | await jestState.page.$eval( field, (element) => element.value = ''); 14 | await jestState.page.click(field); 15 | await jestState.page.type(field, 'wp-content\nwp-admin\nwp-includes'); 16 | 17 | await jestState.page.click('#spbc_settings_form [name="submit"]'); 18 | } 19 | 20 | /** 21 | * Run tests. 22 | * This test is a wrapper for group of tests. 23 | * @param {boolean} doLogin 24 | * @return {void} 25 | */ 26 | export function groupSettingsSetDirExclusion(doLogin = true) { 27 | if (doLogin) { 28 | test('LOGIN', async () => { 29 | await __runLogin(); 30 | }, jestState.globals.globalTimeout); 31 | } 32 | 33 | test('SETTINGS SET DIR EXCLUSION', async () => { 34 | await __settingsSetDirExclusion(); 35 | }, jestState.globals.globalTimeout); 36 | } 37 | -------------------------------------------------------------------------------- /spec/__tests__/settings_tab.test.js: -------------------------------------------------------------------------------- 1 | // Version: 1.0.0 2 | import {test} from '@jest/globals'; 3 | import {__runLogin} from './login.test'; 4 | import {jestState} from '../form.spec'; 5 | 6 | /** 7 | * Run top info tests. 8 | * @return {Promise} 9 | * @private 10 | */ 11 | export async function __runSettingsTabTests() { 12 | // example 13 | return Promise.resolve(); 14 | } 15 | 16 | /** 17 | * Run settings Tab tests. 18 | * This test is a wrapper for group of tests. 19 | * @param {boolean} doLogin 20 | * @return {void} 21 | */ 22 | export function groupSettingsTab(doLogin = true) { 23 | if (doLogin) { 24 | test('LOGIN', async () => { 25 | await __runLogin(); 26 | }, jestState.globals.globalTimeout); 27 | } 28 | test('SETTINGS TAB', async () => { 29 | await __runSettingsTabTests(); 30 | }, jestState.globals.globalTimeout); 31 | // more test there 32 | } 33 | -------------------------------------------------------------------------------- /spec/__tests__/topinfo.test.js: -------------------------------------------------------------------------------- 1 | // Version: 1.0.0 2 | import {jestState} from '../form.spec'; 3 | import {__runLogin} from './login.test'; 4 | import {test} from '@jest/globals'; 5 | /** 6 | * Run top info tests. 7 | * @return {Promise} 8 | * @private 9 | */ 10 | async function __topInfoElementsExist() { 11 | await jestState.page.goto( 12 | jestState.envData.root + '/wp-admin/options-general.php?page=spbc&spbc_tab=settings_general', 13 | {waitUntil: 'load'}, 14 | ); 15 | const topInfoElementsClasses = [ 16 | '.spbc_page_header_info_common_wrapper', 17 | '.spbc_page_header_info_left_column', 18 | '.spbc_page_header_info_right_column', 19 | '.spbc_page_header_info__state_block', 20 | '.spbc_page_header_info__block_label', 21 | '.spbc_page_header_info__block_body', 22 | '.spbc_page_header_info__block_row', 23 | '.spbc_page_header_info__about_block', 24 | '#spbc_page_header_about_block', 25 | //'.spbc_page_header_info__error_block', //Situational check, you need to have an error block in the header 26 | 27 | ]; 28 | for (let i = 0; i < topInfoElementsClasses.length; i++) { 29 | await jestState.page.$eval(topInfoElementsClasses[i], (el) => el.innerText); 30 | } 31 | } 32 | 33 | /** 34 | * Run navigation bar tests. 35 | * This test is a wrapper for group of tests. 36 | * @param {boolean} doLogin 37 | * @return {void} 38 | */ 39 | export function groupTopInfo(doLogin = true) { 40 | if (doLogin) { 41 | test('LOGIN', async () => { 42 | await __runLogin(); 43 | }, jestState.globals.globalTimeout); 44 | } 45 | test('TOP INFO ELEMENTS EXISTS', async () => { 46 | await __topInfoElementsExist(); 47 | }, jestState.globals.globalTimeout); 48 | // more test there 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /templates/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sniff code to check different PHP compatibility 4 | 5 | 6 | ../ 7 | /vendor/ 8 | /node_modules/ 9 | /install/security-malware-firewall-mu.php 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | tests/* 20 | vendor/* 21 | fw_files/* 22 | backups/* 23 | quarantine/* 24 | lib/CleantalkSP/Common/Scanner/HeuristicAnalyser/Vendors/* 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/CleantalkSP/SpbctWP/UploadChecker/TestUploadChecker.php: -------------------------------------------------------------------------------- 1 | bad_source = __DIR__ . '/files/bad_source'; 11 | $this->good_source = __DIR__ . '/files/good_source'; 12 | } 13 | 14 | public function testCheckVulnerabilityBad() 15 | { 16 | $this->assertTrue(is_dir($this->bad_source)); 17 | $result = \CleantalkSP\SpbctWP\Firewall\UploadChecker::checkVulnerability($this->bad_source); 18 | $this->assertTrue($result, $this->bad_source); 19 | } 20 | 21 | public function testCheckVulnerabilityGood() 22 | { 23 | $this->assertTrue(is_dir($this->good_source)); 24 | $result = \CleantalkSP\SpbctWP\Firewall\UploadChecker::checkVulnerability($this->good_source); 25 | $this->assertFalse($result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/CleantalkSP/SpbctWP/UploadChecker/files/bad_source/plugin_bad.php: -------------------------------------------------------------------------------- 1 | scanFile($file_to_check, $current_dir); 18 | // 19 | // $this->assertInstanceOf('CleantalkSP\Common\Scanner\HeuristicAnalyser\Structures\Verdict', $result); 20 | // $this->assertEquals($result->error_msg, 'FILE_SIZE_ZERO'); 21 | // unset ($content); 22 | // 23 | // } 24 | 25 | public function testLarge() 26 | { 27 | unset ($content); 28 | $current_dir = __DIR__ . DIRECTORY_SEPARATOR; 29 | $heuristic_scanner = new Controller(); 30 | $content = str_repeat('-', 1024*8*1024*2); 31 | $file_to_check = new FileInfo(null, $content); 32 | $result = $heuristic_scanner->scanFile($file_to_check, $current_dir); 33 | 34 | $this->assertInstanceOf('CleantalkSP\Common\Scanner\HeuristicAnalyser\Structures\Verdict', $result); 35 | $this->assertEquals( 'FILE_SIZE_TOO_LARGE', $result->error_msg); 36 | unset ($content); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Mock/FirewallStateMock.php: -------------------------------------------------------------------------------- 1 | 'QUEUE_FULL'), $file_id); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/SpbctWP/DTO/ExceptionDTOTest.php: -------------------------------------------------------------------------------- 1 | '', 15 | 'attached_sfile' => '', 16 | 'md5sum_sfile' => '', 17 | 'dangerous_code' => '', 18 | 'version' => 'version', 19 | 'source' => 'source', 20 | 'source_type' => 'source_type', 21 | 'source_status' => 'source_status', 22 | 'real_hash' => 'real_hash', 23 | ), 24 | array( 25 | 'path_to_sfile' => null, 26 | ), 27 | array( 28 | 'path_to_sfile' => 'path_to_sfile', 29 | 'lkj' => 'attached_sfile', 30 | 'jo0' => 'md5sum_sfile', 31 | '0jkjn' => 'dangerous_code', 32 | ), 33 | ); 34 | 35 | } 36 | 37 | public function testFailCreateDTO(){ 38 | $this->expectException(InvalidArgumentException::class); 39 | global $incorrect_arrays; 40 | foreach ($incorrect_arrays as $array){ 41 | $dto = new DTO\MScanFilesDTO($array); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/SpbctWP/DTO/MScanFilesDTOTest.php: -------------------------------------------------------------------------------- 1 | 'path', 14 | 'attached_sfile' => 'attached_sfile', 15 | 'md5sum_sfile' => 'md5sum_sfile', 16 | 'dangerous_code' => array(), 17 | 'version' => 'version', 18 | 'source' => 'source', 19 | 'source_type' => 'source_type', 20 | 'source_status' => 'source_status', 21 | 'real_hash' => 4, 22 | ), 23 | array( 24 | 'path_to_sfile' => 'path', 25 | 'attached_sfile' => 'attached_sfile', 26 | 'md5sum_sfile' => 'md5sum_sfile', 27 | 'dangerous_code' => 'stringtoarray', 28 | ), 29 | ); 30 | } 31 | 32 | public function testSuccessCreateDTO(){ 33 | global $correct_arrays; 34 | foreach ($correct_arrays as $array){ 35 | $dto = new DTO\MScanFilesDTO($array); 36 | $this->assertIsObject($dto); 37 | $this->assertObjectHasAttribute('path_to_sfile',$dto); 38 | $this->assertObjectHasAttribute('attached_sfile',$dto); 39 | $this->assertObjectHasAttribute('md5sum_sfile',$dto); 40 | $this->assertIsString($dto->path_to_sfile); 41 | $this->assertIsString($dto->attached_sfile); 42 | $this->assertIsString($dto->md5sum_sfile); 43 | $this->assertObjectHasAttribute('dangerous_code',$dto); 44 | $this->assertIsString($dto->dangerous_code); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/HelperTest.php: -------------------------------------------------------------------------------- 1 | assertIsArray(Helper::prepareParamForSQLQuery(array())); 11 | $this->assertIsInt(Helper::prepareParamForSQLQuery(54)); 12 | $this->assertIsString(Helper::prepareParamForSQLQuery('str')); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPClientIpTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::X_CLIENT_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPCloudflareTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::CF_CONNECTING_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPEzoicTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::X_MIDDLETON_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPForwardedForTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 23 | 24 | IP::getInstance()->ips_stored = []; 25 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 26 | 27 | $this->assertEquals(self::X_FORWARDED_FOR, IP::get()); 28 | } 29 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPGTranslateTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::X_GT_VIEWER_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPIcoForwardedForTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::ICO_X_FORWARDED_FOR, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPIncapTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::INCAP_CLIENT_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPOvhTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::OVH, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPRealIpTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 23 | 24 | IP::getInstance()->ips_stored = []; 25 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 26 | 27 | $this->assertEquals(self::X_REAL_IP, IP::get()); 28 | } 29 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPRemoteAddrTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 23 | 24 | IP::getInstance()->ips_stored = []; 25 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 26 | 27 | $this->assertEquals(self::X_FORWARDED_FOR, IP::get()); 28 | } 29 | 30 | /** 31 | * @server REMOTE_ADDR=127.0.0.1 32 | * @server HTTP_X_Forwarded_For=127.0.0.2 33 | */ 34 | public function test_find_ip() 35 | { 36 | global $spbc; 37 | $spbc->settings['secfw__get_ip'] = 2; 38 | 39 | IP::getInstance()->ips_stored = []; 40 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 41 | 42 | $this->assertEquals(self::REMOTE_ADDR, IP::get()); 43 | } 44 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPStackpathTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 24 | 25 | IP::getInstance()->ips_stored = []; 26 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 27 | 28 | $this->assertEquals(self::X_SP_FORWARDED_IP, IP::get()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPSucuriTest.php: -------------------------------------------------------------------------------- 1 | settings['secfw__get_ip'] = 1; 23 | 24 | IP::getInstance()->ips_stored = []; 25 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 26 | 27 | $this->assertEquals(self::X_SUCURI_CLIENTIP, IP::get()); 28 | } 29 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/HelperGetIPTest.php: -------------------------------------------------------------------------------- 1 | ips_stored = []; 20 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 21 | 22 | $this->assertEquals(self::REMOTE_ADDR, IP::get()); 23 | } 24 | 25 | /** 26 | * @server REMOTE_ADDR=127.0.0.1 27 | */ 28 | public function test_find_ip_header_not_sent() 29 | { 30 | global $spbc; 31 | $spbc->settings['secfw__get_ip'] = 3; 32 | 33 | IP::getInstance()->ips_stored = []; 34 | \CleantalkSP\Common\Helpers\HTTP::getInstance()->http_headers = []; 35 | 36 | $this->assertEquals(self::REMOTE_ADDR, IP::get()); 37 | } 38 | } -------------------------------------------------------------------------------- /tests/SpbctWP/Helpers/IP/README.md: -------------------------------------------------------------------------------- 1 | # The reasons for the appearance of a separate script here 2 | 3 | 4 | In this case we check work with different headers, 5 | but Phpunit can not change global variables (session, header, etc...). 6 | So, with GlobalAnnotationsListener we change headers. 7 | 8 | List of available options for secfw__get_ip setting 9 | ```php 10 | 'secfw__get_ip' => array( 11 | 'type' => 'field', 12 | 'input_type' => 'select', 13 | 'options' => array( 14 | array('val' => 1, 'label' => __('Auto', 'security-malware-firewall'),), 15 | array('val' => 2, 'label' => __('Remote Addr', 'security-malware-firewall'),), 16 | array('val' => 3, 'label' => __('X-Forwarder-For', 'security-malware-firewall'),), 17 | array('val' => 4, 'label' => __('X-Real-Ip', 'security-malware-firewall'),), 18 | array('val' => 5, 'label' => __('Incap-Client-Ip', 'security-malware-firewall'),), 19 | array('val' => 6, 'label' => __('Ico-X-Forwarded-For', 'security-malware-firewall'),), 20 | array('val' => 7, 'label' => __('X-Sp-Forwarded-Ip', 'security-malware-firewall'),), 21 | array('val' => 8, 'label' => __('X-Client-Ip', 'security-malware-firewall'),), 22 | array('val' => 9, 'label' => __('X-Sucuri-Clientip', 'security-malware-firewall'),), 23 | array('val' => 10, 'label' => __('X-Middleton-Ip', 'security-malware-firewall'),), 24 | array('val' => 11, 'label' => __('X-Gt-Viewer-Ip', 'security-malware-firewall'),), 25 | array('val' => 12, 'label' => __('Cf-Connecting-Ip', 'security-malware-firewall'),), 26 | array('val' => 13, 'label' => __('Remote-Ip', 'security-malware-firewall'),), 27 | ), 28 | ``` -------------------------------------------------------------------------------- /tests/StateTest.php: -------------------------------------------------------------------------------- 1 | state = new State( 14 | 'spbc', 15 | array( 16 | 'settings', 17 | 'data', 18 | 'remote_calls', 19 | 'debug', 20 | 'installing', 21 | 'errors', 22 | 'fw_stats' 23 | ), 24 | is_multisite(), 25 | is_main_site() 26 | ); 27 | } 28 | 29 | public function testIsHaveErrors() 30 | { 31 | $this->state->errors = array(); 32 | $this->assertFalse($this->state->isHaveErrors()); 33 | 34 | $this->state->errors = array('cron'=>array()); 35 | $this->assertFalse($this->state->isHaveErrors()); 36 | 37 | $this->state->errors = array('apikey' => array( 38 | 'error' => 'Access key is not valid. Key: someapikey', 39 | 'error_time' => 1657218128, 40 | )); 41 | $this->assertTrue($this->state->isHaveErrors()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Surface/test_deep_directory/directory1/directory11/test1.php: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ./ 19 | ./bootstrap.php 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './js/src/react/index.js', 5 | module: { 6 | rules: [ 7 | { test: /\.(js)$/, use: { 8 | loader: 'babel-loader', 9 | options: { 10 | presets: ["@babel/preset-react"] 11 | } 12 | } 13 | }, 14 | { test: /\.css$/, use: [ 15 | { 16 | loader: 'style-loader', 17 | }, 18 | { 19 | loader: 'css-loader', 20 | }, 21 | ], 22 | }, 23 | { test: /\.(gif|png|jpe?g)$/i, use: [ 24 | 'file-loader', 25 | { 26 | loader: 'image-webpack-loader', 27 | options: { 28 | bypassOnDebug: true, // webpack@1.x 29 | disable: true, // webpack@2.x and newer 30 | }, 31 | }, 32 | ], 33 | } 34 | ] 35 | }, 36 | output: { 37 | path: path.resolve(__dirname, 'js/public'), 38 | filename: 'spbct-react-bundle.js', 39 | }, 40 | // mode: 'production' 41 | mode: 'development' 42 | }; --------------------------------------------------------------------------------