File: README.md
SafeLine - Make your web apps secure
🏆 Achievements
👋 INTRODUCTION
SafeLine is a self-hosted WAF(Web Application Firewall) to protect your web apps from attacks and exploits.
A web application firewall helps protect web apps by filtering and monitoring HTTP traffic between a web application and the Internet. It typically protects web apps from attacks such as SQL injection, XSS, code injection, os command injection, CRLF injection, ldap injection, xpath injection, RCE, XXE, SSRF, path traversal, backdoor, bruteforce, http-flood, bot abused, among others.
💡 How It Works
By deploying a WAF in front of a web application, a shield is placed between the web application and the Internet. While a proxy server protects a client machine’s identity by using an intermediary, a WAF is a type of reverse-proxy, protecting the server from exposure by having clients pass through the WAF before reaching the server.
A WAF protects your web apps by filtering, monitoring, and blocking any malicious HTTP/S traffic traveling to the web application, and prevents any unauthorized data from leaving the app. It does this by adhering to a set of policies that help determine what traffic is malicious and what traffic is safe. Just as a proxy server acts as an intermediary to protect the identity of a client, a WAF operates in similar fashion but acting as a reverse proxy intermediary that protects the web app server from a potentially malicious client.
its core capabilities include:
- Defenses for web attacks
- Proactive bot abused defense
- HTML & JS code encryption
- IP-based rate limiting
- Web Access Control List
⚡️ Screenshots
Get Live Demo
🔥 FEATURES
List of the main features as follows:
Block Web Attacks- It defenses for all of web attacks, such as
SQL injection,XSS,code injection,os command injection,CRLF injection,XXE,SSRF,path traversaland so on.
- It defenses for all of web attacks, such as
Rate Limiting- Defend your web apps against
DoS attacks,bruteforce attempts,traffic surges, and other types of abuse by throttling traffic that exceeds defined limits.
- Defend your web apps against
Anti-Bot Challenge- Anti-Bot challenges to protect your website from
bot attacks, human users will be allowed, crawlers and bots will be blocked.
- Anti-Bot challenges to protect your website from
Authentication Challenge- When authentication challenge turned on, visitors need to enter the password, otherwise they will be blocked.
Dynamic Protection- When dynamic protection turned on, html and js codes in your web server will be dynamically encrypted by each time you visit.
🧩 Showcases
| Legitimate User | Malicious User | |
|---|---|---|
Block Web Attacks |
||
Rate Limiting |
||
Anti-Bot Challenge |
||
Auth Challenge |
||
HTML Dynamic Protection |
||
JS Dynamic Protection |
🚀 Quickstart
[!WARNING]
中国大陆用户安装国际版可能会导致无法连接云服务,请查看 中文版安装文档
📦 Installing
Information on how to install SafeLine can be found in the Install Guide
⚙️ Protecting Web Apps
to see Configuration
📋 More Informations
Effect Evaluation
| Metric | ModSecurity, Level 1 | CloudFlare, Free | SafeLine, Balance | SafeLine, Strict |
|---|---|---|---|---|
| Total Samples | 33669 | 33669 | 33669 | 33669 |
| Detection | 69.74% | 10.70% | 71.65% | 76.17% |
| False Positive | 17.58% | 0.07% | 0.07% | 0.22% |
| Accuracy | 82.20% | 98.40% | 99.45% | 99.38% |
Is SafeLine Production-Ready?
Yes, SafeLine is production-ready.
- Over 400,000 installations worldwide
- Protecting over 1,000,000 Websites
- Handling over 30,000,000,000 HTTP Requests Daily
🌟 Community Recognition
- Rated 10.0/10 by HelloGitHub
- Listed in awesome-selfhosted
- Featured on Product Hunt
- Recognized by Cyber Press as the most popular open-source web firewall on GitHub
🔌 Ecosystem Integrations
- SafeLine MCP Server for AI-assisted management and control
- Ingress-NGINX plugin for protecting Kubernetes ingress traffic
- Kong Gateway plugin for protecting APIs and services
🙋♂️ Community
Join our Discord to get community support, the core team members are identified by the STAFF role in Discord.
- channel #feedback: for new features discussion.
- channel #FAQ: for FAQ.
- channel #general: for any other questions.
Several contact options exist for our community, the primary one being Discord. These are in addition to GitHub issues for creating a new issue.
💪 PRO Edition
SafeLine PRO is now available! Explore plans and pricing or start a 7-day trial.
📝 License
See LICENSE for details.
File: management/tcontrollerd/README.md
TControllerD
Tengine Controller Daemon (abbr. TCD) will be running in the Tengine container,
designed to be in place with minion on the host machine.
Requirements
Go 1.18+
Development
init protobuf
# Refer: https://grpc.io/docs/languages/go/quickstart/
# 1. Install protoc
# https://grpc.io/docs/protoc-installation/
# 2. Install Go plugins
go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]
# 3. Update your PATH so that the protoc compiler can find the plugins
# export PATH="$PATH:$(go env GOPATH)/bin"
# 4. Generate proto go code
# cd /path/to/management
./scripts/genproto.shFile: management/webserver/README.md
Web Server
web server for mgt-api
Requirements
Go 1.18+
Development
Init protobuf
# Refer: https://grpc.io/docs/languages/go/quickstart/
# 1. Install protoc
# https://grpc.io/docs/protoc-installation/
# 2. Install Go plugins
go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]
# 3. Update your PATH so that the protoc compiler can find the plugins
# export PATH="$PATH:$(go env GOPATH)/bin"
# 4. Generate proto go code
# cd /path/to/management
./scripts/genproto.shInit fvm libs
# Due to the fvm c header files
mkdir -p management/webserver/submodule/fvm/
mkdir -p management/webserver/submodule/libct/
cd management/webserver/submodule/fvm/
# Download https://chaitin.cn/patronus/fvm/-/tags 1.8.21 release:release, https://chaitin.cn/patronus/fvm/-/jobs/6716645
unzip artifacts.zip
rm artifacts.zip
cd management/webserver/submodule/libct/
# Download https://chaitin.cn/patronus/libct/-/tags 1.1.1.0 release, https://chaitin.cn/patronus/libct/-/jobs/7229201
# rename
rm artifacts.zip
cd management/webserver/submodule/
# Download https://chaitin.cn/patronus/fusion-2/-/tags 5.3.9-r1 build:release, https://chaitin.cn/patronus/fusion-2/-/jobs/7326007
# rename
unzip artifacts.zip
mv artifacts/lib/libfusion.so libfvm.so
rm artifacts.zip
rm -r artifacts/Build
cd management/
docker run -it --rm -w="/mnt" --mount type=bind,source="$(pwd)",target=/mnt chaitin.cn/ci/golang:1.18 bash
cp webserver/submodule/libfvm.so /usr/lib/
make build-webserverFile: mcp_server/README.md
SafeLine MCP Server
SafeLine MCP Server is an implementation of the Model Context Protocol (MCP) that provides complete management and control capabilities for SafeLine WAF.
Use Cases
- Automated management and control of SafeLine WAF instances
- WAF configuration and policy management through API
- Building AI-based security protection tools and applications
Prerequisites
- Install Docker (if running in container)
- Configure SafeLine API Token (obtained from SafeLine console)
Features
- Complete MCP (Management Control Protocol) server implementation
- Support for SafeLine WAF instance management and control
- Flexible configuration system supporting file configuration and environment variables
- Docker containerization support
- Secure API communication
Quick Start
Environment Variables
| Environment Variable | Description | Default Value | Required |
|---|---|---|---|
| LISTEN_PORT | Service listening port | 5678 | No |
| LISTEN_ADDRESS | Service listening address | 0.0.0.0 | No |
| SAFELINE_SECRET | SSE server secret | - | No |
| SAFELINE_ADDRESS | SafeLine API address | - | Yes |
| SAFELINE_API_TOKEN | SafeLine API authentication token | - | Yes |
Using Docker
Method 1: Using docker run
docker run -d \
--name safeline-mcp \
-p 5678:5678 \
-e SAFELINE_API_TOKEN="your_api_token" \
-e SAFELINE_ADDRESS="https://your.safeline.com" \
-e LISTEN_PORT=5678 \
-e LISTEN_ADDRESS="0.0.0.0" \
chaitin/safeline-mcp:latestMethod 2: Using docker-compose
# 1. Clone repository
git clone https://github.com/chaitin/safeline-mcp.git
cd safeline-mcp
# 2. Edit docker-compose.yml to configure environment variables
# Example docker-compose.yml:
# version: '3'
# services:
# mcp:
# image: chaitin/safeline-mcp:latest
# container_name: safeline-mcp
# ports:
# - "5678:5678"
# environment:
# - SAFELINE_API_TOKEN=your_api_token
# - SAFELINE_ADDRESS=https://your.safeline.com
# - LISTEN_PORT=5678
# - LISTEN_ADDRESS=0.0.0.0
# 3. Start service
docker compose -f docker-compose.yml up -dMethod 3: Using Go
# 1. Clone repository
git clone https://github.com/chaitin/SafeLine.git
cd safeline-mcp
# 2. Install dependencies
go mod download
# 3. Configure config.yaml
cp config.yaml.example config.yaml
# Edit config.yaml with necessary configurations
# 4. Run service
go run main.goFor more API details, please refer to the API Documentation.
Tools
Application Management
- create_application
Rule Management
- create_blacklist_rule
- create_whitelist_rule
Analyze
- get_attack_events
Development Guide
The Go API in this project is currently under development, and APIs may change. If you have specific requirements, please submit an Issue for discussion.
Directory Structure
internal/
├── api/ # API implementation
│ ├── app/ # Application-related APIs
│ │ └── create_application.go
│ └── rule/ # Rule-related APIs
│ └── create_rule.go
└── tools/ # MCP tool implementation
├── app/ # Application-related tools
│ └── create_application.go
└── rule/ # Rule-related tools
└── create_rule.goAdding New Tools
Create Tool File
- Create corresponding directory and file under
internal/tools - File name should match tool name
- Use separate file for each tool
- Example:
internal/tools/app/create_application.go
- Create corresponding directory and file under
Tool Implementation Template
package app
type ToolName struct{}
type ToolParams struct {
// Parameter definitions
Param1 string `json:"param1" desc:"parameter description" required:"true"`
Param2 int `json:"param2" desc:"parameter description" required:"false"`
}
type ToolResult struct {
Field1 string `json:"field1"`
}
func (t *ToolName) Name() string {
return "tool_name"
}
func (t *ToolName) Description() string {
return "tool description"
}
func (t *ToolName) Validate(params ToolParams) error {
// Parameter validation logic
return nil
}
func (t *ToolName) Execute(ctx context.Context, params ToolParams) (result ToolResult, err error) {
// Tool execution logic
return result, nil
}- [Optional]Create API Implementation
If you need to use some APIs that have not been implemented yet, you need to create corresponding files in the api directory for implementation
- Create same directory structure under
internal/api - File name should match tool func
- Example:
internal/api/app/create_application.go
API Implementation Template
package app
type RequestType struct {
// Request parameter definitions
Param1 string `json:"param1"`
Param2 int `json:"param2"`
}
func APIName(ctx context.Context, req *RequestType) (ResultType, error) {
if req == nil {
return nil, errors.New("request is required")
}
var resp api.Response[ResultType]
err := api.Service().Post(ctx, "/api/path", req, &resp)
if err != nil {
return nil, errors.Wrap(err, "failed to execute")
}
if resp.Err != nil {
return nil, errors.New(resp.Msg)
}
return resp.Data, nil
}- Tool Registration (init.go)
The tool registration file internal/tools/init.go is used to centrally manage all tool registrations
- Register all tools uniformly in the
init()function - Use the
AppendTool()method for registration - Example:go
// Register create application tool AppendTool(&app.CreateApp{}) // Register create blacklist rule tool AppendTool(&rule.CreateBlacklistRule{})
Development Standards
Naming Conventions
- Use lowercase letters and underscores for tool names
- File names should match tool names
Directory Organization
- Divide directories by functional modules (e.g., app, rule, etc.)
- Maintain consistent structure between tools and api directories
- Keep related functionality in the same directory
Code Standards
- Follow Go standard code conventions
- Add necessary parameter validation
- Use unified error handling approach
- Add appropriate logging
Documentation Requirements
- Provide clear functional description in tool Description
- Add detailed description for parameters
- Update API toolkit documentation in README
Example
Refer to the implementation of the create_application tool:
- Tool implementation:
internal/tools/app/create_application.go - API implementation:
internal/api/app/create_application.go
File: sdk/lua-resty-t1k/README.md
lua-resty-t1k
Name
Lua implementation of the T1K protocol for Chaitin/SafeLine Web Application Firewall.
Status
Production ready.
Installation
luarocks install lua-resty-t1kIf you are in Mainland China
luarocks install lua-resty-t1k --server https://luarocks.cnSynopsis
location / {
access_by_lua_block {
local t1k = require "resty.t1k"
local t = {
mode = "block", -- block or monitor or off, default off
host = "unix:/workdir/snserver.sock", -- required, SafeLine WAF detection service host, unix domain socket, IP, or domain is supported, string
port = 8000, -- required when the host is an IP or domain, SafeLine WAF detection service port, integer
connect_timeout = 1000, -- connect timeout, in milliseconds, integer, default 1s (1000ms)
send_timeout = 1000, -- send timeout, in milliseconds, integer, default 1s (1000ms)
read_timeout = 1000, -- read timeout, in milliseconds, integer, default 1s (1000ms)
req_body_size = 1024, -- request body size, in KB, integer, default 1MB (1024KB)
keepalive_size = 256, -- maximum concurrent idle connections to the SafeLine WAF detection service, integer, default 256
keepalive_timeout = 60000, -- idle connection timeout, in milliseconds, integer, default 60s (60000ms)
remote_addr = "http_x_forwarded_for: 1", -- remote address from ngx.var.VARIABLE, string, default from ngx.var.remote_addr
}
local ok, err, _ = t1k.do_access(t, true)
if not ok then
ngx.log(ngx.ERR, err)
end
}
header_filter_by_lua_block {
local t1k = require "resty.t1k"
t1k.do_header_filter()
}
}Lua Resty T1K vs. C T1K
C T1K, as part of SafeLine's enterprise edition, is a deployment mode crafted in C language for enhanced performance.
It is compatible with all versions of Nginx and does not require deployment via OpenResty (lua_nginx_module).
| Lua Resty T1K | C T1K | |
|---|---|---|
| Request Detection | ✅ | ✅ |
| Response Detection | ❌ | ✅ |
| Health Checks* | ❌ | ✅ |
| Cookie Protection | ❌ | ✅ |
| Bot Protection | ❌ | ✅ |
| Proxy-side Statistics | ❌ | ✅ |
* APISIX implements health check functionality for the chaitin-waf plugin. For more information, please see the chaitin-waf documentation.
File: sdk/kong/Readme.md
Kong Safeline Plugin
Kong plugin for Chaitin SafeLine Web Application Firewall (WAF). This plugin is used to protect your API from malicious requests. It can be used to block requests that contain malicious content in the request body, query parameters, headers, or URI.
Safeline Prepare
The detection engine of the SafeLine provides services by default via Unix socket. We need to modify it to use TCP, so it can be called by the t1k plugin.
1.Navigate to the configuration directory of the SafeLine detection engine:
cd /data/safeline/resources/detector/2.Open the detector.yml file in a text editor. Modify the bind configuration from Unix socket to TCP by adding the following settings:
bind_addr: 0.0.0.0
listen_port: 8000These configuration values will override the default settings in the container, making the SafeLine engine listen on port 8000.
3.Next, map the container’s port 8000 to the host machine. First, navigate to the SafeLine installation directory:
cd /data/safeline4.Open the compose.yaml file in a text editor and add the ports field to the detector container to expose port 8000:
...
detect:
ports:
- 8000:8000
...5.Save the changes and restart SafeLine with the following commands:
docker-compose down
docker-compose up -dThis will apply the changes and activate the new configuration.
Plugin Installation
To install the plugin, run the following command in your Kong server:
$ luarocks install kong-safelinePlugin Configuration
You can add the plugin to your API by making the following request:
# if your detector is running on tcp port
$ curl -X POST http://kong:8001/services/{name}/plugins \
--data "name=safeline" \
--data "config.host=your_detector_host" \
--data "config.port=your_detector_port"
# if your detector is running on unix socket
$ curl -X POST http://kong:8001/services/{name}/plugins \
--data "name=safeline" \
--data "config.host=unix:/path/to/your/unix/socket"Test
You can test the plugin by sending a request to your API with malicious content. If the request is blocked, you will receive a 403 Forbidden response.
$ curl -X POST http://kong:8000?1=1%20and%202=2
# you will receive a 403 Forbidden response
{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "8b41a021ea9541c89bb88f3773b4da24"}File: sdk/ingress-nginx/README.md
ingress-nginx-safeline
Ingress-nginx plugin for Chaitin SafeLine Web Application Firewall (WAF). This plugin is used to protect your API from malicious requests. It can be used to block requests that contain malicious content in the request body, query parameters, headers, or URI.
Safeline Prepare
The detection engine of the SafeLine provides services by default via Unix socket. We need to modify it to use TCP, so it can be called by the t1k plugin.
1.Navigate to the configuration directory of the SafeLine detection engine:
cd /data/safeline/resources/detector/2.Open the detector.yml file in a text editor. Modify the bind configuration from Unix socket to TCP by adding the following settings:
bind_addr: 0.0.0.0
listen_port: 8000These configuration values will override the default settings in the container, making the SafeLine engine listen on port 8000.
3.Next, map the container’s port 8000 to the host machine. First, navigate to the SafeLine installation directory:
cd /data/safeline4.Open the compose.yaml file in a text editor and add the ports field to the detector container to expose port 8000:
...
detect:
ports:
- 8000:8000
...5.Save the changes and restart SafeLine with the following commands:
docker-compose down
docker-compose up -dThis will apply the changes and activate the new configuration.
Plugin Usage
Step 1: Install the plugin
way 1: Build your own ingress-nginx/controller image with the plugin installed.
FROM registry.k8s.io/ingress-nginx/controller:v1.10.1
USER root
RUN apk add --no-cache make gcc unzip wget
# install luaroncks
RUN wget https://luarocks.org/releases/luarocks-3.11.0.tar.gz && \
tar zxpf luarocks-3.11.0.tar.gz && \
cd luarocks-3.11.0 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf luarocks-3.11.0 luarocks-3.11.0.tar.gz
RUN luarocks install ingress-nginx-safeline && \
ln -s /usr/local/share/lua/5.1/safeline /etc/nginx/lua/plugins/safeline
USER www-dataway 2: Use the chaitin ingress-nginx-controller image.
replace image ingress-nginx-controller with docker.io/chaitin/ingress-nginx-controller:v1.10.1 in your deployment.
Step 2: Configure the plugin
use a ConfigMap to configure the plugin
apiVersion: v1
kind: ConfigMap
metadata:
name: safeline
namespace: default
data:
host: "YOUR_DETECTOR_HOST"
port: "YOUR_DETECTOR_PORT"Step 3: Configure the ingress-controller
inject env SAFELINE_HOST and SAFELINE_PORT to the ingress-controller deployment
...
env:
- name: SAFELINE_HOST
valueFrom:
configMapKeyRef:
name: safeline
key: host
- name: SAFELINE_PORT
valueFrom:
configMapKeyRef:
name: safeline
key: port
...Step 3: Enable the plugin
enable safeline plugin in configmap
apiVersion: v1
data:
allow-snippet-annotations: "false"
plugins: "safeline"
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: defaultStep 4: Set externalTrafficPolicy to Local
by default, the ingress-nginx-controller service is of type LoadBalancer, which means the source IP of the request will be the IP of the LoadBalancer. If you want to get the real source IP, you can set the externalTrafficPolicy to Local.
Step 5: Test the plugin
use a simple http sql injection test
curl -X POST http://localhost/ -d "select * from users where id=1 or 1=1"you should get a 403 response.
{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "b53eb5b95796475699c52a019abb8e6a"}File: yanshi/README.md
偃师 (yanshi)
yanshi is a finite state automaton generator like Ragel. Use inline operators to embed C++ code in the recognition of a language. yanshi is enhanced with features to approximate context-free grammar:
- Approximation of substring grammar
- Approximation of recursive automaton to match expressions with recursion.
The motivation to create yanshi is that Ragel does not provide a mechanism to serialize its representation of finite state automata, making it difficult to post-process generated automata and obtain the substring grammar recognizer.
Later on, I found a simplified SQL grammar might contain more than 10000 states. It was not only slow to generate the automaton, making it hard to do trial-and-error experiments, but wasted memory to store the automaton. I introduced CollapseExpr to allow circular references.
CallExpr takes one step further, maintains a return address stack to imitate function calls. It can be seen as an augmented CollapseExpr, removing a lot of false positive cases.
Name
From https://en.wikipedia.org/wiki/Automaton:
In ancient China, a curious account of automata is found in the Lie Zi text (列子), written in the 3rd century BC. Within it there is a description of a much earlier encounter between King Mu of Zhou (周穆王, 1023-957 BC) and a mechanical engineer known as Yan Shi (偃师), an 'artificer'.
Build
- Debug:
make - Release:
make build=release
Getting Started
Create file
a.ys:textexport foo = 'hello'Run
yanshi -S a.ys -o /tmp/a.ccto generate a C++ file from the yanshi source filea.ys.yanshi_foo_start: the start state is 0. States are represented by natural numbers.yanshi_foo_is_final: leave asideret_stackand look at the last line, it checks whetheruis one of the final states.yanshi_foo_transit: leave asideret_stack,uis the current state andcis the next input codepoint or label.
With the
-Soption, yanshi will generate a standalone C++ file.text% make -C /tmp a make: Entering directory '/tmp' g++ a.cc -o a make: Leaving directory '/tmp' % /tmp/a hello 0 h 1 e 2 l 3 l 4 o 5 len: 5 pref: 5 state: 5 final: true % /tmp/a hello0 h 1 e 2 l 3 l 4 o 5 len: 5 pref: 5 state: 5 final: trueStates are yellow and interleaved with transition labels. Final states are bold yellow.
len: the length of input codepoints or labelspref: the length of the longest prefix that does not enter the dead statestate: the state entered after consuming the inputfinal: whether the state is one of final states
Interactive mode
The
-ioption enables interactive mode.text% yanshi -i a.ys Testing foo foo :: DefineStmt .integer mode Commands available from the prompt: .automaton dump automaton .assoc dump associated AST Expr for each state .help display this help .integer input is a list of non-negative integers, macros(#define) or '' quoted strings .macro display defined macros .string input is a string .stmt change target DefineStmt to .quit exit interactive mode λ 104 101 108 108 111 0 104 1 101 2 108 3 108 4 111 5 export foo = 'hello': λ .string .string mode λ hello 0 h 1 e 2 l 3 l 4 o 5 export foo = 'hello': λRegex-like syntax
textexport hello = [gh] 'e' l{2} 'o' l = 'l'[gh]is a bracket expression andl{2}denotes to matcheslat least twice. This grammar matcheshello,gello,helllo, ...- Union:
c = a | b - Intersection:
c = a && b - Difference:
c = a - b - Concatenation:
c = a b - Complement:
c = ~ a
- Union:
Actions (embedded C++ code)
textc++ { #include <stdio.h> } export hello = '喵' @ { puts("meow"); } {2}I have not thought clearly on the implementation. The executing point may be counter-intuitive.
Modules
text# a.ys import 'b.ys' as B # B::bar import 'b.ys' # qux export foo = B::bar | qux bar = '4' # b.ys bar = '3' qux = '5'Substring grammar
Specify the--substring-grammaroption to generate code for substring grammar. That is, the generated code matches every substring of the grammar. The implementation creates a new start state and a new final state, connects the start state to the old start state, and old final states to the new final state.EmbedExpr, reference a nonterminal without modifierstextfoo = bar bar = [0-9]The complete automaton of bar will be duplicated in each reference site. If the referenced automaton is large,
EmbedExprwill significantly increase the number of states.EmbedExprdefines dependencies among states and no cyclic dependency is allowed.CollapseExpr, reference a nonterminal with the!modifiertextexport foo = 'pre' !bar 'post' bar = [\u0300-\u034E] quz = 'meow' !bar 'meow'The final state of
'pre'and the start state of'post'will be connected by a special directed arc. When exporting, an epsilon transition will be added from the tail of the arc to the start state ofbar, others will be added from the final states ofbarto the head of the arc.CollapseExprbehaves like function calls, however, the return address is not preserved (hence the nameCollapseExpr) and the state may go to other call sites. In this example, the state may go to eitherfooorquzafter traveling throughbar, causing false positives.CallExpr, reference a nonterminal with the&modifiertextexport foo = 'pre' &bar 'post' bar = '4'This is a refinement of
CollapseExpr. Suppose state&Bis contained inA's definition (AcallsB).&Bwill be represented as an pseudo arc (u -> v), whereuis the state before&Bandvis the state after&B. If arcs ofudo not collide with arcs ofB, the transition function will pushvto the return stack if current state set containsuand there is no other transition. NoteBis disconnected fromA, which is different from theCollapseExprcase. The machine will transit on automatonBgreedily. If there is no transition, it will pop a return address(vin this case) and jumps to it.
Contrib
Vim
Syntax highlighting, and a syntax checking plugin for Synaptics
ln -sr contrib/vim/compiler/yanshi.vim ~/.vim/compiler/
ln -sr contrib/vim/ftdetect/yanshi.vim ~/.vim/ftdetect/
ln -sr contrib/vim/ftplugin/yanshi.vim ~/.vim/ftplugin/
ln -sr contrib/vim/syntax/yanshi.vim ~/.vim/syntax/
ln -sr contrib/vim/syntax_checker/yanshi ~/.vim/syntax_checker/Zsh
Command line completion
# ~/.zshrc
fpath=(~/.zsh $fpath)
# ln -sr contrib/zsh/_yanshi ~/.zsh/Internals
src
common.{cc,hh}
main.{cc,hh}
syntax.{cc,hh}
loader.{cc,hh}
fsa.{cc,hh}
fsa_anno.{cc,hh}
compiler.{cc,hh}
parser.y
lexer.l
location.cc- Lex
lexer.l - Parse and generate a syntax tree
parser.y loader.cc- Get a list of definitions
- Recursively load for each
import - Resolve references and associate uses to definitions
- Build a dependency graph from
EmbedExpr - Compile automaton for each nonterminal in topological order.
CollapseExprandCallExprare represented by special directed arcs. - Generate code for
exportnonterminals, resolvingCollapseExprandCallExpr
Finite state automaton
Each node of the syntax tree corresponds to an automaton. The parent builds an automaton from its children according to the semantics. The automaton of the parent may contain states from the automaton of one of the children, or it is a state introduced by the parent.
assoc[i] records the associative nodes in the automaton tree (which part of the syntax tree has associations with this state) and positions (start state, final state or inner state) for state i. It serves three purposes:
- Check which action should be triggered
- Look for inner states (neither start nor final) in the implementation of substring grammar
- Check whether it is associated to a
CallExprorCollapseExpr
`CollapseExpr`
File: README_CN.md
SafeLine - 雷池 - 不让黑客越过半步
🏆 项目荣誉
👋 项目介绍
SafeLine,中文名 "雷池",是一款简单好用, 效果突出的 Web 应用防火墙(WAF),可以保护 Web 服务不受黑客攻击。
雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入、XSS、 代码注入、命令注入、CRLF 注入、ldap 注入、xpath 注入、RCE、XXE、SSRF、路径遍历、后门、暴力破解、CC、爬虫 等攻击。
💡 工作原理
雷池通过阻断流向 Web 服务的恶意 HTTP 流量来保护 Web 服务。雷池作为反向代理接入网络,通过在 Web 服务前部署雷池,可在 Web 服务和互联网之间设置一道屏障。
雷池的核心功能如下:
- 防护 Web 攻击
- 防爬虫, 防扫描
- 前端代码动态加密
- 基于源 IP 的访问速率限制
- HTTP 访问控制
⚡️ 项目截图
查看 演示环境
🔥 核心能力
对于你的网站而言, 雷池可以实现如下效果:
阻断 Web 攻击- 可以防御所有的 Web 攻击,例如
SQL 注入、XSS、代码注入、操作系统命令注入、CRLF 注入、XXE、SSRF、路径遍历等等。
- 可以防御所有的 Web 攻击,例如
限制访问频率- 限制用户的访问速率,让 Web 服务免遭
CC 攻击、暴力破解、流量激增和其他类型的滥用。
- 限制用户的访问速率,让 Web 服务免遭
人机验证- 互联网上有来自真人用户的流量,但更多的是由爬虫, 漏洞扫描器, 蠕虫病毒, 漏洞利用程序等自动化程序发起的流量,开启雷池的人机验证功能后真人用户会被放行,恶意爬虫将会被阻断。
身份认证- 雷池的 "身份认证" 功能可以很好的解决 "未授权访问" 漏洞,当用户访问您的网站时,需要输入您配置的用户名和密码信息,不持有认证信息的用户将被拒之门外。
动态防护- 在用户浏览到的网页内容不变的情况下,将网页赋予动态特性,对 HTML 和 JavaScript 代码进行动态加密,确保每次访问时这些代码都以随机且独特的形态呈现。
🧩 核心能力展示
| Legitimate User | Malicious User | |
|---|---|---|
阻断 Web 攻击 |
||
限制访问频率 |
||
人机验证 |
||
身份认证 |
||
HTML 动态防护 |
||
JS 动态防护 |
🚀 上手指南
📦 安装
查看 安装雷池
⚙️ 配置防护站点
查看 快速配置
📋 更多信息
防护效果测试
| Metric | ModSecurity, Level 1 | CloudFlare | 雷池, 平衡 | 雷池, 严格 |
|---|---|---|---|---|
| 样本数量 | 33669 | 33669 | 33669 | 33669 |
| 检出率 | 69.74% | 10.70% | 71.65% | 76.17% |
| 误报率 | 17.58% | 0.07% | 0.07% | 0.22% |
| 准确率 | 82.20% | 98.40% | 99.45% | 99.38% |
雷池可以投入生产使用吗
是的,已经有不少用户将雷池投入生产使用,截至目前
- 全球累计装机量已超过 40 万台
- 防护的网站数量超过 100 万个
- 每天清洗 HTTP 请求超过 300 亿次
🌟 社区认可
- 获得 HelloGitHub 10.0/10 评分
- 被 awesome-selfhosted 收录
- 被 Cyber Press 评为 GitHub 上最受欢迎的开源 Web 应用防火墙
🔌 生态集成
- SafeLine MCP Server:支持通过 AI 辅助管理和控制雷池
- Ingress-NGINX:保护 Kubernetes Ingress 流量
- Kong Gateway:保护经过 Kong 的 API 和服务
🙋♂️ 用户社区
欢迎加入雷池 社区微信群 进行技术交流。
也可以加入雷池 Discord 来获取更多社区支持。
💪 专业版
雷池专业版现已发布!查看 社区版 vs 专业版,选择适合你的版本。