@@ -48,7 +48,7 @@ def handle_bad_request(e):
48
48
@app .route ("/" )
49
49
def index ():
50
50
if project := request .args .get ("project" ):
51
- return redirect (f"/project/{ project } " )
51
+ return redirect (f"/project/{ project } " )
52
52
return render_template ("index.html" )
53
53
54
54
@@ -78,7 +78,7 @@ def versions(project_name):
78
78
def distributions (project_name , version ):
79
79
resp = requests .get (f"https://pypi.org/pypi/{ project_name } /{ version } /json" )
80
80
if resp .status_code != 200 :
81
- return redirect (f"/project/{ project_name } /" )
81
+ return redirect (f"/project/{ project_name } /" )
82
82
83
83
dist_urls = [
84
84
"." + urllib .parse .urlparse (url ["url" ]).path + "/"
@@ -200,22 +200,47 @@ def distribution(project_name, version, first, second, rest, distname):
200
200
return "Distribution type not supported"
201
201
202
202
203
+ def mailto_report_link (project_name , version , file_path , request_url ):
204
+ """
205
+ Generate a mailto report link for malicious code.
206
+ """
207
+ message_body = (
208
+ "PyPI Malicious Package Report\n "
209
+ "--\n "
210
+ f"Package Name: { project_name } \n "
211
+ f"Version: { version } \n "
212
+ f"File Path: { file_path } \n "
213
+ f"Inspector URL: { request_url } \n \n "
214
+ "Additional Information:\n \n "
215
+ )
216
+
217
+ subject = f"Malicious Package Report: { project_name } "
218
+
219
+ return (
220
+ f"mailto:security@pypi.org?"
221
+ f"subject={ urllib .parse .quote (subject )} "
222
+ f"&body={ urllib .parse .quote (message_body )} "
223
+ )
224
+
225
+
203
226
@app .route (
204
227
"/project/<project_name>/<version>/packages/<first>/<second>/<rest>/<distname>/<path:filepath>" # noqa
205
228
)
206
229
def file (project_name , version , first , second , rest , distname , filepath ):
207
230
dist = _get_dist (first , second , rest , distname )
208
-
209
231
if dist :
210
232
try :
211
233
contents = dist .contents (filepath )
212
234
except UnicodeDecodeError :
213
235
return "Binary files are not supported"
214
236
except FileNotFoundError :
215
237
return abort (404 )
238
+
239
+ report_link = mailto_report_link (project_name , version , filepath , request .url )
216
240
return render_template (
217
241
"code.html" ,
218
242
code = contents ,
243
+ mailto_report_link = report_link ,
219
244
h2 = f"{ project_name } " ,
220
245
h2_link = f"/project/{ project_name } " ,
221
246
h2_paren = "View this project on PyPI" ,
0 commit comments