Given an application object this returns a semi-stable 9 digit pin code and a random key. The hope is that this is stable between restarts to not make debugging particularly frustrating. If the pin was forcefully disabled this returns `None`. Second item in the resulting tuple is
(
app: WSGIApplication,
)
| 140 | |
| 141 | |
| 142 | def get_pin_and_cookie_name( |
| 143 | app: WSGIApplication, |
| 144 | ) -> tuple[str, str] | tuple[None, None]: |
| 145 | """Given an application object this returns a semi-stable 9 digit pin |
| 146 | code and a random key. The hope is that this is stable between |
| 147 | restarts to not make debugging particularly frustrating. If the pin |
| 148 | was forcefully disabled this returns `None`. |
| 149 | |
| 150 | Second item in the resulting tuple is the cookie name for remembering. |
| 151 | """ |
| 152 | pin = os.environ.get("WERKZEUG_DEBUG_PIN") |
| 153 | rv = None |
| 154 | num = None |
| 155 | |
| 156 | # Pin was explicitly disabled |
| 157 | if pin == "off": |
| 158 | return None, None |
| 159 | |
| 160 | # Pin was provided explicitly |
| 161 | if pin is not None and pin.replace("-", "").isdecimal(): |
| 162 | # If there are separators in the pin, return it directly |
| 163 | if "-" in pin: |
| 164 | rv = pin |
| 165 | else: |
| 166 | num = pin |
| 167 | |
| 168 | modname = getattr(app, "__module__", t.cast(object, app).__class__.__module__) |
| 169 | username: str | None |
| 170 | |
| 171 | try: |
| 172 | # getuser imports the pwd module, which does not exist in Google |
| 173 | # App Engine. It may also raise a KeyError if the UID does not |
| 174 | # have a username, such as in Docker. |
| 175 | username = getpass.getuser() |
| 176 | # Python >= 3.13 only raises OSError |
| 177 | except (ImportError, KeyError, OSError): |
| 178 | username = None |
| 179 | |
| 180 | mod = sys.modules.get(modname) |
| 181 | |
| 182 | # This information only exists to make the cookie unique on the |
| 183 | # computer, not as a security feature. |
| 184 | probably_public_bits = [ |
| 185 | username, |
| 186 | modname, |
| 187 | getattr(app, "__name__", type(app).__name__), |
| 188 | getattr(mod, "__file__", None), |
| 189 | ] |
| 190 | |
| 191 | # This information is here to make it harder for an attacker to |
| 192 | # guess the cookie name. They are unlikely to be contained anywhere |
| 193 | # within the unauthenticated debug page. |
| 194 | private_bits = [str(uuid.getnode()), get_machine_id()] |
| 195 | |
| 196 | h = hashlib.sha1() |
| 197 | for bit in chain(probably_public_bits, private_bits): |
| 198 | if not bit: |
| 199 | continue |
no test coverage detected