|
| 1 | +<!DOCTYPE html> |
| 2 | +<html> |
| 3 | +<head> |
| 4 | +<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | +<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css"> |
| 7 | +<link rel="stylesheet" href="checker.css"> |
| 8 | +<script src="js-yaml.min.js"></script> |
| 9 | +<script src="checker.js"></script> |
| 10 | +<link rel="license" href="https://creativecommons.org/licenses/by/4.0/"> |
| 11 | + |
| 12 | + |
| 13 | +<script id="expected0" type="plain/text"> |
| 14 | + return '{format_string}, {event.level}'.format(format_string=user_input, event=event) |
| 15 | +</script> |
| 16 | + |
| 17 | +<!-- Full pattern of correct answer --> |
| 18 | +<script id="correct0" type="plain/text"> |
| 19 | +\s*return\s'\{format_string\},\s\{event\.level\}'\.format\(format_string=user_input,\sevent=event\)\s* |
| 20 | +</script> |
| 21 | + |
| 22 | +<script id="info" type="application/yaml"> |
| 23 | +--- |
| 24 | +- absent: "user_input" |
| 25 | + text: Make sure the user_input is included in the replacement fields passed to the format function |
| 26 | + examples: |
| 27 | + - - "'some format'.format(user_input=user_input)" |
| 28 | + - - "'some format'.format(user_input)" |
| 29 | +- absent: "event" |
| 30 | + text: Make sure the event is included in the replacement fields passed to the format function |
| 31 | + examples: |
| 32 | + - - "'some format'.format(user_input=user_input, event=event)" |
| 33 | + - - "'some format'.format(user_input, event)" |
| 34 | +- absent: \{(0|format_string)\} |
| 35 | + text: Make sure the braces for the format_string replacement field are in the format string |
| 36 | + examples: |
| 37 | + - - "'{event}'.format(format_string=user_input)" |
| 38 | + - - "'{0}.format(user_input)" |
| 39 | +- absent: \{(1|event)\} |
| 40 | + text: Make sure the braces for the event replacement field are in the format string |
| 41 | + examples: |
| 42 | + - - "'{format_string}, {event.level}'.format(format_string=user_input, event=event)" |
| 43 | + - - "'{0}, {1.level}'.format(user_input, event)" |
| 44 | +- absent: \{(1\.level|event\.level)\} |
| 45 | + text: Make sure the level attribute of the event replacement field is in the format string |
| 46 | + examples: |
| 47 | + - - "'{format_string}, {event.level}'.format(format_string=user_input, event=event)" |
| 48 | + - - "'{0}, {1.level}'.format(user_input, event)" |
| 49 | +# debug: true |
| 50 | +</script> |
| 51 | +</head> |
| 52 | +<body> |
| 53 | +<!-- For GitHub Pages formatting: --> |
| 54 | +<div class="container-lg px-3 my-5 markdown-body"> |
| 55 | +<h1>Lab Exercise Format Strings and Templates</h1> |
| 56 | +<p> |
| 57 | +This is a lab exercise on developing secure software. |
| 58 | +For more information, see the <a href="introduction.html" target="_blank">introduction to |
| 59 | +the labs</a>. |
| 60 | + |
| 61 | +<p> |
| 62 | +<h2>Task</h2> |
| 63 | +<p> |
| 64 | +<b>Practice using string templates in a secure way.</b> |
| 65 | + |
| 66 | +<p> |
| 67 | +<h2>Background</h2> |
| 68 | +<p> |
| 69 | +In this exercise, we'll adjust our string formatting so that it doesn't allow a user to control |
| 70 | +the <a href="https://docs.python.org/3/tutorial/inputoutput.html#the-string-format-method"><tt> |
| 71 | +format string</tt></a>. If a user can control the <tt>format string</tt> they can access |
| 72 | +variables which they shouldn't. Particularly if those variable's values can be returned to the user |
| 73 | +as output, it could lead to information disclosure beyond what was intended by the developer. |
| 74 | + |
| 75 | +<p> |
| 76 | +<h2>Task Information</h2> |
| 77 | +<p> |
| 78 | + |
| 79 | +<p> |
| 80 | +Please change the code below so the string formatting cannot disclose arbitrary |
| 81 | +program values. The server-side program is written in Python and allows a user to specify a |
| 82 | +<tt>format string</tt> to control the output format of an event. |
| 83 | + |
| 84 | +<p> |
| 85 | +You could adjust the program so that it only formats the event, and does not include any user input, |
| 86 | +However it is considered safe to include user input in the output as long as they cannot control |
| 87 | +the <tt>format string</tt> itself. |
| 88 | + |
| 89 | +<p> |
| 90 | +Adjust the value returned by the <tt>format_event</tt> function so the the user controlled |
| 91 | +<tt>user_input</tt> variable is only used as a |
| 92 | +<a href="https://docs.python.org/3/library/string.html#format-string-syntax"><tt>replacement field</tt></a> |
| 93 | +and is not used as the <tt>format string</tt>. |
| 94 | + |
| 95 | +<p> |
| 96 | +Use the “hint” and “give up” buttons if necessary. |
| 97 | + |
| 98 | +<p> |
| 99 | +<h2>Interactive Lab (<span id="grade"></span>)</h2> |
| 100 | +<p> |
| 101 | +<form id="lab"> |
| 102 | +<pre><code |
| 103 | +> # Application configuration which should be kept secret from a user |
| 104 | +CONFIG = { |
| 105 | + 'SECRET_KEY': 'super secret key' |
| 106 | +} |
| 107 | + |
| 108 | +# A event object with a single attribute used by the malicious format string to gain access to the |
| 109 | +# secret application configuration below |
| 110 | +class Event(object): |
| 111 | + def __init__(self, level): |
| 112 | + self.level = level |
| 113 | + |
| 114 | +def format_event(user_input, event): |
| 115 | +<input id="attempt0" type="text" size="60" spellcheck="false" value=" return user_input.format(event=event)"> |
| 116 | + |
| 117 | +event = Event('level') |
| 118 | +format_event('{event.__init__.__globals__[CONFIG][SECRET_KEY]}', event) |
| 119 | +</code></pre> |
| 120 | +<button type="button" class="hintButton">Hint</button> |
| 121 | +<button type="button" class="resetButton">Reset</button> |
| 122 | +<button type="button" class="giveUpButton">Give up</button> |
| 123 | +<br><br> |
| 124 | +<p> |
| 125 | +<i>This lab was developed by Jason Shepherd at |
| 126 | +<a href="https://access.redhat.com" |
| 127 | +>Red Hat</a>.</i> with an modified version of the example code from Armin Ronacher's |
| 128 | +<a href="https://lucumr.pocoo.org/2016/12/29/careful-with-str-format/">Be Careful with Python's New-Style String Format</a> article. |
| 129 | +<br><br> |
| 130 | +<p id="correctStamp" class="small"> |
| 131 | +<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly> |
| 132 | +</textarea> |
| 133 | +</form> |
| 134 | +</div><!-- End GitHub pages formatting --> |
| 135 | +</body> |
| 136 | +</html> |
0 commit comments