Skip to content

Commit ad7ce64

Browse files
committed
init
1 parent 90169ec commit ad7ce64

File tree

68 files changed

+366
-179
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+366
-179
lines changed

.flake8

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[flake8]
2+
# Increase the max line length to 120 characters
3+
max-line-length = 120
4+
5+
# Ignore specific errors/warnings:
6+
# E501: Line too long
7+
# W291: Trailing whitespace
8+
# E128: Continuation line under-indented for visual indent
9+
# E126: Continuation line over-indented for hanging indent
10+
# E127: Continuation line over-indented for visual indent
11+
# W503: Line break occurred before a binary operator
12+
# E266: Too many leading '#' for block comment
13+
ignore = E501, W291, E128, E126, E127, W503, E266, W605, C901
14+
15+
# Exclude some directories from checking
16+
exclude =
17+
.git,
18+
__pycache__,
19+
build,
20+
dist,
21+
.venv
22+
23+
24+
# Maximum allowed complexity for functions
25+
max-complexity = 10

.github/workflows/ci.yml

+71-47
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,77 @@
1-
stages:
2-
- lint
3-
- test
4-
- build
5-
- deploy
1+
name: CI/CD Pipeline
62

7-
variables:
8-
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
98

10-
cache:
11-
paths:
12-
- .pip-cache/
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
- name: Set up Python
15+
uses: actions/setup-python@v2
16+
with:
17+
python-version: 3.9
18+
- name: Install dependencies
19+
run: |
20+
python -m pip install --upgrade pip
21+
pip install flake8
22+
- name: Lint with flake8
23+
run: flake8 .
1324

14-
lint:
15-
stage: lint
16-
image: python:3.9
17-
before_script:
18-
- pip install flake8
19-
script:
20-
- flake8 .
21-
22-
test:
23-
stage: test
24-
image: python:3.9
25-
before_script:
26-
- pip install -r requirements.txt
27-
- pip install pytest pytest-cov
28-
script:
29-
- pytest tests/ --cov=./ --cov-report=xml
30-
artifacts:
31-
reports:
32-
coverage_report:
33-
coverage_format: cobertura
25+
test:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v2
29+
- name: Set up Python
30+
uses: actions/setup-python@v2
31+
with:
32+
python-version: 3.9
33+
- name: Install dependencies
34+
run: |
35+
python -m pip install --upgrade pip
36+
pip install -r requirements.txt
37+
pip install pytest pytest-cov
38+
- name: List directory contents
39+
run: ls -R
40+
- name: Run tests
41+
run: pytest tests/ -v --cov=./ --cov-report=xml
42+
- name: Upload coverage report
43+
uses: actions/upload-artifact@v2
44+
with:
45+
name: coverage-report
3446
path: coverage.xml
3547

36-
build:
37-
stage: build
38-
image: python:3.9
39-
script:
40-
- pip install pyinstaller
41-
- pyinstaller --onefile main.py
42-
artifacts:
43-
paths:
44-
- dist/main
48+
build:
49+
runs-on: ubuntu-latest
50+
needs: [lint, test]
51+
steps:
52+
- uses: actions/checkout@v2
53+
- name: Set up Python
54+
uses: actions/setup-python@v2
55+
with:
56+
python-version: 3.9
57+
- name: Install dependencies
58+
run: |
59+
python -m pip install --upgrade pip
60+
pip install pyinstaller
61+
- name: Build executable
62+
run: pyinstaller --onefile main.py
63+
- name: Upload artifact
64+
uses: actions/upload-artifact@v2
65+
with:
66+
name: abap-code-scanner
67+
path: dist/main
4568

46-
deploy:
47-
stage: deploy
48-
image: python:3.9
49-
script:
50-
- echo "Deploying application..."
51-
# Add your deployment steps here
52-
only:
53-
- main # This job will only run on the main branch
69+
deploy:
70+
runs-on: ubuntu-latest
71+
needs: build
72+
if: github.ref == 'refs/heads/main'
73+
steps:
74+
- name: Deploy application
75+
run: |
76+
echo "Deploying application..."
77+
# Add your deployment steps here

checks/CheckAbapOutgoingFtpConn.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
# checks/check_abap_outgoing_ftp_conn.py
1+
# checks/CheckAbapOutgoingFtpConn.py
22

33
import re
44
from dataclasses import dataclass
55
from typing import List
66

7+
78
@dataclass
89
class CheckResult:
910
line_number: int
1011
line_content: str
1112

13+
1214
class CheckAbapOutgoingFtpConn:
1315
title = "Outgoing FTP Connection"
16+
confidence = "Definitive"
1417
severity = "Low"
1518
vulnerability_type = "Unencrypted Communications"
1619

@@ -26,4 +29,3 @@ def run(self, file_content: str) -> List[CheckResult]:
2629
line_number = file_content[:match.start()].count('\n') + 1
2730
return [CheckResult(line_number, match.group().strip())]
2831
return []
29-

checks/CheckCallTransformation.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from dataclasses import dataclass
33
from typing import List
44

5+
56
@dataclass
67
class CheckResult:
78
line_number: int
89
line_content: str
910

11+
1012
class CheckCallTransformation:
1113
title = "XML Injection via \"CALL TRANSFORMATION\""
1214
severity = "High"

checks/CheckCrossSiteScripting.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from dataclasses import dataclass
55
from typing import List, Dict
66

7+
78
@dataclass
89
class CheckResult:
910
line_number: int
1011
line_content: str
1112

13+
1214
class CheckCrossSiteScripting:
1315
title = "Potential Cross-Site Scripting vulnerability"
1416
severity = "High"
@@ -60,4 +62,4 @@ def run(self, file_content: str) -> List[CheckResult]:
6062
results.append(CheckResult(i, line.strip()))
6163
break # Stop searching after finding the first vulnerability in the line
6264

63-
return results
65+
return results

checks/CheckDangerousAbapCommands.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from dataclasses import dataclass
55
from typing import List
66

7+
78
@dataclass
89
class CheckResult:
910
line_number: int
1011
line_content: str
1112

13+
1214
class CheckDangerousAbapCommands:
1315
title = "Dangerous ABAP statements"
1416
severity = "Medium"

checks/CheckDeleteDynpro.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from dataclasses import dataclass
33
from typing import List
44

5+
56
@dataclass
67
class CheckResult:
78
line_number: int
89
line_content: str
910

11+
1012
class CheckDeleteDynpro:
1113
title = "Critical actions via deleting a screen"
1214
severity = "High"

checks/CheckDirectoryTraversalCRstrbReadBuffered.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from dataclasses import dataclass
33
from typing import List
44

5+
56
@dataclass
67
class CheckResult:
78
line_number: int
89
line_content: str
910

11+
1012
class CheckDirectoryTraversalCRstrbReadBuffered:
1113
title = "Path Traversal - CALL C_RSTRB_READ_BUFFERED"
1214
severity = "Medium"
@@ -23,4 +25,4 @@ def run(self, file_content: str) -> List[CheckResult]:
2325
if self.pattern2.search(call_statement):
2426
line_number = file_content[:match1.start()].count('\n') + 1
2527
results.append(CheckResult(line_number, call_statement.strip()))
26-
return results
28+
return results

checks/CheckDirectoryTraversalCallAlerts.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from dataclasses import dataclass
33
from typing import List
44

5+
56
@dataclass
67
class CheckResult:
78
line_number: int
89
line_content: str
910

11+
1012
class CheckDirectoryTraversalCallAlerts:
1113
title = "Path Traversal - CALL ALERTS"
1214
severity = "Medium"
@@ -23,4 +25,4 @@ def run(self, file_content: str) -> List[CheckResult]:
2325
if self.pattern2.search(call_statement):
2426
line_number = file_content[:match1.start()].count('\n') + 1
2527
results.append(CheckResult(line_number, call_statement.strip()))
26-
return results
28+
return results

checks/CheckDirectoryTraversalDeleteDataset.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import re
44
from dataclasses import dataclass
55
from typing import List
6-
from enum import Enum
6+
77

88
@dataclass
99
class CheckResult:
1010
line_number: int
1111
line_content: str
1212

13+
1314
class CheckDirectoryTraversalDeleteDataset:
1415
title = "Path Traversal - DELETE DATASET"
1516
severity = "HIGH"

checks/CheckDirectoryTraversalReadDataset.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import re
44
from dataclasses import dataclass
55
from typing import List
6-
from enum import Enum
6+
77

88
@dataclass
99
class CheckResult:
1010
line_number: int
1111
line_content: str
1212

13+
1314
class CheckDirectoryTraversalReadDataset:
1415
title = "Path Traversal - READ DATASET"
1516
severity = "HIGH"

checks/CheckDirectoryTraversalRfcRemoteFile.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
import re
44
from dataclasses import dataclass
55
from typing import List
6-
from enum import Enum
6+
77

88
@dataclass
99
class CheckResult:
1010
line_number: int
1111
line_content: str
1212

13+
1314
class CheckDirectoryTraversalRfcRemoteFile:
1415
title = "Potential Path Traversal detected - RFC_REMOTE_FILE"
1516
severity = "HIGH"
1617
vulnerability_type = "Path Traversal"
1718

18-
1919
def __init__(self):
2020
self.main_pattern = re.compile(
2121
r"(?ims)^[\s]*(\bCALL FUNCTION\b)(.+?\.)",

checks/CheckDirectoryTraversalTransfer.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22
from dataclasses import dataclass
33
from typing import List
44

5+
56
@dataclass
67
class CheckResult:
78
line_number: int
89
line_content: str
910

11+
1012
class CheckDirectoryTraversalTransfer:
1113
title = "Directory traversal via \"TRANSFER\" statement"
1214
severity = "High"
1315
vulnerability_type = "Directory Traversal"
1416

1517
def __init__(self):
16-
self.transfer_pattern = re.compile(r'(^\s*|\.\s*)TRANSFER\s+[\S]+\s+TO\s+(\w+)\.?', re.IGNORECASE | re.MULTILINE)
18+
self.transfer_pattern = re.compile(r'(^\s*|\.\s*)TRANSFER\s+[\S]+\s+TO\s+(\w+)\.?',
19+
re.IGNORECASE | re.MULTILINE)
1720
self.validation_pattern = re.compile(r'CALL\s+FUNCTION\s+(\'|\`)FILE_VALIDATE_NAME(\'|\`)', re.IGNORECASE)
18-
self.subrc_check_pattern = re.compile(r'(IF\s+sy(st)?-subrc\s*(=|EQ)\s*0|CHECK\s+sy(st)?-subrc\s*(=|EQ)\s*0)', re.IGNORECASE)
21+
self.subrc_check_pattern = re.compile(r'(IF\s+sy(st)?-subrc\s*(=|EQ)\s*0|CHECK\s+sy(st)?-subrc\s*(=|EQ)\s*0)',
22+
re.IGNORECASE)
1923

2024
def run(self, file_content: str) -> List[CheckResult]:
2125
results = []
@@ -30,7 +34,8 @@ def run(self, file_content: str) -> List[CheckResult]:
3034

3135
def is_filename_validated(self, file_content: str, filename_var: str) -> bool:
3236
# Check if FILE_VALIDATE_NAME is called with the filename variable
33-
validation_call = re.search(rf'CALL\s+FUNCTION\s+(\'|\`)FILE_VALIDATE_NAME(\'|\`).*?{filename_var}', file_content, re.IGNORECASE | re.DOTALL)
37+
validation_call = re.search(rf'CALL\s+FUNCTION\s+(\'|\`)FILE_VALIDATE_NAME(\'|\`).*?{filename_var}',
38+
file_content, re.IGNORECASE | re.DOTALL)
3439
if validation_call:
3540
# Check if there's a proper subrc check after the validation
3641
validation_pos = validation_call.start()

checks/CheckDosInDoLoop.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import re
22
from dataclasses import dataclass
33
from typing import List
4-
from enum import Enum
4+
55

66
@dataclass
77
class CheckResult:
88
line_number: int
99
line_content: str
1010

11+
1112
class CheckDosInDoLoop:
1213
title = "Denial of Service (DOS) in do/enddo loop."
1314
severity = "Medium"
@@ -25,4 +26,3 @@ def run(self, file_content: str) -> List[CheckResult]:
2526
line_number = file_content[:match.start()].count('\n') + 1
2627
results.append(CheckResult(line_number, match.group().strip()))
2728
return results
28-

0 commit comments

Comments
 (0)