| 93 | # Validate and process all the previous forms before instantiating the |
| 94 | # current step's form in case self.process_step makes changes to |
| 95 | # self.form_list. |
| 96 | |
| 97 | # If any of them fails validation, that must mean the validator relied |
| 98 | # on some other input, such as an external Web site. |
| 99 | |
| 100 | # It is also possible that alidation might fail under certain attack |
| 101 | # situations: an attacker might be able to bypass previous stages, and |
| 102 | # generate correct security hashes for all the skipped stages by virtue |
| 103 | # of: |
| 104 | # 1) having filled out an identical form which doesn't have the |
| 105 | # validation (and does something different at the end), |
| 106 | # 2) or having filled out a previous version of the same form which |
| 107 | # had some validation missing, |
| 108 | # 3) or previously having filled out the form when they had more |
| 109 | # privileges than they do now. |
| 110 | # |
| 111 | # Since the hashes only take into account values, and not other other |
| 112 | # validation the form might do, we must re-do validation now for |
| 113 | # security reasons. |
| 114 | previous_form_list = [] |
| 115 | for i in range(current_step): |
| 116 | f = self.get_form(i, request.POST) |
| 117 | if not self._check_security_hash(request.POST.get("hash_%d" % i, ''), |
| 118 | request, f): |
| 119 | return self.render_hash_failure(request, i) |
| 120 | |
| 121 | if not f.is_valid(): |
| 122 | return self.render_revalidation_failure(request, i, f) |
| 123 | else: |
| 124 | self.process_step(request, f, i) |
| 125 | previous_form_list.append(f) |
| 126 | |
101 | | # Validate all the forms. If any of them fail validation, that |
102 | | # must mean the validator relied on some other input, such as |
103 | | # an external Web site. |
104 | | |
105 | | # It is also possible that validation might fail under certain |
106 | | # attack situations: an attacker might be able to bypass previous |
107 | | # stages, and generate correct security hashes for all the |
108 | | # skipped stages by virtue of: |
109 | | # 1) having filled out an identical form which doesn't have the |
110 | | # validation (and does something different at the end), |
111 | | # 2) or having filled out a previous version of the same form |
112 | | # which had some validation missing, |
113 | | # 3) or previously having filled out the form when they had |
114 | | # more privileges than they do now. |
115 | | # |
116 | | # Since the hashes only take into account values, and not other |
117 | | # other validation the form might do, we must re-do validation |
118 | | # now for security reasons. |
119 | | previous_form_list = [self.get_form(i, request.POST) for i in range(current_step)] |
120 | | |
121 | | for i, f in enumerate(previous_form_list): |
122 | | if not self._check_security_hash(request.POST.get("hash_%d" % i, ''), request, f): |
123 | | return self.render_hash_failure(request, i) |
124 | | |
125 | | if not f.is_valid(): |
126 | | return self.render_revalidation_failure(request, i, f) |
127 | | else: |
128 | | self.process_step(request, f, i) |
129 | | |
130 | | # Now progress to processing this step: |