Skip to content

Commit 9f696c4

Browse files
committed
feat: restructure TASVS to TCASVS v1.0 (ASVS 5.0.0 format)
- Migrate 79 requirements across 6 chapters to ASVS 5.0.0 format (132 total) - Add 73 gap-fill requirements for thick-client threat coverage - Create versioned directory layout (1.0/en/) with 0x-prefix file naming - Add Source column to all requirement tables (TASVS vs New) - Add build tooling: parser, JSON/CSV/CycloneDX export, Makefile - Add CI pipeline (.github/workflows/main.yml) - Add full traceability mapping (mappings/mapping_tasvs_to_tcasvs_v1.0.yml) - Archive original TASVS content (archive/1.0-original-tasvs/) - Include MIGRATION-SUMMARY.md with Mermaid diagram and stats
1 parent 2f2db99 commit 9f696c4

50 files changed

Lines changed: 3786 additions & 104 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Bug Report
2+
description: Report an error or inconsistency in the standard
3+
labels: ["bug"]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for taking the time to report an issue with the TCASVS.
9+
- type: input
10+
id: location
11+
attributes:
12+
label: Location
13+
description: Which chapter, section, or requirement ID is affected?
14+
placeholder: "e.g., V3.2.1 or 0x12-V3-Data-Storage-and-Protection.md"
15+
validations:
16+
required: true
17+
- type: textarea
18+
id: description
19+
attributes:
20+
label: Description
21+
description: Describe the issue clearly.
22+
placeholder: What is wrong and what should it say instead?
23+
validations:
24+
required: true
25+
- type: dropdown
26+
id: type
27+
attributes:
28+
label: Issue type
29+
options:
30+
- Incorrect requirement text
31+
- Missing CWE mapping
32+
- Incorrect level assignment
33+
- Formatting/layout issue
34+
- Broken link
35+
- Other
36+
validations:
37+
required: true

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: OWASP Slack
4+
url: https://owasp.slack.com
5+
about: Join the OWASP Slack workspace to discuss the TCASVS with the community
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: New Requirement Proposal
2+
description: Propose a new security requirement for inclusion in the TCASVS
3+
labels: ["enhancement", "new-requirement"]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Use this template to propose a new requirement. Please provide enough context for the working group to evaluate the proposal.
9+
- type: input
10+
id: chapter
11+
attributes:
12+
label: Target Chapter
13+
description: Which chapter should this requirement belong to?
14+
placeholder: "e.g., V3 Data Storage and Protection"
15+
validations:
16+
required: true
17+
- type: textarea
18+
id: requirement
19+
attributes:
20+
label: Proposed Requirement
21+
description: Write the requirement in TCASVS format (start with "Verify that...").
22+
placeholder: "Verify that the application..."
23+
validations:
24+
required: true
25+
- type: dropdown
26+
id: level
27+
attributes:
28+
label: Suggested Level
29+
description: At which verification level should this apply?
30+
options:
31+
- L1 (all applications)
32+
- L2 (sensitive data)
33+
- L3 (high security)
34+
validations:
35+
required: true
36+
- type: textarea
37+
id: rationale
38+
attributes:
39+
label: Rationale
40+
description: Why is this requirement needed? Reference attack scenarios, CWEs, or real-world incidents.
41+
validations:
42+
required: true
43+
- type: input
44+
id: cwe
45+
attributes:
46+
label: CWE Mapping
47+
description: Related CWE ID(s) if known.
48+
placeholder: "e.g., CWE-312"

.github/workflows/main.yml

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,121 @@
1-
name: Convert Markdown to PDF and Create Release
1+
name: Build and Release TCASVS
22

33
on:
44
push:
55
branches:
66
- main
7+
paths:
8+
- '1.0/en/**'
9+
- '1.0/tools/**'
10+
- '1.0/Makefile'
711

812
jobs:
913
build:
1014
runs-on: ubuntu-latest
1115

1216
steps:
1317
- name: Checkout repository
14-
uses: actions/checkout@v6
18+
uses: actions/checkout@v4
1519

16-
- name: Set up Pandoc and jq
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: '3.12'
24+
25+
- name: Install system dependencies
1726
run: |
1827
sudo apt-get update
19-
sudo apt-get install -y pandoc texlive jq
28+
sudo apt-get install -y pandoc texlive-xetex texlive-fonts-recommended jq
29+
30+
- name: Install Python dependencies
31+
run: pip install dicttoxml2
32+
33+
- name: Verify requirements parse correctly
34+
working-directory: 1.0
35+
run: |
36+
python tools/export.py --verify-only --format json --language en
37+
python tools/export.py --verify-only --format csv --language en
2038
21-
- name: Fetch the latest release
39+
- name: Build all exports
40+
working-directory: 1.0
41+
run: make all
42+
43+
- name: Fetch the latest release tag
2244
id: fetch_latest_release
2345
run: |
2446
LATEST_TAG=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name)
2547
if [ -z "$LATEST_TAG" ] || [ "$LATEST_TAG" == "null" ]; then
26-
LATEST_TAG="v0.4.0"
27-
fi
28-
# using this to fake/bump versions to v1.0
29-
if [ "$LATEST_TAG" == "v0.4.0" ]; then
30-
LATEST_TAG="v1.0"
48+
LATEST_TAG="v1.0.0"
3149
fi
3250
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV
3351
3452
- name: Increment version
3553
id: increment_version
3654
run: |
3755
LATEST_TAG=${{ env.LATEST_TAG }}
38-
echo "Latest tag: $LATEST_TAG"
3956
LATEST_VERSION=${LATEST_TAG#v}
40-
IFS='.' read -r major minor <<< "$LATEST_VERSION"
41-
NEW_VERSION="$major.$((minor + 1))"
57+
IFS='.' read -r major minor patch <<< "$LATEST_VERSION"
58+
NEW_VERSION="$major.$minor.$((patch + 1))"
4259
NEW_TAG="v$NEW_VERSION"
43-
echo "New version: $NEW_TAG"
4460
echo "NEW_TAG=$NEW_TAG" >> $GITHUB_ENV
4561
46-
- name: Concatenate and Convert Markdown to PDF
47-
run: |
48-
pandoc document/1.0/*.md -o TASVS-${{ env.NEW_TAG }}.pdf -V geometry:margin=2cm
49-
5062
- name: Create GitHub Release
5163
id: create_release
5264
uses: actions/create-release@v1
5365
env:
5466
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5567
with:
5668
tag_name: ${{ env.NEW_TAG }}
57-
release_name: Release ${{ env.NEW_TAG }}
69+
release_name: TCASVS ${{ env.NEW_TAG }}
5870
draft: false
5971
prerelease: false
6072

61-
- name: Upload PDF to Release
73+
- name: Upload PDF
6274
uses: actions/upload-release-asset@v1
6375
env:
6476
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6577
with:
6678
upload_url: ${{ steps.create_release.outputs.upload_url }}
67-
asset_path: ./TASVS-${{ env.NEW_TAG }}.pdf
68-
asset_name: TASVS-${{ env.NEW_TAG }}.pdf
79+
asset_path: ./1.0/dist/OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_en.pdf
80+
asset_name: TCASVS-${{ env.NEW_TAG }}.pdf
6981
asset_content_type: application/pdf
82+
83+
- name: Upload DOCX
84+
uses: actions/upload-release-asset@v1
85+
env:
86+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
87+
with:
88+
upload_url: ${{ steps.create_release.outputs.upload_url }}
89+
asset_path: ./1.0/dist/OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_en.docx
90+
asset_name: TCASVS-${{ env.NEW_TAG }}.docx
91+
asset_content_type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
92+
93+
- name: Upload JSON
94+
uses: actions/upload-release-asset@v1
95+
env:
96+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
97+
with:
98+
upload_url: ${{ steps.create_release.outputs.upload_url }}
99+
asset_path: ./1.0/dist/OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_en.json
100+
asset_name: TCASVS-${{ env.NEW_TAG }}.json
101+
asset_content_type: application/json
102+
103+
- name: Upload CSV
104+
uses: actions/upload-release-asset@v1
105+
env:
106+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107+
with:
108+
upload_url: ${{ steps.create_release.outputs.upload_url }}
109+
asset_path: ./1.0/dist/OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_en.csv
110+
asset_name: TCASVS-${{ env.NEW_TAG }}.csv
111+
asset_content_type: text/csv
112+
113+
- name: Upload CycloneDX
114+
uses: actions/upload-release-asset@v1
115+
env:
116+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117+
with:
118+
upload_url: ${{ steps.create_release.outputs.upload_url }}
119+
asset_path: ./1.0/dist/OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_en.cdx.json
120+
asset_name: TCASVS-${{ env.NEW_TAG }}.cdx.json
121+
asset_content_type: application/json

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
/Gemfile
22
/Gemfile.lock
33
/favicon.ico
4-
_site/
4+
_site/
5+
__pycache__/
6+
*.pyc

.markdownlint.jsonc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"default": true,
3+
"MD013": {
4+
"line_length": 500,
5+
"tables": false
6+
},
7+
"MD024": {
8+
"siblings_only": true
9+
},
10+
"MD033": {
11+
"allowed_elements": [
12+
"a",
13+
"img",
14+
"div",
15+
"b",
16+
"sup",
17+
"u",
18+
"br"
19+
]
20+
},
21+
"MD041": false
22+
}

1.0/Makefile

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# TCASVS Build System
2+
# Generates PDF, DOCX, JSON, CSV, XML, and CycloneDX outputs from source Markdown.
3+
4+
PROJDIR := $(realpath $(CURDIR))
5+
TOOLSDIR := tools
6+
TEMPLATEDIR := templates
7+
SOURCEDIR := en
8+
BUILDDIR := build
9+
DISTDIR := dist
10+
11+
TARGETNAME := OWASP_Thick_Client_Application_Security_Verification_Standard_1.0.0_
12+
13+
# Source files
14+
SOURCE_FILES := $(sort $(wildcard $(SOURCEDIR)/0x*.md $(SOURCEDIR)/0x*.yaml))
15+
BUILD_FILES := $(patsubst $(SOURCEDIR)/%, $(BUILDDIR)/%, $(SOURCE_FILES))
16+
17+
# Output targets
18+
MD_FILE := $(DISTDIR)/$(TARGETNAME)en.md
19+
PDF_FILE := $(DISTDIR)/$(TARGETNAME)en.pdf
20+
DOCX_FILE := $(DISTDIR)/$(TARGETNAME)en.docx
21+
JSON_FILE := $(DISTDIR)/$(TARGETNAME)en.json
22+
JSON_FLAT_FILE := $(DISTDIR)/$(TARGETNAME)en.flat.json
23+
CSV_FILE := $(DISTDIR)/$(TARGETNAME)en.csv
24+
XML_FILE := $(DISTDIR)/$(TARGETNAME)en.xml
25+
CDX_FILE := $(DISTDIR)/$(TARGETNAME)en.cdx.json
26+
27+
EXPORT_TOOL := $(TOOLSDIR)/export.py
28+
29+
# Pandoc flags
30+
PANDOC_PDF_FLAGS := -f markdown -s -t latex --pdf-engine=xelatex
31+
PANDOC_DOCX_FLAGS := -s -t docx -f markdown --toc --columns 10000 \
32+
--reference-doc=$(TEMPLATEDIR)/reference.docx
33+
34+
.PHONY: all pdf docx json json_flat csv xml cdx_json md clean verify
35+
36+
all: md pdf docx json json_flat csv xml cdx_json
37+
38+
$(BUILDDIR):
39+
mkdir -p $@
40+
41+
$(DISTDIR):
42+
mkdir -p $@
43+
44+
# Transform source MD (add CWE hyperlinks, fix image paths)
45+
$(BUILDDIR)/%.md: $(SOURCEDIR)/%.md | $(BUILDDIR)
46+
sed -E 's#(\| ?)([0-9]{2,4})( ?\|)#\1[\2](https://cwe.mitre.org/data/definitions/\2.html)\3#g' $< > $@
47+
48+
$(BUILDDIR)/%.yaml: $(SOURCEDIR)/%.yaml | $(BUILDDIR)
49+
cp $< $@
50+
51+
# Merged Markdown
52+
md: $(MD_FILE)
53+
$(MD_FILE): $(BUILD_FILES) | $(DISTDIR)
54+
pandoc -f gfm -s -t markdown -o $@ $(BUILDDIR)/0x*.md
55+
56+
# PDF via LaTeX
57+
pdf: $(PDF_FILE)
58+
$(PDF_FILE): $(BUILD_FILES) | $(DISTDIR)
59+
pandoc $(PANDOC_PDF_FLAGS) \
60+
--include-in-header=$(TEMPLATEDIR)/header-eisvogel.tex \
61+
-o $@ --template $(TEMPLATEDIR)/eisvogel.tex \
62+
$(BUILDDIR)/0x*.md $(SOURCEDIR)/0x00-Header.yaml
63+
64+
# DOCX
65+
docx: $(DOCX_FILE)
66+
$(DOCX_FILE): $(BUILD_FILES) | $(DISTDIR)
67+
pandoc $(PANDOC_DOCX_FLAGS) -o $@ $(BUILDDIR)/0x*.md $(SOURCEDIR)/0x00-Header.yaml
68+
69+
# Structured exports via Python
70+
json: $(JSON_FILE)
71+
$(JSON_FILE): $(SOURCE_FILES) | $(DISTDIR)
72+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --format json --language $(SOURCEDIR) > $@
73+
74+
json_flat: $(JSON_FLAT_FILE)
75+
$(JSON_FLAT_FILE): $(SOURCE_FILES) | $(DISTDIR)
76+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --format json_flat --language $(SOURCEDIR) > $@
77+
78+
csv: $(CSV_FILE)
79+
$(CSV_FILE): $(SOURCE_FILES) | $(DISTDIR)
80+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --format csv --language $(SOURCEDIR) > $@
81+
82+
xml: $(XML_FILE)
83+
$(XML_FILE): $(SOURCE_FILES) | $(DISTDIR)
84+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --format xml --language $(SOURCEDIR) > $@
85+
86+
cdx_json: $(CDX_FILE)
87+
$(CDX_FILE): $(SOURCE_FILES) | $(DISTDIR)
88+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --format cdx_json --language $(SOURCEDIR) > $@
89+
90+
# Verification
91+
verify: $(SOURCE_FILES)
92+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --verify-only --format json --language $(SOURCEDIR)
93+
cd $(PROJDIR) && python3 $(EXPORT_TOOL) --verify-only --format csv --language $(SOURCEDIR)
94+
95+
# Clean
96+
clean:
97+
rm -rf $(BUILDDIR) $(DISTDIR)

1.0/docs_en/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Compiled Outputs
2+
3+
This directory contains auto-generated output files for the TCASVS standard.
4+
5+
## Available Formats
6+
7+
The following formats are generated by the CI pipeline and attached to GitHub Releases:
8+
9+
- **PDF** — Paginated document for offline reading
10+
- **DOCX** — Editable Word format for review workflows
11+
- **CSV** — Flat requirement list for spreadsheet tooling
12+
- **JSON** — Machine-readable structured export
13+
- **CycloneDX JSON** — SBOM-compatible requirement representation
14+
15+
## Generating Locally
16+
17+
```bash
18+
cd ../
19+
make
20+
```
21+
22+
Output files will be placed in `dist/`. See [COMPILING.md](../../COMPILING.md) for full instructions.
23+
24+
## Note
25+
26+
Do not commit generated files to this directory manually. They are produced by the `main.yml` GitHub Actions workflow and published as release artifacts.

0 commit comments

Comments
 (0)