├── .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 '';
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 |
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 |
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 |
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 |
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 |
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 .= '';
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 |

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 |
{{LAST_UPDATE_RESULT}}
4 |
5 |
6 |
{{CURRENT_STATE_TEXT}}
7 |
8 |
9 |
10 |
11 |
{{VULNERABILITIES_SUBTITLE}}
12 |
13 |
14 | {{VULNERABLE_ITEMS}}
15 |
16 |
17 |
18 |
{{PSC_SUBTITLE}}
19 |
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 | };
--------------------------------------------------------------------------------