Replies: 6 comments 3 replies
-
One possible alternative approach would be to teach lean into the problem by showing the This has the benefit of teaching them about security, and XSS which is one of the OWASP Top 10. Like accessibility knowledge, security is potentially a valuable differentiator in the employability market. (Although I should note that security is a big topic, and basic knowledge of XSS probably isn't enough to cut it). On the flip side, I think there is a risk that we would just confuse trainees and they would learn neither approach. |
Beta Was this translation helpful? Give feedback.
-
From my personal experience, the CTO of the company I work for is extremely conscious of security (probably rightly so!) and is asked about in every engineering interview that we run. I have a feeling that if he got wind that we were explicitly teaching |
Beta Was this translation helpful? Give feedback.
-
Is it worth teaching DOM manipulation as a basic feature at all if we end up teaching them React in the end? Lot of trainees had issues with this part at least in my group, and later got relieved that using React this is all taken care of, and by the time they graduated have likely forgotten everything about this already. There was only one project that had used non-react DOM manipulation and that was done in a single component as well. |
Beta Was this translation helpful? Give feedback.
-
I think the createElement stuff is fairly unreadable and encourages invalid/inaccessible HTML. A suggestion here would be to use normal HTML templates? It's still pretty verbose but it's closer to frameworks, where they typically populate a template with data. Thinking about the TV Show project:
const episodeCard = (episode, template) => {
const template = document.getElementById(template);
const card = template.content.cloneNode(true);
card.querySelector(".card").setAttribute("id", episode.id);
card.querySelector(".card__image").setAttribute("src", episode.image.medium);
card.querySelector(".card__title").textContent = episode.name
card.querySelector(".card__summary").append(episode.summary);
return card;
}; or even I guess if we want to take it closer to a react component we could show destructuring const episodeCard = (template, { id, image: { medium }, name, summary }) => {
const card = document.getElementById(template).content.cloneNode(true);
card.querySelector(".card").setAttribute("id", id);
card.querySelector(".card__image").setAttribute("src", medium);
card.querySelector(".card__title").textContent = name;
card.querySelector(".card__summary").append(summary);
return card;
}; I don't think it's a solution to just pretend innerHTML doesn't exist because ChatGPT will suggest it to them anyway. I just tried some of the JS2/3 exercises asking it to help me work through the problems and it actually wouldn't STOP writing innerHTML even when I forbade it. So maybe two things: more readable code samples using templates, and a brief workshop/project on security. InnerHTML is only a problem when you're not in control of the content and it hasn't passed through some kind of sanitisation, so I think probably that insight is the useful part to develop. If only they would actually release that Sanitizer API! |
Beta Was this translation helpful? Give feedback.
-
One thing I'll add of JS3 context: The TV Maze API we use for the TV show project returns literal HTML as a string which we expect our trainees to display in the page (example, see these disappointing lines in my sample implementation). I would love for our trainees to be able to identify this as a problem, and consider approaches to mitigate it; whatever approach we pick, maybe this could be useful as a case study? |
Beta Was this translation helpful? Give feedback.
-
Update on this It's not a good tradeoff. We have solved the problem another way. JS3 has been rewritten! |
Beta Was this translation helpful? Give feedback.
-
As discussed during the last couple of Tech Ed syllabus team meetings, I have noticed that we have adopted the use of
innerHTML
when teaching DOM manipulation - at least when it comes to "child elements", as seen in this section of JS3 Week 1:Unfortunately
innerHTML
is vulnerable to XSS attacks, since the browser will treat the assigned value literally as "normal" HTML, giving it the same power as code written by the web developer. This can be abused by an attacker by crafting values that will execute JS in the victim's browser, potentially stealing cookies or other malicious actions. Using the example from the JS3 Week 1 code snippet above, iffilm.title
was controllable by a user, you could set the value to something like:<script>alert('haxxored')</script>
. If the snippet above is then run, you would see the alert dialog popup as if the author of the page had written that code.The safe alternative is to rewrite the snippet above as something like this:
Here, I'm constructing each individual element as a DOM object, then appending it together. Note that
textContent
(or potentiallyinnerText
) will not treat the value as HTML and so will not execute any JS within it.The major downside of this approach is that it is unfortunately significantly less readable than the
innerHTML
version. This is more obvious when building multiple nesting DOM elements:This presents a difficult tradeoff: do we teach a technique that is considerably easier to understand but insecure? Or the opposite? Or an alternative option?
Beta Was this translation helpful? Give feedback.
All reactions