Skip to content

Commit fa18388

Browse files
msureshkumar88Suresh Kumar Moharajan
andauthored
feat(security): add MIME type restrictions for resources (US-2) (#3847)
Add content security validation for MIME types on resources: - ContentSecurityService.validate_resource_mime_type() with configurable allowlist (CONTENT_ALLOWED_RESOURCE_MIMETYPES) and strict/log-only modes (CONTENT_STRICT_MIME_VALIDATION, default: false) - Log-only mode checks the allowlist and logs violations at WARNING level with Prometheus metrics, enabling monitoring before enforcement - ContentTypeError exception with HTTP 415 global handler - URL-detected MIME type priority over user-provided values - Prometheus counters for size and MIME type violations - PII-safe audit logging (hashed emails, masked IPs) - Validation in register_resource, update_resource (including MIME-only updates without content changes), and bulk import Partially closes #538 Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Co-authored-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
1 parent 9348c8f commit fa18388

18 files changed

Lines changed: 2017 additions & 225 deletions

.env.example

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ ALLOW_PUBLIC_VISIBILITY=true
9898
# The 100.64.0.0/10 range is Carrier-Grade NAT (CGNAT) which some cloud providers use
9999

100100
# -----------------------------------------------------------------------------
101-
# Content Security - Size Limits
101+
# Content Security - Size Limits and MIME Type Restrictions (US-2)
102102
# -----------------------------------------------------------------------------
103103
# Maximum content sizes (in bytes) to prevent DoS attacks via large uploads
104104

@@ -110,6 +110,19 @@ ALLOW_PUBLIC_VISIBILITY=true
110110
# Prompts exceeding this limit will be rejected with 413 Payload Too Large
111111
# CONTENT_MAX_PROMPT_SIZE=10240
112112

113+
# Allowed MIME types for resources (JSON array or comma-separated list)
114+
# In strict mode, only MIME types explicitly listed here are accepted.
115+
# Vendor types (application/x-*, text/x-*) and suffix types (+json, +xml) must be
116+
# explicitly added to this list if needed - they are NOT automatically allowed.
117+
# Default: text/plain,text/markdown,text/html,text/csv,application/json,application/xml,application/pdf,...
118+
# Both formats are accepted:
119+
# CONTENT_ALLOWED_RESOURCE_MIMETYPES=["text/plain","text/markdown","application/json"]
120+
# CONTENT_ALLOWED_RESOURCE_MIMETYPES=text/plain,text/markdown,application/json
121+
122+
# Enable strict MIME type validation for resources (default: false)
123+
# Set to true to reject disallowed MIME types; false logs violations without blocking
124+
# CONTENT_STRICT_MIME_VALIDATION=false
125+
113126
# =============================================================================
114127
# Project defaults (batteries-included overrides)
115128
# =============================================================================

.secrets.baseline

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": "package-lock.json|Cargo.lock|^.secrets.baseline$|scripts/sign_image.sh|scripts/zap|sonar-project.properties|^/Users/brian/dev/github.ibm.com/contextforge-org/sps-pipeline-config/.secrets.baseline$|^./.secrets.baseline$",
44
"lines": null
55
},
6-
"generated_at": "2026-04-03T10:38:44Z",
6+
"generated_at": "2026-04-03T11:21:02Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -92,87 +92,87 @@
9292
"hashed_secret": "08cd923367890009657eab812753379bdb321eeb",
9393
"is_secret": false,
9494
"is_verified": false,
95-
"line_number": 509,
95+
"line_number": 522,
9696
"type": "Basic Auth Credentials",
9797
"verified_result": null
9898
},
9999
{
100100
"hashed_secret": "14f8aa3e560a47851908ab0f04ec856dbc512d93",
101101
"is_secret": false,
102102
"is_verified": false,
103-
"line_number": 704,
103+
"line_number": 717,
104104
"type": "Secret Keyword",
105105
"verified_result": null
106106
},
107107
{
108108
"hashed_secret": "fa9beb99e4029ad5a6615399e7bbae21356086b3",
109109
"is_secret": false,
110110
"is_verified": false,
111-
"line_number": 964,
111+
"line_number": 977,
112112
"type": "Secret Keyword",
113113
"verified_result": null
114114
},
115115
{
116116
"hashed_secret": "7b4455a56fbf1d198e45e04c437488514645a82c",
117117
"is_secret": false,
118118
"is_verified": false,
119-
"line_number": 990,
119+
"line_number": 1003,
120120
"type": "Secret Keyword",
121121
"verified_result": null
122122
},
123123
{
124124
"hashed_secret": "ac371b6dcce28a86c90d12bc57d946a800eebf17",
125125
"is_secret": false,
126126
"is_verified": false,
127-
"line_number": 1070,
127+
"line_number": 1083,
128128
"type": "Secret Keyword",
129129
"verified_result": null
130130
},
131131
{
132132
"hashed_secret": "0b6ec68df700dec4dcd64babd0eda1edccddace1",
133133
"is_secret": false,
134134
"is_verified": false,
135-
"line_number": 1075,
135+
"line_number": 1088,
136136
"type": "Secret Keyword",
137137
"verified_result": null
138138
},
139139
{
140140
"hashed_secret": "4ad6f0082ee224001beb3ca5c3e81c8ceea5ed86",
141141
"is_secret": false,
142142
"is_verified": false,
143-
"line_number": 1080,
143+
"line_number": 1093,
144144
"type": "Secret Keyword",
145145
"verified_result": null
146146
},
147147
{
148148
"hashed_secret": "cb32747fcfb55eaa194c8cd8e4ba7d49ada08a94",
149149
"is_secret": false,
150150
"is_verified": false,
151-
"line_number": 1086,
151+
"line_number": 1099,
152152
"type": "Secret Keyword",
153153
"verified_result": null
154154
},
155155
{
156156
"hashed_secret": "6c178d51b13520496dbc767ed3d9d7aa5803ac72",
157157
"is_secret": false,
158158
"is_verified": false,
159-
"line_number": 1098,
159+
"line_number": 1111,
160160
"type": "Secret Keyword",
161161
"verified_result": null
162162
},
163163
{
164164
"hashed_secret": "ca45060a53fd8a255d1a83ee8d2f025283ccc66e",
165165
"is_secret": false,
166166
"is_verified": false,
167-
"line_number": 1116,
167+
"line_number": 1129,
168168
"type": "Secret Keyword",
169169
"verified_result": null
170170
},
171171
{
172172
"hashed_secret": "910fbf00f58e9bcb095ea26a75cc1d9a3355e671",
173173
"is_secret": false,
174174
"is_verified": false,
175-
"line_number": 1177,
175+
"line_number": 1190,
176176
"type": "Secret Keyword",
177177
"verified_result": null
178178
}
@@ -1828,7 +1828,7 @@
18281828
"hashed_secret": "e689846dfc65621eeab3a906bb8b0ddd52f5c514",
18291829
"is_secret": false,
18301830
"is_verified": false,
1831-
"line_number": 130,
1831+
"line_number": 158,
18321832
"type": "Secret Keyword",
18331833
"verified_result": null
18341834
}
@@ -5110,7 +5110,7 @@
51105110
"hashed_secret": "85b60d811d16ff56b3654587d4487f713bfa33b7",
51115111
"is_secret": false,
51125112
"is_verified": false,
5113-
"line_number": 14931,
5113+
"line_number": 14976,
51145114
"type": "Secret Keyword",
51155115
"verified_result": null
51165116
}
@@ -5752,15 +5752,15 @@
57525752
"hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684",
57535753
"is_secret": false,
57545754
"is_verified": false,
5755-
"line_number": 221,
5755+
"line_number": 222,
57565756
"type": "Basic Auth Credentials",
57575757
"verified_result": null
57585758
},
57595759
{
57605760
"hashed_secret": "ff37a98a9963d347e9749a5c1b3936a4a245a6ff",
57615761
"is_secret": false,
57625762
"is_verified": false,
5763-
"line_number": 2140,
5763+
"line_number": 2169,
57645764
"type": "Secret Keyword",
57655765
"verified_result": null
57665766
}
@@ -6082,7 +6082,7 @@
60826082
"hashed_secret": "718cbcc5a4207c0d5f38e3a309bdba17cb0074b7",
60836083
"is_secret": false,
60846084
"is_verified": false,
6085-
"line_number": 3290,
6085+
"line_number": 3404,
60866086
"type": "Hex High Entropy String",
60876087
"verified_result": null
60886088
}
@@ -7380,7 +7380,7 @@
73807380
"hashed_secret": "ba9cdae9b74942b8ac45ec20dfc3803a07fe6de9",
73817381
"is_secret": false,
73827382
"is_verified": false,
7383-
"line_number": 58,
7383+
"line_number": 61,
73847384
"type": "Secret Keyword",
73857385
"verified_result": null
73867386
}
@@ -9854,23 +9854,23 @@
98549854
"hashed_secret": "b0beaa298b4c296ba29df08b919548d17e68d6c8",
98559855
"is_secret": false,
98569856
"is_verified": false,
9857-
"line_number": 3496,
9857+
"line_number": 4017,
98589858
"type": "Secret Keyword",
98599859
"verified_result": null
98609860
},
98619861
{
98629862
"hashed_secret": "f2b14f68eb995facb3a1c35287b778d5bd785511",
98639863
"is_secret": false,
98649864
"is_verified": false,
9865-
"line_number": 3511,
9865+
"line_number": 4032,
98669866
"type": "Secret Keyword",
98679867
"verified_result": null
98689868
},
98699869
{
98709870
"hashed_secret": "718cbcc5a4207c0d5f38e3a309bdba17cb0074b7",
98719871
"is_secret": false,
98729872
"is_verified": false,
9873-
"line_number": 4203,
9873+
"line_number": 4724,
98749874
"type": "Hex High Entropy String",
98759875
"verified_result": null
98769876
}
@@ -10212,119 +10212,119 @@
1021210212
"hashed_secret": "206c80413b9a96c1312cc346b7d2517b84463edd",
1021310213
"is_secret": false,
1021410214
"is_verified": false,
10215-
"line_number": 1600,
10215+
"line_number": 1604,
1021610216
"type": "Secret Keyword",
1021710217
"verified_result": null
1021810218
},
1021910219
{
1022010220
"hashed_secret": "5cbd0bf2db07a8f50fa9bbcc5ac720b1911c6380",
1022110221
"is_secret": false,
1022210222
"is_verified": false,
10223-
"line_number": 1772,
10223+
"line_number": 1776,
1022410224
"type": "Secret Keyword",
1022510225
"verified_result": null
1022610226
},
1022710227
{
1022810228
"hashed_secret": "a10b98d7340036e9c8c301704f623eddd733cc1a",
1022910229
"is_secret": false,
1023010230
"is_verified": false,
10231-
"line_number": 2736,
10231+
"line_number": 2781,
1023210232
"type": "Hex High Entropy String",
1023310233
"verified_result": null
1023410234
},
1023510235
{
1023610236
"hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f",
1023710237
"is_secret": false,
1023810238
"is_verified": false,
10239-
"line_number": 5148,
10239+
"line_number": 5189,
1024010240
"type": "Secret Keyword",
1024110241
"verified_result": null
1024210242
},
1024310243
{
1024410244
"hashed_secret": "fe1bae27cb7c1fb823f496f286e78f1d2ae87734",
1024510245
"is_secret": false,
1024610246
"is_verified": false,
10247-
"line_number": 5795,
10247+
"line_number": 5842,
1024810248
"type": "Secret Keyword",
1024910249
"verified_result": null
1025010250
},
1025110251
{
1025210252
"hashed_secret": "2878cbdbbcfa6feafc04b8889f5ecc8c470ba32e",
1025310253
"is_secret": false,
1025410254
"is_verified": false,
10255-
"line_number": 5859,
10255+
"line_number": 5906,
1025610256
"type": "Secret Keyword",
1025710257
"verified_result": null
1025810258
},
1025910259
{
1026010260
"hashed_secret": "a0281cd072cea8e80e7866b05dc124815760b6c9",
1026110261
"is_secret": false,
1026210262
"is_verified": false,
10263-
"line_number": 6111,
10263+
"line_number": 6158,
1026410264
"type": "Secret Keyword",
1026510265
"verified_result": null
1026610266
},
1026710267
{
1026810268
"hashed_secret": "a0f4ea7d91495df92bbac2e2149dfb850fe81396",
1026910269
"is_secret": false,
1027010270
"is_verified": false,
10271-
"line_number": 9086,
10271+
"line_number": 9140,
1027210272
"type": "Secret Keyword",
1027310273
"verified_result": null
1027410274
},
1027510275
{
1027610276
"hashed_secret": "a75a7c7b31474f3f04f3a395228ded8d61ee1ae3",
1027710277
"is_secret": false,
1027810278
"is_verified": false,
10279-
"line_number": 9135,
10279+
"line_number": 9189,
1028010280
"type": "Secret Keyword",
1028110281
"verified_result": null
1028210282
},
1028310283
{
1028410284
"hashed_secret": "02c593fd9af8254b859d426a76b6cd42847fbec1",
1028510285
"is_secret": false,
1028610286
"is_verified": false,
10287-
"line_number": 9174,
10287+
"line_number": 9228,
1028810288
"type": "Secret Keyword",
1028910289
"verified_result": null
1029010290
},
1029110291
{
1029210292
"hashed_secret": "1ded3053d0363079a4e681a3b700435d6d880290",
1029310293
"is_secret": false,
1029410294
"is_verified": false,
10295-
"line_number": 9231,
10295+
"line_number": 9285,
1029610296
"type": "Secret Keyword",
1029710297
"verified_result": null
1029810298
},
1029910299
{
1030010300
"hashed_secret": "c00dbbc9dadfbe1e232e93a729dd4752fade0abf",
1030110301
"is_secret": false,
1030210302
"is_verified": false,
10303-
"line_number": 14001,
10303+
"line_number": 14058,
1030410304
"type": "Secret Keyword",
1030510305
"verified_result": null
1030610306
},
1030710307
{
1030810308
"hashed_secret": "f2b14f68eb995facb3a1c35287b778d5bd785511",
1030910309
"is_secret": false,
1031010310
"is_verified": false,
10311-
"line_number": 16758,
10311+
"line_number": 16815,
1031210312
"type": "Secret Keyword",
1031310313
"verified_result": null
1031410314
},
1031510315
{
1031610316
"hashed_secret": "a4b48a81cdab1e1a5dd37907d6c85ca1c61ddc7c",
1031710317
"is_secret": false,
1031810318
"is_verified": false,
10319-
"line_number": 16777,
10319+
"line_number": 16834,
1032010320
"type": "Secret Keyword",
1032110321
"verified_result": null
1032210322
},
1032310323
{
1032410324
"hashed_secret": "dc8002865f92070749b264e76045b04fa3b8de71",
1032510325
"is_secret": false,
1032610326
"is_verified": false,
10327-
"line_number": 20332,
10327+
"line_number": 20389,
1032810328
"type": "Secret Keyword",
1032910329
"verified_result": null
1033010330
}
@@ -10698,23 +10698,23 @@
1069810698
"hashed_secret": "cd024c09e5784e941e833bd8fabf1dcfc3fb6cd8",
1069910699
"is_secret": false,
1070010700
"is_verified": false,
10701-
"line_number": 53,
10701+
"line_number": 54,
1070210702
"type": "Secret Keyword",
1070310703
"verified_result": null
1070410704
},
1070510705
{
1070610706
"hashed_secret": "718cbcc5a4207c0d5f38e3a309bdba17cb0074b7",
1070710707
"is_secret": false,
1070810708
"is_verified": false,
10709-
"line_number": 137,
10709+
"line_number": 138,
1071010710
"type": "Hex High Entropy String",
1071110711
"verified_result": null
1071210712
},
1071310713
{
1071410714
"hashed_secret": "a10b98d7340036e9c8c301704f623eddd733cc1a",
1071510715
"is_secret": false,
1071610716
"is_verified": false,
10717-
"line_number": 150,
10717+
"line_number": 151,
1071810718
"type": "Hex High Entropy String",
1071910719
"verified_result": null
1072010720
}
@@ -10724,7 +10724,7 @@
1072410724
"hashed_secret": "cd024c09e5784e941e833bd8fabf1dcfc3fb6cd8",
1072510725
"is_secret": false,
1072610726
"is_verified": false,
10727-
"line_number": 30,
10727+
"line_number": 35,
1072810728
"type": "Secret Keyword",
1072910729
"verified_result": null
1073010730
}

0 commit comments

Comments
 (0)