Skip to content

Commit 86adc2f

Browse files
authored
Merge pull request #76 from webability-go/late-night
Late night
2 parents 5d2442f + 47658fa commit 86adc2f

6 files changed

Lines changed: 179 additions & 16 deletions

File tree

README.md

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ __Highlights__:
1818
- Can handle millions of pages per month (~500 pages per second in real environment, up to 3000 requests per second on tests, basic server ).
1919
- Available under the liberal MIT license.
2020

21-
Xamboo is the result of over 15 years of manufacturing engineering frameworks, originally written for PHP 7+ and now ported to GO 1.16+
21+
Xamboo is the result of over 17 years of manufacturing engineering frameworks, originally written for PHP 7+ and now ported to GO 1.16.3+
2222

23-
24-
It is a very high quality framework for CMS, made in GO 1.16 or higher, fully object-oriented and strong to distribute code into Web portals with heavy load and REST APIs optimization.
23+
It is a very high quality framework for CMS, made in GO 1.16.3 or higher, fully object-oriented and strong to distribute code into Web portals with heavy load and REST APIs optimization.
2524

2625
Xamboo is freeware, and uses several other freeware components (XConfig, XCore, XDominion, WAJAF)
2726

@@ -334,7 +333,7 @@ Example of a working real listeners for HTTP and HTTPS:
334333
A Host is the equivalent to a site responding to requests on a Listener. The site is named with a (sub) domain name.
335334
Any host can listen on any listener, and respond to any domain in the configuration.
336335

337-
A Host may have components activated, like compressed response, minify HTML/CSS/JS response, Basic Auth, Redirect, etc.
336+
A Host may have components activated, like compressed response, minify HTML/CSS/JS response, Basic Auth, Prot, Redirect, etc.
338337

339338
The components can be built-in or programmed.
340339

@@ -376,6 +375,7 @@ The available built-in components are:
376375
- stat: will store all the system statistics and also the requests (used by log).
377376
- redirect: will control the called domain and port, and redirect to the correct one if it is any other variant.
378377
- auth: will control the access with a username and password for basic realm authorization to access site.
378+
- prot: will protect the get, post, put variables against SQL injection.
379379
- compress: will compress the content as asked by the client (gzip or deflate) based on mime content
380380
- minify: will minify the html, css, javascript, json, xml text files if authorized type of file or mime.
381381
- origin: will set authorized headers for cros origin APIs based on rules.
@@ -399,6 +399,7 @@ The main components section follow the following structure:
399399
{ "name": "stat", "source": "built-in" },
400400
{ "name": "redirect", "source": "built-in" },
401401
{ "name": "auth", "source": "built-in" },
402+
{ "name": "prot", "source": "built-in" },
402403
{ "name": "compress", "source": "built-in" },
403404
{ "name": "minify", "source": "built-in" },
404405
{ "name": "origin", "source": "built-in" },
@@ -556,8 +557,42 @@ User and pass are the expected data to be captured to authorized the use of the
556557

557558
If the user and pass are wrong, the system returns a 401 unauthorized status.
558559

560+
#### 4.2.5. Prot
561+
562+
The protection component intend to protect the system from SQL injection.
563+
The heuristic is based on counting the quantity of SQL sentence keywords into the get and post variables, and if a certain quantity is found the security is triggered.
564+
This is a basic protection system that can be enhanced on a more personalized component.
565+
566+
The prot configuration parameters are
567+
```
568+
"hosts": [
569+
{
570+
...
571+
"prot": {
572+
"enabled": true,
573+
"sql": true,
574+
"ignore": ["var1", "var2"],
575+
"threshold": 3
576+
}
577+
},
578+
...
579+
]
580+
```
559581

560-
#### 4.2.5. compress
582+
enabled: true/false, to activate or de-activate the protection component.
583+
584+
sql: enable or disable the sql injection verification of entry variables.
585+
586+
ignore: is the list of the entry variables that will be ignored in the verification.
587+
588+
threshold: is the score of sql injection to activate the protection. A score of 3 is normally a good score to protect the code. 1 is very sensible, 5 is hard to trigger.
589+
590+
It will serve a 500 error if a sql injection is detected.
591+
592+
The activation of the protection is logged into the error log of the host with information about the injection.
593+
594+
595+
#### 4.2.6. compress
561596

562597
The compress configuration parameters are
563598
```
@@ -596,7 +631,7 @@ mimes is the list of authorized mimes to compress. If the information is any oth
596631
files is the list of filters on file names to compress. They are normal file names, with files joker (* and ?)
597632

598633

599-
#### 4.2.6. minify
634+
#### 4.2.7. minify
600635

601636
The minify configuration parameters are
602637
```
@@ -623,7 +658,7 @@ The component will minify the type of generated code (based on mime).
623658
Activate or deactivate each type of information.
624659

625660

626-
#### 4.2.7. origin
661+
#### 4.2.8. origin
627662

628663
The origin configuration parameters are
629664
```
@@ -650,7 +685,7 @@ The component will identify an OPTIONS or HEAD request and distribute the correc
650685
You should use this component only when you program some REST API or so.
651686

652687

653-
#### 4.2.8. fileserver
688+
#### 4.2.9. fileserver
654689

655690
The fileserver configuration parameters are
656691
```
@@ -676,7 +711,7 @@ If the takeover is false, when a file does not exists, the next handler will be
676711
The static directy is where the static files are.
677712

678713

679-
#### 4.2.9. cms
714+
#### 4.2.10. cms
680715

681716
The CMS is a full content mamagement system with meta language, to build powerfull dynamic sites, with business rules implemented directly into pages and code.
682717

@@ -765,7 +800,7 @@ The base template is used if the type of browser is unknown.
765800
Then CMS makes a full takeover on the handlers, so none of the following handlers will be called.
766801

767802

768-
#### 4.2.10. error
803+
#### 4.2.11. error
769804

770805
The error component will only returns a 404 errors. You may want to build your own error component to personalize the returned data.
771806

@@ -867,11 +902,10 @@ When you want to add a hand made external engine, the syntax is:
867902
{ "name": "myengine", "source": "extern", "library": "./path/to/your/myengine.so" },
868903
```
869904

870-
You may need to developp a new components for instance to replace a built-in one, or add new components.
905+
You may need to develop a new engine for instance to replace a built-in one, or add new engines.
871906

872-
For instance if you need a "auth" component based on a database for users, you may copy the library to your own directory and modify it to your needs, then call it as a extern library instead of the built-in one.
907+
For instance if you need a new page type engine based on a new type of templates for instance, you may copy the library to your own directory and modify it to your needs, then call it as a extern library instead of the built-in one.
873908

874-
Another example would be a component to verify security and SQL injection and reject the request if it does not pass though the security system. This component could be inserted before the redirect component.
875909

876910
### 5.2. List of build-in engines
877911

@@ -1443,6 +1477,11 @@ Extras:
14431477

14441478
# Version Changes Control
14451479

1480+
v1.6.2 - 2021-05-18
1481+
-----------------------
1482+
- New component "prot" added, to protect the code and query variables against SQL injection.
1483+
- In the CMS engines, the cached xtemplate is now cloned before injection into the engines to avoid racing problems between pages.
1484+
14461485
v1.6.1 - 2021-04-27
14471486
-----------------------
14481487
- The device resolution can now be replaced with the version of the programmer choice to call the correct templates. Add version=newversion into the cms configuration file.

cms/engines/template/template.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ func (p *TemplateEngineInstance) NeedTemplate() bool {
6060

6161
// context contains all the page context and history
6262
// params are an array of strings (if page from outside) or a mapped array of data (inner pages)
63+
// template may be modified, we need to CLONE it
6364
func (p *TemplateEngineInstance) Run(ctx *context.Context, template *xcore.XTemplate, language *xcore.XLanguage, e interface{}) interface{} {
6465

6566
cdata, _ := TemplateCache.Get(p.FilePath)
6667
if cdata != nil {
67-
return cdata.(*xcore.XTemplate)
68+
return cdata.(*xcore.XTemplate).Clone()
6869
}
6970

7071
if utils.FileExists(p.FilePath) {
@@ -73,7 +74,7 @@ func (p *TemplateEngineInstance) Run(ctx *context.Context, template *xcore.XTemp
7374
data.LoadFile(p.FilePath)
7475

7576
TemplateCache.Set(p.FilePath, data)
76-
return data
77+
return data.Clone()
7778
}
7879
return nil
7980
}

components/linker.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/webability-go/xamboo/components/log"
1818
"github.com/webability-go/xamboo/components/minify"
1919
"github.com/webability-go/xamboo/components/origin"
20+
"github.com/webability-go/xamboo/components/prot"
2021
"github.com/webability-go/xamboo/components/redirect"
2122
"github.com/webability-go/xamboo/components/stat"
2223
"github.com/webability-go/xamboo/config"
@@ -50,6 +51,9 @@ func Link() {
5051
case "auth":
5152
Components["auth"] = auth.Component
5253
auth.Component.Start()
54+
case "prot":
55+
Components["prot"] = prot.Component
56+
prot.Component.Start()
5357
case "compress":
5458
Components["compress"] = compress.Component
5559
compress.Component.Start()

components/prot/prot.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package prot
2+
3+
import (
4+
"net/http"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/webability-go/xamboo/components/host"
9+
"github.com/webability-go/xamboo/config"
10+
"github.com/webability-go/xamboo/loggers"
11+
)
12+
13+
var Component = &Prot{}
14+
15+
type Prot struct{}
16+
17+
func (prot *Prot) Start() {
18+
}
19+
20+
func (prot *Prot) StartHost(host *config.Host) {
21+
}
22+
23+
func (prot *Prot) NeedHandler() bool {
24+
return true
25+
}
26+
27+
func (prot *Prot) Handler(handler http.HandlerFunc) http.HandlerFunc {
28+
return func(w http.ResponseWriter, r *http.Request) {
29+
30+
slg := loggers.GetCoreLogger("errors")
31+
32+
hw, ok := w.(host.HostWriter)
33+
if !ok {
34+
slg.Println("C[prot]: Critical error: the writer is not a HostWriter (and that should not happen)", r, w)
35+
http.Error(w, "C[prot]: Writer error (see logs for more info)", http.StatusInternalServerError)
36+
return
37+
}
38+
host := hw.GetHost()
39+
if host == nil {
40+
slg.Println("C[prot]: Critical error: there is no HOST in the host writer (and that should not happen)", r, w)
41+
http.Error(w, "C[prot]: Writer error (see logs for more info)", http.StatusInternalServerError)
42+
return
43+
}
44+
45+
lg := loggers.GetHostLogger(host.Name, "sys")
46+
if host.Debug {
47+
lg.Println("C[prot]: We are going to verify the SQL Injection Protector, enabled:", host.Prot.Enabled)
48+
}
49+
50+
if host.Prot.Enabled {
51+
if host.Prot.SQL {
52+
// Search into request specific keywords:
53+
// SELECT UPDATE DELETE INSERT COALESCE FROM TABLE ORDER GROUP WHERE /**/ AND OR
54+
syntax := `(?si)` + // . is multiline and case insensitive
55+
56+
// keywords
57+
`\bselect\b` +
58+
`|\binsert\b` +
59+
`|\bupdate\b` +
60+
`|\bdelete\b` +
61+
`|\bcoalesce\b` +
62+
`|\bfrom\b` +
63+
`|\btable\b` +
64+
`|\bwhere\b` +
65+
`|\border\b` +
66+
`|\bgroup\b` +
67+
`|\blimit\b` +
68+
`|\bhaving\b` +
69+
`|\bjoin\b` +
70+
`|\band\b` +
71+
`|\bor\b` +
72+
`|\/\*\*\/`
73+
74+
codex := regexp.MustCompile(syntax)
75+
76+
ignored := map[string]bool{}
77+
for _, i := range host.Prot.Ignore {
78+
ignored[i] = true
79+
}
80+
81+
r.ParseForm()
82+
nummatch := 0
83+
for p, v := range r.Form {
84+
// ignore variables
85+
if ignored[p] {
86+
continue
87+
}
88+
data := strings.Join(v, " ")
89+
indexes := codex.FindAllStringIndex(data, -1)
90+
nummatch += len(indexes)
91+
}
92+
93+
if nummatch >= host.Prot.Threshold { // threshold to have a real query
94+
slg.Println("C[prot]: SQL INJECTION MATCH FOUND:", r)
95+
http.Error(w, "C[prot]: SQL INJECTION MATCH FOUND by Xamboo Protection System", http.StatusInternalServerError)
96+
return
97+
}
98+
99+
}
100+
}
101+
102+
if host.Debug {
103+
lg.Println("C[Prot]: Protector not activated. We are going to serve the handler.")
104+
}
105+
handler.ServeHTTP(w, r)
106+
if host.Debug {
107+
lg.Println("C[Prot]: We have served the handler.")
108+
}
109+
}
110+
}

config/hosts.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Host struct {
3434
Stat Stat `json:"stat"`
3535
Redirect Redirect `json:"redirect"`
3636
Auth Auth `json:"auth"`
37+
Prot Prot `json:"prot"`
3738
Compress Compress `json:"compress"`
3839
Minify Minify `json:"minify"`
3940
Origin Origin `json:"origin"`
@@ -91,6 +92,7 @@ func (hc *Host) UnmarshalJSON(buf []byte) error {
9192
hc.Stat = thc.Stat
9293
hc.Redirect = thc.Redirect
9394
hc.Auth = thc.Auth
95+
hc.Prot = thc.Prot
9496
hc.Compress = thc.Compress
9597
hc.Minify = thc.Minify
9698
hc.Origin = thc.Origin
@@ -119,6 +121,13 @@ type Auth struct {
119121
Pass string `json:"pass"`
120122
}
121123

124+
type Prot struct {
125+
Enabled bool `json:"enabled"`
126+
SQL bool `json:"sql"`
127+
Ignore []string `json:"ignore"`
128+
Threshold int
129+
}
130+
122131
type Compress struct {
123132
Enabled bool `json:"enabled"`
124133
Mimes []string `json:"mimes"`

xamboo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
package xamboo
2727

2828
// VERSION last oficial published version of the xamboo on github.com
29-
const VERSION = "1.6.1"
29+
const VERSION = "1.6.2"

0 commit comments

Comments
 (0)